diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d768329..0b2e20e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI -on: [ push ] +on: [ push, pull_request ] env: CI: true @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-latest, windows-latest ] + os: [ ubuntu-latest ] node-version: ${{ fromJson(needs.get-lts.outputs.active) }} fail-fast: false steps: @@ -29,6 +29,7 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm install + - run: sudo ./test/fixtures/linux/setup.sh - run: npm test get-lts: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 42a9bb9..d489fbd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,8 @@ on: push: branches: - master + paths: + - package.json env: CI: true diff --git a/.release b/.release index 9be2b27..0890e94 160000 --- a/.release +++ b/.release @@ -1 +1 @@ -Subproject commit 9be2b270ef836bcfefda085674bf62e2a91defe8 +Subproject commit 0890e945e4e061c96c7b2ab45017525904c17728 diff --git a/Changes.md b/Changes.md index a2e78c5..f8411f7 100644 --- a/Changes.md +++ b/Changes.md @@ -1,6 +1,14 @@ ### Unreleased +### [1.1.0] - 2023-04-27 + +- chore(es6): use nullish operator, arrow fns +- dep(async): removed dependency +- dep(ldapjs): bump version from 1.0.2 to 2.3.3 +- test: add an authentication test + + ### [1.0.3] - 2022-06-06 - dep(async): bump version 3.0.1 -> 3.2.3 @@ -25,3 +33,4 @@ [1.0.3]: https://github.com/haraka/haraka-plugin-auth-ldap/releases/tag/1.0.3 +[1.1.0]: https://github.com/haraka/haraka-plugin-auth-ldap/releases/tag/1.1.0 diff --git a/index.js b/index.js index 0682221..66f0ea8 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ // auth/auth_ldap const ldap = require('ldapjs'); -const async = require('async'); exports.hook_capabilities = function (next, connection) { // Don't offer AUTH capabilities by default unless session is encrypted @@ -19,59 +18,74 @@ exports.register = function () { } exports.load_auth_ldap_ini = function () { - const plugin = this; - plugin.cfg = plugin.config.get('auth_ldap.ini', { + + this.cfg = this.config.get('auth_ldap.ini', { booleans: [ 'core.rejectUnauthorized' ], }, - function () { - plugin.load_auth_ldap_ini(); - }); + () => { + this.load_auth_ldap_ini(); + }) } exports.check_plain_passwd = function (connection, user, passwd, cb) { - // Get LDAP config - const config = this.cfg; - let ldap_url = 'ldap://127.0.0.1'; - if (config.core.server) { - ldap_url = config.core.server; + const ldap_url = this.cfg.core.server ? this.cfg.core.server : 'ldap://127.0.0.1'; + + const rejectUnauthorized = this.cfg.core.rejectUnauthorized ?? true; + + const dnList = Object.keys(this.cfg.dns).map((v) => { + return this.cfg.dns[v]; + }) + + let cbCalled = false + let iter = 0 + + function cbOnce (result) { + if (cbCalled) return + if (result) { + cbCalled = true + cb(result) + } + else if (iter === dnList.length) { + cbCalled = true + cb(result) + } } - const rejectUnauthorized = (config.core.rejectUnauthorized != undefined) ? - config.core.rejectUnauthorized : true; - const client = ldap.createClient({ + this.client = ldap.createClient({ url: ldap_url, - timeout: (config.core.timeout != undefined) ? config.core.timeout : 5000, + timeout: this.cfg.core.timeout ?? 5000, tlsOptions: { rejectUnauthorized } - }); + }) - client.on('error', function (err) { - connection.loginfo(`auth_ldap: client error ${ err.message}`); - cb(false); - }); + this.client.on('error', (err) => { + connection.loginfo(`auth_ldap: client error ${err.message}`); + iter = dnList.length; + cbOnce(false); + }) - config.dns = Object.keys(config.dns).map(function (v) { - return config.dns[v]; + this.client.on('connectError', (err) => { + connection.loginfo(`auth_ldap: connection error ${err.message}`); + iter = dnList.length; + cbOnce(false); }) - async.detectSeries(config.dns, function (dn, callback) { - dn = dn.replace(/%u/g, user); - client.bind(dn, passwd, function (err) { + for (const dn of dnList) { + const u = dn.replace(/%u/g, user) + this.client.bind(u, passwd, (err) => { + iter++; if (err) { - connection.loginfo(`auth_ldap: (${ dn }) ${ err.message}`); - return callback(false); + connection.loginfo(`auth_ldap: (${u}) ${err.message}`); + cbOnce(false); } else { - client.unbind(); - return callback(true); + cbOnce(true); } + this.client.unbind(); }) - }, function (result) { - cb(result); - }); + } } - diff --git a/package.json b/package.json index 603a372..f29bb81 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "haraka-plugin-auth-ldap", - "version": "1.0.3", + "version": "1.1.0", "description": "Haraka plugin that uses an LDAP bind to authenticate users", "main": "index.js", "scripts": { "lint": "npx eslint *.js test", "lintfix": "npx eslint --fix *.js test", - "test": "npx _mocha" + "test": "npx mocha --exit" }, "repository": { "type": "git", @@ -30,7 +30,6 @@ "mocha": ">=9" }, "dependencies": { - "async": "^3.2.3", - "ldapjs": "^1.0.2" + "ldapjs": "^2.3.3" } } diff --git a/test/config/auth_ldap.ini b/test/config/auth_ldap.ini new file mode 100644 index 0000000..35e58c2 --- /dev/null +++ b/test/config/auth_ldap.ini @@ -0,0 +1,8 @@ +[core] +server=ldaps://127.0.0.1:3636 +timeout=5000 +rejectUnauthorized=false + +[dns] +dn1=uid=%u,ou=users,dc=example,dc=com +dn2=uid=%u,ou=people,dc=example,dc=com \ No newline at end of file diff --git a/test/config/slapdcert.pem b/test/config/slapdcert.pem new file mode 100644 index 0000000..30544b3 --- /dev/null +++ b/test/config/slapdcert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIJAOdTREdxzeEvMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV +BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg +Q29tcGFueSBMdGQxFjAUBgNVBAMMDW15LWRvbWFpbi5jb20wIBcNMTYxMDA4MDkw +NDA2WhgPMjA4NDEwMjYwOTA0MDZaMFoxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxE +ZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxFjAUBgNV +BAMMDW15LWRvbWFpbi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC8hWmnizuif/qpPtfX/+Kcb1C17sakGkYwASmUJZotvmT+BeHPwAfOasjP9AXW +tQnJv5R+C//hTCdhCrMo66OtplSZoMbWGQHSgL3J7i+QUfYQikpwcYXm7bsmWKtQ +39eUQ+wHh9H0G0+YuNcXELRWoN3DK+Kjd9EyeEGLDJP297XtAfCnR9E/s5dyDCij +MhSx0Thg/lqRGRK+29n10cxO5Gxisep24FWMaLJlhpMpbvKC/c1yC1nxftOt/2l5 +UTMklNzvixP5QwhUNH4nTU+/PRfq1QjpJCX89li7Ln0Rx6hgvIdGbLgkOptAliUy +Z4CazBnvuZ8j9OY001rsKJopAgMBAAGjUDBOMB0GA1UdDgQWBBR8uERwVCbIMJCJ +w88WZQ2aHSM5vDAfBgNVHSMEGDAWgBR8uERwVCbIMJCJw88WZQ2aHSM5vDAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB7btFZM5FElhF+BKdXfSTyFaJb +ocg0xsstse84HOtV7EUHYEeeXmInSzgptQo64L2oS1yRqAlxBM/0jq8XQ8gHtKML +bonTzeK36eMAB+OosVTP8XRZqJfWrntqOFxhf3YkXOYm49QHl8Y0XtWtvXNrYiyr +mnbW5iyOhxkggxfD8gxWQW+l9rZFlfCHAkGZw2M8lw5iV2uiXZKiWtuB1aN7i2AH +YTYP7hqb4MOUd9lpJ93irHw2KbejY6rIxIZVyjN4Y4IUGF67fj1RPcDgRIy55c28 +grSmnCLrYSYRsA5jeEB6PAknx3OuLtYj8WvZPe4KiP77r+YIN9nBywF9sVdd +-----END CERTIFICATE----- diff --git a/test/config/slapdkey.pem b/test/config/slapdkey.pem new file mode 100644 index 0000000..635a567 --- /dev/null +++ b/test/config/slapdkey.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8hWmnizuif/qp +PtfX/+Kcb1C17sakGkYwASmUJZotvmT+BeHPwAfOasjP9AXWtQnJv5R+C//hTCdh +CrMo66OtplSZoMbWGQHSgL3J7i+QUfYQikpwcYXm7bsmWKtQ39eUQ+wHh9H0G0+Y +uNcXELRWoN3DK+Kjd9EyeEGLDJP297XtAfCnR9E/s5dyDCijMhSx0Thg/lqRGRK+ +29n10cxO5Gxisep24FWMaLJlhpMpbvKC/c1yC1nxftOt/2l5UTMklNzvixP5QwhU +NH4nTU+/PRfq1QjpJCX89li7Ln0Rx6hgvIdGbLgkOptAliUyZ4CazBnvuZ8j9OY0 +01rsKJopAgMBAAECggEANJ44Ix9lgbGe0OZNcGhnY6peKKmAoAUFWhi49jSYl/Pw +VEZoBIhgpWiArCo8BvV4yerDE3td7BBJXXiTEPTUNn+aVVbeqJtKOurcDiSA+hMm +Tu+KX2AQM6he+BD/oA8aKLPciS2LmEqXKNVOk42CCDvWKcdx9pZWuXN/N8RG+EMn +us8hOtEJjtJNUKwmD/HTIBDgkklIHBo+q/T8yrtKOkoKhX3jPDjDYPADLf86djCw +0aDtCe8bB7UJPpC5cWRGmInxCUhVIaBVwyBA8vb3gHW9L4Bj9hGp/AQWdPzY8qU/ +ia6iXbsyRg0o0M32iSssBNCQw5mNghiQm+EyFY+QAQKBgQD6vhFf6qrEDw8a5jWc +C++wZzuIpOhkUgBHWe5LTev2HTQij92qztvz4PRxaFUOUAqL/zm+QxzObwXGh4Qy +4dNALnI5LPbT3MlJkVp0lBA1CMlAzogZA3QEjjSCTUbhtTm+uPLsQ+quIEKHboaW +xa3GnK9Fbxh4jfgpRV6aQ3AkgQKBgQDAeVql+3K5joYy8iaB5bChggFwxJ/6FvtP +T2FQohMcmIWB+pHYZfW4XDGil2L/4AKBBGKdju/Rq4/SfPGrHTS59i8LnYAs8Drx +fLxPgYzJUyAR7dB/2GXX6AnZqUEJe5fKbuFz38cs38HnZnubwqHOXqvWvUe75Dgm +2EE5CPwBqQKBgG6JOamaDtvNc7A9CicXj/upFrKfWB9Zkuvhdk5WNI5Tw3b1CxhQ +huBVLA2Om+hqWqvqwK7icSGECfzCIwI3UWR61TnlW458R3QaEtFPsHFgxS+/nHnC +bvPPKNDEdlnsBV/Rsq17J0rJx+piTAzNalUjH5Uxa41BsMOo5BKHZjmBAoGBALFs +LD9s9mhOFS7JQO3kyVlX+fP1jHKA1NBbIB2wCWYGwqr6S47rDgMQGUEDw+KSoDxF +ypHqvO7N8xnYyv0tQvlZEizm1syV9f+9N+kiRqEe2yUrz1LKK7dG0i2uc6FGKLoW +VAT4dyXKbXfdZHxEgds2MbkVahatXYWROy5UNdlhAoGAIHo7cDuxz4OkDhe4/r8n +q9QA8f4iH9n046u/nyyhc1s7J4XYPARNRJ7/26lNpVQf/j9jmPZ696cTXcxxNGyS +tJM5HzQbx5jM81ugLpDqPyu96lZCM8YkoR55XveJzkd4RKIdTkU6yjfPJ9/KuMZy +hxCTSQjvH4JmaJAB0aeo9Ms= +-----END PRIVATE KEY----- diff --git a/test/fixtures/linux/setup.sh b/test/fixtures/linux/setup.sh new file mode 100755 index 0000000..b163e0e --- /dev/null +++ b/test/fixtures/linux/setup.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +if ! dpkg -l | grep -q slapd; then + sudo apt install --no-install-recommends -y gcc gettext make g++ apparmor-utils slapd ldap-utils ldapscripts + sudo service slapd stop + sudo systemctl disable slapd.service +fi + +sudo killall slapd +sudo aa-complain /usr/sbin/slapd + +if [ ! -d "/tmp/slapd" ]; then sudo mkdir /tmp/slapd; fi +sudo rm -rf /tmp/slapd/* /var/lib/ldap/* + +sudo slapd -f test/fixtures/linux/slapd.conf -h "ldap://localhost:3389 ldaps://localhost:3636" +sleep 2 +ldapadd -x -D "cn=admin,dc=example,dc=com" -w "rAR84,NZ=F" -H ldap://localhost:3389 -f test/fixtures/testdata.ldif diff --git a/test/fixtures/linux/slapd.conf b/test/fixtures/linux/slapd.conf new file mode 100644 index 0000000..7cd8806 --- /dev/null +++ b/test/fixtures/linux/slapd.conf @@ -0,0 +1,19 @@ +include /etc/ldap/schema/core.schema +include /etc/ldap/schema/cosine.schema +include /etc/ldap/schema/misc.schema +include /etc/ldap/schema/inetorgperson.schema +# include /etc/ldap/schema/nis.schema + +pidfile /var/run/slapd/slapd.pid + +modulepath /usr/lib/ldap + +database ldif +directory /tmp/slapd + +suffix "dc=example,dc=com" +rootdn "cn=admin,dc=example,dc=com" +rootpw {SSHA}2Gl8VBvuOxkhcrVCRNzDcCG9ecJHg0gl + +TLSCertificateFile test/config/slapdcert.pem +TLSCertificateKeyFile test/config/slapdkey.pem diff --git a/test/fixtures/linux/slapd.ldif b/test/fixtures/linux/slapd.ldif new file mode 100644 index 0000000..851858b --- /dev/null +++ b/test/fixtures/linux/slapd.ldif @@ -0,0 +1,39 @@ + +dn: cn=config +objectClass: olcGlobal +cn: config + +dn: cn=module,cn=config +objectClass: olcModuleList +cn: module +olcModulepath: /usr/lib/ldap +olcModuleload: back_mdb.la + +dn: cn=schema,cn=config +objectClass: olcSchemaConfig +cn: schema + +include: file:///etc/ldap/schema/core.ldif + +dn: olcDatabase=frontend,cn=config +objectClass: olcDatabaseConfig +objectClass: olcFrontendConfig +olcDatabase: frontend + +dn: olcDatabase=mdb,cn=config +objectClass: olcDatabaseConfig +objectClass: olcMdbConfig +olcDatabase: mdb +OlcDbMaxSize: 1073741824 +olcSuffix: dc=example,dc=com +olcRootDN: cn=Manager,dc=example,dc=com +olcRootPW: rAR84,NZ=F +olcDbDirectory: /var/tmp/slapd +olcDbIndex: objectClass eq + +dn: olcDatabase=monitor,cn=config +objectClass: olcDatabaseConfig +olcDatabase: monitor +olcRootDN: cn=config +olcMonitoring: FALSE + diff --git a/test/fixtures/macports/setup.sh b/test/fixtures/macports/setup.sh new file mode 100644 index 0000000..60090b5 --- /dev/null +++ b/test/fixtures/macports/setup.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +/usr/bin/sed -i -e '/^server/ s/:389/:3389/' -e 's/^server.*:636$/:3636/' config/ldap.ini +if [ ! -d "/var/tmp/slapd" ]; then mkdir /var/tmp/slapd; fi +rm -r /var/tmp/slapd/* || exit + +/opt/local/sbin/slapadd -n 0 -F /var/tmp/slapd -l test/fixtures/macosx/slapd.ldif || exit + +/opt/local/libexec/slapd -f test/fixtures/macosx/slapd.conf -h "ldap://localhost:3389 ldaps://localhost:3636" & +sleep 3 + +/opt/local/bin/ldapadd -x -D "cn=admin,dc=example,dc=com" -w "rAR84,NZ=F" -H ldap://localhost:3389 -f test/fixtures/testdata.ldif diff --git a/test/fixtures/macports/slapd.conf b/test/fixtures/macports/slapd.conf new file mode 100644 index 0000000..46a1d11 --- /dev/null +++ b/test/fixtures/macports/slapd.conf @@ -0,0 +1,18 @@ +include /opt/local/etc/openldap/schema/core.schema +include /opt/local/etc/openldap/schema/cosine.schema +include /opt/local/etc/openldap/schema/misc.schema +include /opt/local/etc/openldap/schema/inetorgperson.schema + +pidfile /var/run/slapd/slapd.pid + +#modulepath /usr/lib/openldap + +database ldif +directory /var/tmp/slapd + +suffix "dc=example,dc=com" +rootdn "cn=admin,dc=example,dc=com" +rootpw {SSHA}bPf32h0ItVUKLlVzsR6od+Ub5GDZRBIr + +TLSCertificateFile test/config/slapdcert.pem +TLSCertificateKeyFile test/config/slapdkey.pem diff --git a/test/fixtures/macports/slapd.ldif b/test/fixtures/macports/slapd.ldif new file mode 100644 index 0000000..8968290 --- /dev/null +++ b/test/fixtures/macports/slapd.ldif @@ -0,0 +1,40 @@ + + +dn: cn=config +objectClass: olcGlobal +cn: config + +dn: cn=module,cn=config +objectClass: olcModuleList +cn: module +olcModulepath: /opt/local/libexec/openldap +olcModuleload: back_mdb.la + +dn: cn=schema,cn=config +objectClass: olcSchemaConfig +cn: schema + + +include: file:///opt/local/etc/openldap/schema/core.ldif + +dn: olcDatabase=frontend,cn=config +objectClass: olcDatabaseConfig +objectClass: olcFrontendConfig +olcDatabase: frontend + +dn: olcDatabase=mdb,cn=config +objectClass: olcDatabaseConfig +objectClass: olcMdbConfig +olcDatabase: mdb +OlcDbMaxSize: 1073741824 +olcSuffix: dc=example,dc=com +olcRootDN: cn=Manager,dc=example,dc=com +olcRootPW: rAR84,NZ=F +olcDbDirectory: /var/tmp/slapd +olcDbIndex: objectClass eq + +dn: olcDatabase=monitor,cn=config +objectClass: olcDatabaseConfig +olcDatabase: monitor +olcRootDN: cn=config +olcMonitoring: FALSE diff --git a/test/fixtures/testdata.ldif b/test/fixtures/testdata.ldif new file mode 100644 index 0000000..74e11f7 --- /dev/null +++ b/test/fixtures/testdata.ldif @@ -0,0 +1,104 @@ +# add base dn +dn: dc=example,dc=com +changetype: add +objectclass: top +objectclass: organization +objectClass: dcObject +dc: example +o: example.com + +# add 2 dn for people +dn: ou=users,dc=example,dc=com +changetype: add +objectclass: top +objectclass: organizationalUnit +ou: users + +dn: ou=people,dc=example,dc=com +changetype: add +objectclass: top +objectclass: organizationalUnit +ou: people + +# add user1 in 1st dn +# password is: ykaHsOzEZD +dn: uid=user1,ou=users,dc=example,dc=com +changetype: add +objectClass: top +objectClass: uidObject +objectClass: device +objectClass: simpleSecurityObject +objectClass: inetLocalMailRecipient +uid: user1 +cn: Test User 1 +mailLocalAddress: user1@example.com +userPassword: {SSHA}ul8jaq76hmLRuvheYxSqPDCQrPxldRkl + +# add user2 in 2nd dn +# password is: KQD9zs,LGv +dn: uid=user2,ou=people,dc=example,dc=com +changetype: add +objectClass: top +objectClass: uidObject +objectClass: device +objectClass: simpleSecurityObject +objectClass: inetLocalMailRecipient +uid: user2 +cn: Test User 2 +mailLocalAddress: user2@example.com +userPassword: {SSHA}j999dNJUvKzt480ky0/A5VvNRqzSS1TA + +# add nonunique in both dn +# password is: CZVm3,BLlx +dn: uid=nonunique,ou=users,dc=example,dc=com +changetype: add +objectClass: top +objectClass: uidObject +objectClass: device +objectClass: simpleSecurityObject +objectClass: inetLocalMailRecipient +uid: nonunique +cn: Nonunique Test User 1 +mailLocalAddress: nonunique1@example.com +userPassword: {SSHA}/zz+SrbdIhlwQ6ypFP2bupP6IUKzgA2z + +# password is: LsBHDGorAh +dn: uid=nonunique,ou=people,dc=example,dc=com +changetype: add +objectClass: top +objectClass: uidObject +objectClass: device +objectClass: simpleSecurityObject +objectClass: inetLocalMailRecipient +uid: nonunique +cn: Nonunique Test User 2 +mailLocalAddress: nonunique2@example.com +userPassword: {SSHA}gLTxl9QpE1dHNgfZK9d3Ne8MKXtFRRfn + +# add user who forwards mail +# password is: 1QRSrUECyKLR +dn: uid=forwarder,ou=people,dc=example,dc=com +changetype: add +objectClass: top +objectClass: uidObject +objectClass: device +objectClass: simpleSecurityObject +objectClass: inetLocalMailRecipient +uid: forwarder +cn: Forwarding Test User +mailLocalAddress: forwarder@example.com +mailRoutingAddress: user2@example.com +userPassword: {SSHA}h53i1Xy3/Hi27rr+krH/TwSGkEohfbxH + +# add group to resolve by-dn +dn: cn=postmaster,dc=example,dc=com +changetype: add +objectclass: top +objectclass: groupOfNames +objectClass: inetLocalMailRecipient +mailLocalAddress: postmaster@example.com +member: uid=user1,ou=users,dc=example,dc=com +member: uid=user2,ou=people,dc=example,dc=com +member: uid=nonunique,ou=users,dc=example,dc=com +member: uid=unknown,dc=wherever,dc=com + diff --git a/test/index.js b/test/index.js index 7b89430..f2507f6 100644 --- a/test/index.js +++ b/test/index.js @@ -1,6 +1,7 @@ // node.js built-in modules const assert = require('assert'); +const path = require('path') // npm modules const fixtures = require('haraka-test-fixtures'); @@ -11,26 +12,87 @@ const fixtures = require('haraka-test-fixtures'); beforeEach(function (done) { this.plugin = new fixtures.plugin('auth-ldap'); + this.plugin.config = this.plugin.config.module_config(path.resolve('test')); done(); // if a test hangs, assure you called done() -}); +}) -describe('', function () { - it('loads', function (done) { + +describe('auth-ldap', function () { + it('plugin loads', function () { assert.ok(this.plugin); - done(); - }); -}); + }) +}) describe('load_ini', function () { it('loads .ini from config/auth_ldap.ini', function (done) { this.plugin.load_auth_ldap_ini(); assert.ok(this.plugin.cfg); done(); - }); + }) - it('initializes enabled boolean', function (done) { + it('initializes enabled boolean', function () { this.plugin.load_auth_ldap_ini(); assert.equal(this.plugin.cfg.core.rejectUnauthorized, false, this.plugin.cfg); - done(); - }); -}); + }) +}) + +// test user data as defined in testdata.ldif +const users = [ + { + uid: 'user1', + dn: 'uid=user1,ou=users,dc=example,dc=com', + password: 'ykaHsOzEZD', + mail: 'user1@example.com' + }, + { + uid: 'user2', + dn: 'uid=user2,ou=people,dc=example,dc=com', + password: 'KQD9zs,LGv', + mail: 'user2@example.com' + }, + { + uid: 'nonunique', + dn: 'uid=nonunique,ou=users,dc=example,dc=com', + password: 'CZVm3,BLlx', + mail: 'nonunique1@example.com' + }, + { + uid: 'nonunique', + dn: 'uid=nonunique,ou=people,dc=example,dc=com', + password: 'LsBHDGorAh', + mail: 'nonunique2@example.com' + } +]; + +function _set_up (done) { + this.plugin = new fixtures.plugin('auth-ldap'); + this.plugin.config = this.plugin.config.module_config(path.resolve('test')); + this.plugin.load_auth_ldap_ini() + this.connection = fixtures.connection.createConnection(); + this.connection.server = { notes: {}}; + done(); +} + +describe('check_plain_passwd', function () { + + before(_set_up) + + for (const user of users.slice(0, 2)) { + // for some reason this test fails on GHA sporadically. Skip for now. + it.skip(`validates user ${user.uid}`, function (done) { + this.timeout(3000); + this.plugin.check_plain_passwd(this.connection, user.uid, user.password, (result) => { + assert.equal(true, result); + done() + }) + }) + } + + it(`rejects invalid user`, function (done) { + this.timeout(3000); + this.plugin.check_plain_passwd(this.connection, 'invalid', 'invalid', (result) => { + assert.equal(false, result); + done(); + }) + }) +})