Skip to content

Commit

Permalink
adaptations for official ChurchTools interface
Browse files Browse the repository at this point in the history
  • Loading branch information
milux committed Dec 20, 2017
1 parent 3790826 commit dd585a7
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 38 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Changelog

### 2.0
- adapted to built-in ChurchTools ctldap API

### 1.0.1
- re-added missing autoload code to PHP API
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# LDAP Wrapper for ChurchTools v1.0.1
# LDAP Wrapper for ChurchTools v2.0

This software acts as an LDAP server for ChurchTools version 3.x
This software acts as an LDAP server for ChurchTools >= 3.25.0

**This software was tested in a common environment, yet no warranties of any kind!**

Expand All @@ -13,27 +13,29 @@ http://nodejs.org/
### Run the install.sh script as root user. It will
- run "npm install" to install required Node.js dependencies for the server
- create a new user "ctldap" to run the server with limited privileges
- create log/error log files for stdout/stderr output and set the required ownership attributes
- create the configuration file with secure random keys and offer to adapt it, asking for reset if it already exists
- (optionally) adapt and create the ctldap.sh file in /etc/init.d and call "update-rc.d ctldap.sh defaults"
- create the configuration file, asking for a reset if it already exists
- *[new config or reset]* ask for the ChurchTools domain (and directory)
- *[new config or reset]* ask for the ChurchTools API user credentials and insert them into the config file
- *[new config or reset]* insert a secure random LDAP root user password into the config file
- *[new config or reset]* offer to customize the config file
- *optionally adapt and create the ctldap.sh file in /etc/init.d and call "update-rc.d ctldap.sh defaults"*

#### ctldap.sh remarks:
The file "ctldap.sh" contains a shell script for (re)starting ctldap.sh with Node.js as a background service.
It will attempt to create/remove an iptables NAT rule on start/stop in order to redirect traffic from a standard LDAP port (< 1024) to ldap_port without root.
The script can be used to start/stop the service manually, but will not work correctly without root privileges.
The file "ctldap.sh" contains a shell script for (re)starting ctldap.sh with Node.js as a background service, redirecting all output to the system log with systemd-cat. The logs can be reviewed with the shell command `journalctl -t ctldap`. See https://wiki.ubuntuusers.de/systemd/journalctl/ for further options.

The script will attempt to create/remove an iptables NAT rule on start/stop in order to redirect traffic from a standard LDAP port (< 1024) to ldap_port without root.

It can be used to start/stop the service manually, but will not work correctly without root privileges!

Usage: ctldap.sh {start|stop|status|restart}

### If you don't have root privileges:
- run `npm install` manually or otherwise trigger the installation of required dependencies
- copy "ctldap.example.config" to "ctldap.config" and adjust the required settings accordingly
- register "ctldap.js" to be run by Node.js, or start the server directly by executing `node ctldap.js`

## PHP API install
- copy the contents of "php_api" to the root folder of your ChurchTools installation (the composer.* files can be safely ignored)
- copy the line "api_key=<random_20_char_string>" from your "ctldap.config" to your ChuchTools configuration at /sites/[default|subdomain]/churchtools.config

# Usage
The LDAP DNs depend on your configuration. We assume the following configuration:
The LDAP DNs depend on your configuration. Let's assume the following configuration:
```
ldap_user=root
ldap_password=0a1b2c3d4e5f6g7h8i9j
Expand Down
13 changes: 7 additions & 6 deletions ctldap.example.config
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ iptables_port=389
ldap_base_dn=churchtools

; The URI pointing to the root of your ChurchTools installation
ct_uri=https://mghh.churchtools.de/
; This API key is used to authenticate against the PHP API
; IMPORTANT: AFTER using install.sh or choosing a LONG SECURE RANDOM API key from a password generator like KeePass,
; copy this line into your CT configuration at /sites/[default|subdomain]/churchtools.config
api_key=XXXXXXXXXXXXXXXXXXXX
ct_uri=https://mysite.church.tools/
; This user credentials are used to authenticate against ChurchTools for API access
; The user must be granted "churchcore:administer persons" and "churchdb:view" rights for the wrapper to work properly!
; IMPORTANT: It is strongly recommended to use a LONG SECURE RANDOM password from a generator like KeePass for this user!
api_user=XXXXXXXXXXXXXXXXXXXX
api_password=XXXXXXXXXXXXXXXXXXXX
; This controls (in milliseconds) how old the user/group data can be until it is fetched from ChurchTools again
cache_lifetime=10000

Expand All @@ -30,4 +31,4 @@ cache_lifetime=10000
; Use this command to remove the encryption password:
; openssl rsa -in key.pem -out newkey.pem && mv newkey.pem key.pem
; ldap_cert_filename=cert.pem
; ldap_key_filename=key.pem
; ldap_key_filename=key.pem
55 changes: 48 additions & 7 deletions ctldap.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ChurchTools 3.2 LDAP-Wrapper
// This tool requires a node.js-Server
// ChurchTools LDAP-Wrapper 2.0
// This tool requires a node.js-Server and ChurchTools >= 3.25.0
// (c) 2017 Michael Lux
// License: GNU/GPL v3.0

Expand All @@ -20,6 +20,8 @@ if (config.debug) {
var fnUserDn = ldapEsc.dn("cn=${cn},ou=users,o=" + config.ldap_base_dn);
var fnGroupDn = ldapEsc.dn("cn=${cn},ou=groups,o=" + config.ldap_base_dn);
var adminDn = fnUserDn({ cn: config.ldap_user });
var cookieJar = rp.jar();
var loginPromise = null;

if (config.dn_lower_case) {
var compatTransform = function (s) {
Expand All @@ -40,26 +42,65 @@ if (config.ldap_cert_filename && config.ldap_key_filename) {
}

if (typeof config.cache_lifetime !== 'number') {
config.cache_lifetime = 10000;
config.cache_lifetime = 10000; // 10 seconds
}
if (config.ct_uri.slice(-1) !== "/") {
config.ct_uri += "/";
}

/**
* Returns a promise for the login on the ChurchTools API.
* If a pending login promise already exists, it is returned right away.
*/
function apiLogin() {
if (loginPromise === null) {
loginPromise = rp({
"method": "POST",
"jar": cookieJar,
"uri": config.ct_uri + "?q=login/ajax",
"form": {
"func": "login",
"email": config.api_user,
"password": config.api_password
},
"json": true
}).then(function (result) {
if (result.status !== "success") {
throw result.message;
}
// clear login promise
loginPromise = null;
// end gracefully
return null;
});
}
return loginPromise;
}

/**
* Retrieves data from the PHP API via a POST call.
* @param {function} func - The function to call in the API class
* @param {object} [data] - The optional form data to pass along with the POST request
* @param {boolean} [triedLogin] - Is true if this is the second attempt after API login
*/
function apiPost(func, data) {
function apiPost(func, data, triedLogin) {
return rp({
"method": "POST",
"uri": config.ct_uri + "api.php/API/" + func,
"form": extend({ api_key: config.api_key }, data || {}),
"jar": cookieJar,
"uri": config.ct_uri + "?q=churchdb/ajax",
"form": extend({ "func": func }, data || {}),
"json": true
}).then(function (result) {
if (result.status !== "success") {
throw result.status;
// If session has expired, get a login Promise and await login
if (result.message === "Session expired!" && !triedLogin) {
// Remember that we tried to login to prevent looping
return apiLogin().then(function () {
// Retry operation after login
return apiPost(func, data, true);
});
}
throw result.message;
}
return result.data;
});
Expand Down
4 changes: 2 additions & 2 deletions ctldap_raw.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: ChurchTools 3.2 LDAP-Wrapper
# Short-Description: ChurchTools LDAP-Wrapper v2.0
# Description: Init script for the ChurchTools LDAP Wrapper.
### END INIT INFO

Expand All @@ -32,7 +32,7 @@ start)
sh $DIR/$0 stop
fi
fi
su -c "nohup node $CTLDAP/ctldap.js 2>>$CTLDAP/error.log >>$CTLDAP/output.log &" - ctldap
su -c "systemd-cat -t ctldap node $CTLDAP/ctldap.js &" - ctldap
PID=$( ps axf | grep "node $CTLDAP/ctldap.js" | grep -v grep | awk '{print $1}' )
if [ -z "$PID" ]; then
echo "Fail"
Expand Down
30 changes: 20 additions & 10 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

# ChurchTools 3.2 LDAP-Wrapper
# ChurchTools LDAP-Wrapper 2.0
# (c) 2017 Michael Lux <[email protected]>
# License: GNU/GPL v3.0

Expand All @@ -24,22 +24,32 @@ echo "Now creating the \"ctldap\" user..."
useradd ctldap
echo ""

echo "Init logging files..."
touch output.log
touch error.log
chown ctldap:ctldap *.log
echo ""

ANSWER="y"
if [ -f "ctldap.config" ]; then
read -n1 -p "Reset configuration file? [y/n]" ANSWER
echo ""
fi
if [ $ANSWER = "y" ]; then
PRNG_CMD="tr -cd '[:alnum:]' < /dev/urandom | fold -w20 | head -n1"
PRNG_PASSWORD=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w20 | head -n1)
echo ""
echo "The new password for the LDAP root user is: $PRNG_PASSWORD"
echo ""
read -r -p "Please enter the domain (and directory) of your ChurchTools installation (example: mychurch.church.tools): " CTLOC
echo "Assumed (HTTPS) ChurchTools URL: https://$CTLOC/"
echo "If this is wrong, please fix it manually when the configuration file is opened for customization."
echo ""
read -r -p "Please enter ChurchTools username for authentication: " USERNAME
read -r -p "Please enter ChurchTools user password for authentication: " PASSWORD
cat ctldap.example.config | \
sed "s/ldap_password=XXXXXXXXXXXXXXXXXXXX/ldap_password=$(eval ${PRNG_CMD})/" | \
sed "s/api_key=XXXXXXXXXXXXXXXXXXXX/api_key=$(eval ${PRNG_CMD})/" > ctldap.config
sed "s?mysite.church.tools?$CTLOC?" | \
sed "s/ldap_password=XXXXXXXXXXXXXXXXXXXX/ldap_password=$PRNG_PASSWORD/" | \
sed "s/api_user=XXXXXXXXXXXXXXXXXXXX/api_user=$USERNAME/" | \
sed "s/api_password=XXXXXXXXXXXXXXXXXXXX/api_password=$PASSWORD/" > ctldap.config
echo ""
echo "Don't forget to grant your ChurchTools API user this privileges:"
echo "- churchcore:administer persons (Required to access the user data)"
echo "- churchdb:view (Required for ChurchDB API access)"
echo ""
fi

echo "Trying to open ctldap.config now, modify it according to your needs!"
Expand Down

0 comments on commit dd585a7

Please sign in to comment.