UNPKG

ldap-authentication

Version:

A simple async nodejs library for LDAP user authentication

427 lines (392 loc) 11.4 kB
const { authenticate, LdapAuthenticationError } = require('../index.js') const url = process.env.INGITHUB ? 'ldap://localhost:1389' : 'ldap://ldap:1389' describe('ldap-authentication test', () => { it('Use an admin user to check if user exists', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', verifyUserExists: true, userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('gauss') }) it('Use an admin user to check if user exists and return attributes', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', verifyUserExists: true, userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', attributes: ['uid', 'sn'], } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('gauss') expect(user.sn).toEqual('Bar1') expect(user.cn).toBeUndefined() }) it('Use an admin user to authenticate a regular user', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('gauss') }) it('Use an admin user to authenticate a regular user and return attributes', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', attributes: ['uid', 'sn'], } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('gauss') expect(user.sn).toEqual('Bar1') expect(user.cn).toBeUndefined() }) it('Use an regular user to authenticate iteself', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=einstein,ou=users,dc=example,dc=com', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'einstein', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('einstein') }) it('Use an regular user to authenticate iteself and return attributes', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=einstein,ou=users,dc=example,dc=com', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'einstein', attributes: ['uid', 'sn'], } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.uid).toEqual('einstein') expect(user.sn).toEqual('Bar2') expect(user.cn).toBeUndefined() }) it('Use an regular user to authenticate iteself without search', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=einstein,ou=users,dc=example,dc=com', userPassword: 'password', } let user = await authenticate(options) expect(user).toBeTruthy() }) it('Use an admin user to authenticate a regular user and fetch user group information', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', groupsSearchBase: 'dc=example,dc=com', groupClass: 'groupOfNames', groupMemberAttribute: 'member', groupMemberUserAttribute: 'dn', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.groups.length).toBeGreaterThan(0) expect(user.groups[0].dn).toEqual('cn=科学A部,ou=groups,dc=example,dc=com') }) it('Use regular user to authenticate and fetch user group information', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=gauss,ou=users,dc=example,dc=com', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', groupsSearchBase: 'dc=example,dc=com', groupClass: 'groupOfNames', groupMemberAttribute: 'member', groupMemberUserAttribute: 'dn', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.groups.length).toBeGreaterThan(0) expect(user.groups[0].dn).toEqual('cn=科学A部,ou=groups,dc=example,dc=com') // backward compatible with 3.2 expect(user.groups[0].objectName).toEqual( 'cn=科学A部,ou=groups,dc=example,dc=com' ) }) it('Not specifying groupMemberAttribute or groupMemberUserAttribute should not cause an error and fallback to default values', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=gauss,ou=users,dc=example,dc=com', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', groupsSearchBase: 'dc=example,dc=com', groupClass: 'groupOfUniqueNames', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.groups.length).toBeLessThan(1) }) }) describe('ldap-authentication negative test', () => { it('wrong admin user should fail', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=not-exist,dc=example,dc=com', adminPassword: 'password', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let e = null try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('wrong admin password should fail', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: '', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let e = null try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('admin auth wrong username should fail', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'wrong', } let e = null try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('admin auth wrong user password should fail', async () => { let options = { ldapOpts: { url: url, }, adminDn: 'cn=read-only-admin,dc=example,dc=com', adminPassword: 'password', userPassword: 'wrongpassword', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let e = null try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('user auth wrong username should fail', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=not-exist,dc=example,dc=com', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let e = null try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('user auth wrong user password should fail', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=gauss,dc=example,dc=com', userPassword: 'wrongpassword', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', } let e = null try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('Use an regular user to authenticate iteself without search with wrong password should fail', async () => { let options = { ldapOpts: { url: url, }, userDn: 'uid=einstein,dc=example,dc=com', userPassword: '', } try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('Wrong options give LdapAuthenticationError', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=einstein,ou=users,dc=example,dc=com', userPassword: 'password', usernameAttribute: 'wrongattribute', userSearchBase: 'dc=example,dc=com', username: 'einstein', } try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() expect(e).toBeInstanceOf(LdapAuthenticationError) }) it('Unreachable ldap server should throw error', async () => { let options = { ldapOpts: { url: 'ldap://x.forumsys.com', connectTimeout: 2000, }, userDn: 'uid=einstein,dc=example,dc=com', userPassword: 'password', usernameAttribute: 'cn', userSearchBase: 'dc=example,dc=com', username: 'einstein', } try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('Unreachable ldap server should throw error (with starttls=true)', async () => { let options = { ldapOpts: { url: 'ldap://x.forumsys.com', connectTimeout: 2000, }, userDn: 'uid=einstein,dc=example,dc=com', userPassword: 'password', usernameAttribute: 'cn', userSearchBase: 'dc=example,dc=com', username: 'einstein', starttls: true, } try { await authenticate(options) } catch (error) { e = error } expect(e).toBeTruthy() }) it('Unmatched supplied groupMemberUserAttribute should return empty group list', async () => { let options = { ldapOpts: { url: url, }, userDn: 'cn=gauss,ou=users,dc=example,dc=com', userPassword: 'password', userSearchBase: 'dc=example,dc=com', usernameAttribute: 'uid', username: 'gauss', groupsSearchBase: 'dc=example,dc=com', groupClass: 'groupOfNames', groupMemberAttribute: 'member', groupMemberUserAttribute: 'dnWRONG', } let user = await authenticate(options) expect(user).toBeTruthy() expect(user.groups.length).toBeLessThan(1) }) })