Skip to content

Commit 9d2bce7

Browse files
brododplewis
authored andcommitted
Add LDAP auth module (parse-community#6226)
1 parent cbddc7f commit 9d2bce7

File tree

6 files changed

+452
-0
lines changed

6 files changed

+452
-0
lines changed

package-lock.json

Lines changed: 150 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"graphql-upload": "8.1.0",
3939
"intersect": "1.0.1",
4040
"jsonwebtoken": "8.5.1",
41+
"ldapjs": "1.0.2",
4142
"lodash": "4.17.15",
4243
"lru-cache": "5.1.1",
4344
"mime": "2.4.4",

spec/LdapAuth.spec.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
const ldap = require('../lib/Adapters/Auth/ldap');
2+
const mockLdapServer = require('./MockLdapServer');
3+
const port = 12345;
4+
5+
it('Should fail with missing options', done => {
6+
ldap
7+
.validateAuthData({ id: 'testuser', password: 'testpw' })
8+
.then(done.fail)
9+
.catch(err => {
10+
jequal(err.message, 'LDAP auth configuration missing');
11+
done();
12+
});
13+
});
14+
15+
it('Should return a resolved promise when validating the app id', done => {
16+
ldap
17+
.validateAppId()
18+
.then(done)
19+
.catch(done.fail);
20+
});
21+
22+
it('Should succeed with right credentials', done => {
23+
mockLdapServer(port, 'uid=testuser, o=example').then(server => {
24+
const options = {
25+
suffix: 'o=example',
26+
url: `ldap://localhost:${port}`,
27+
dn: 'uid={{id}}, o=example',
28+
};
29+
ldap
30+
.validateAuthData({ id: 'testuser', password: 'secret' }, options)
31+
.then(done)
32+
.catch(done.fail)
33+
.finally(() => server.close());
34+
});
35+
});
36+
37+
it('Should fail with wrong credentials', done => {
38+
mockLdapServer(port, 'uid=testuser, o=example').then(server => {
39+
const options = {
40+
suffix: 'o=example',
41+
url: `ldap://localhost:${port}`,
42+
dn: 'uid={{id}}, o=example',
43+
};
44+
ldap
45+
.validateAuthData({ id: 'testuser', password: 'wrong!' }, options)
46+
.then(done.fail)
47+
.catch(err => {
48+
jequal(err.message, 'LDAP: Wrong username or password');
49+
done();
50+
})
51+
.finally(() => server.close());
52+
});
53+
});
54+
55+
it('Should succeed if user is in given group', done => {
56+
mockLdapServer(port, 'uid=testuser, o=example').then(server => {
57+
const options = {
58+
suffix: 'o=example',
59+
url: `ldap://localhost:${port}`,
60+
dn: 'uid={{id}}, o=example',
61+
groupCn: 'powerusers',
62+
groupFilter:
63+
'(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
64+
};
65+
66+
ldap
67+
.validateAuthData({ id: 'testuser', password: 'secret' }, options)
68+
.then(done)
69+
.catch(done.fail)
70+
.finally(() => server.close());
71+
});
72+
});
73+
74+
it('Should fail if user is not in given group', done => {
75+
mockLdapServer(port, 'uid=testuser, o=example').then(server => {
76+
const options = {
77+
suffix: 'o=example',
78+
url: `ldap://localhost:${port}`,
79+
dn: 'uid={{id}}, o=example',
80+
groupCn: 'groupTheUserIsNotIn',
81+
groupFilter:
82+
'(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
83+
};
84+
85+
ldap
86+
.validateAuthData({ id: 'testuser', password: 'secret' }, options)
87+
.then(done.fail)
88+
.catch(err => {
89+
jequal(err.message, 'LDAP: User not in group');
90+
done();
91+
})
92+
.finally(() => server.close());
93+
});
94+
});
95+
96+
it('Should fail if the LDAP server does not allow searching inside the provided suffix', done => {
97+
mockLdapServer(port, 'uid=testuser, o=example').then(server => {
98+
const options = {
99+
suffix: 'o=invalid',
100+
url: `ldap://localhost:${port}`,
101+
dn: 'uid={{id}}, o=example',
102+
groupCn: 'powerusers',
103+
groupFilter:
104+
'(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
105+
};
106+
107+
ldap
108+
.validateAuthData({ id: 'testuser', password: 'secret' }, options)
109+
.then(done.fail)
110+
.catch(err => {
111+
jequal(err.message, 'LDAP group search failed');
112+
done();
113+
})
114+
.finally(() => server.close());
115+
});
116+
});
117+
118+
it('Should fail if the LDAP server encounters an error while searching', done => {
119+
mockLdapServer(port, 'uid=testuser, o=example', true).then(server => {
120+
const options = {
121+
suffix: 'o=example',
122+
url: `ldap://localhost:${port}`,
123+
dn: 'uid={{id}}, o=example',
124+
groupCn: 'powerusers',
125+
groupFilter:
126+
'(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
127+
};
128+
129+
ldap
130+
.validateAuthData({ id: 'testuser', password: 'secret' }, options)
131+
.then(done.fail)
132+
.catch(err => {
133+
jequal(err.message, 'LDAP group search failed');
134+
done();
135+
})
136+
.finally(() => server.close());
137+
});
138+
});

0 commit comments

Comments
 (0)