ldap-authentication 2.3.2 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/Dockerfile +5 -0
- package/.devcontainer/devcontainer.json +24 -0
- package/.devcontainer/docker-compose.yml +22 -0
- package/.github/workflows/integration-test.yml +54 -0
- package/.vscode/launch.json +15 -0
- package/README.md +46 -1
- package/docker-compose.yml +13 -0
- package/index.js +13 -1
- package/package.json +3 -3
- package/test/test.js +67 -35
- package/.travis.yml +0 -3
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
|
2
|
+
// README at: https://github.com/devcontainers/templates/tree/main/src/postgres
|
|
3
|
+
{
|
|
4
|
+
"name": "ldap-authentication",
|
|
5
|
+
"dockerComposeFile": ["./docker-compose.yml"],
|
|
6
|
+
"service": "ldap-authentication",
|
|
7
|
+
"workspaceFolder": "/workspace",
|
|
8
|
+
// Features to add to the dev container. More info: https://containers.dev/features.
|
|
9
|
+
// "features": {},
|
|
10
|
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
|
11
|
+
// This can be used to network with other containers or the host.
|
|
12
|
+
// "forwardPorts": [5000, 5432],
|
|
13
|
+
// Use 'postCreateCommand' to run commands after the container is created.
|
|
14
|
+
"postCreateCommand": "npm install",
|
|
15
|
+
// Configure tool-specific properties.
|
|
16
|
+
// "customizations": {},
|
|
17
|
+
"customizations": {
|
|
18
|
+
"vscode": {
|
|
19
|
+
"extensions": ["esbenp.prettier-vscode", "ms-azuretools.vscode-docker"]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
|
23
|
+
// "remoteUser": "root"
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
version: "3"
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
ldap-authentication:
|
|
5
|
+
build:
|
|
6
|
+
context: ..
|
|
7
|
+
dockerfile: .devcontainer/Dockerfile
|
|
8
|
+
volumes:
|
|
9
|
+
- ..:/workspace:cached
|
|
10
|
+
command: sleep infinity
|
|
11
|
+
|
|
12
|
+
ldap:
|
|
13
|
+
image: bitnami/openldap
|
|
14
|
+
ports:
|
|
15
|
+
- '1389:1389'
|
|
16
|
+
- '1636:1636'
|
|
17
|
+
environment:
|
|
18
|
+
- LDAP_ROOT=dc=example,dc=com
|
|
19
|
+
- LDAP_ADMIN_USERNAME=read-only-admin
|
|
20
|
+
- LDAP_ADMIN_PASSWORD=password
|
|
21
|
+
- LDAP_USERS=gauss,einstein
|
|
22
|
+
- LDAP_PASSWORDS=password,password
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: 'Integration Tests'
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
INGITHUB: true
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
paths-ignore:
|
|
9
|
+
- 'README.md'
|
|
10
|
+
- 'LICENSE'
|
|
11
|
+
- 'SECURITY.md'
|
|
12
|
+
pull_request:
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
integration:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
node-version: [15.x, 16.x, 17.x, 18.x]
|
|
20
|
+
|
|
21
|
+
name: 'Integration Node v${{ matrix.node-version }}'
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v3
|
|
25
|
+
|
|
26
|
+
- name: Install LDAP tools
|
|
27
|
+
run: sudo apt-get install -y ldap-utils
|
|
28
|
+
|
|
29
|
+
- name: Start containers
|
|
30
|
+
run: docker-compose -f "docker-compose.yml" up -d
|
|
31
|
+
|
|
32
|
+
- name: Wait for LDAP server to become available
|
|
33
|
+
uses: nick-fields/retry@v2
|
|
34
|
+
with:
|
|
35
|
+
timeout_minutes: 5
|
|
36
|
+
max_attempts: 10
|
|
37
|
+
polling_interval_seconds: 3
|
|
38
|
+
command: |
|
|
39
|
+
ldapsearch -LLL -o 'ldif-wrap=no' \
|
|
40
|
+
-H ldap://localhost:1389 \
|
|
41
|
+
-D 'cn=read-only-admin,dc=example,dc=com' \
|
|
42
|
+
-w password \
|
|
43
|
+
-b 'cn=einstein,ou=users,dc=example,dc=com' DN
|
|
44
|
+
|
|
45
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
46
|
+
uses: actions/setup-node@v3
|
|
47
|
+
with:
|
|
48
|
+
node-version: ${{ matrix.node-version }}
|
|
49
|
+
- run: npm install
|
|
50
|
+
- run: npm run test
|
|
51
|
+
|
|
52
|
+
- name: Stop containers
|
|
53
|
+
if: always()
|
|
54
|
+
run: docker-compose -f "docker-compose.yml" down
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Debug Example",
|
|
11
|
+
"skipFiles": ["<node_internals>/**"],
|
|
12
|
+
"program": "${workspaceFolder}/example/index.js"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# A Simple node Library that Authenticates a User Against an LDAP/AD Server
|
|
2
2
|
|
|
3
|
-
[](https://github.com/shaozi/ldap-authentication/actions/workflows/integration-test.yml)
|
|
4
4
|
[](https://snyk.io/test/github/shaozi/ldap-authentication?targetFile=package.json)
|
|
5
5
|
|
|
6
6
|
## Goal
|
|
@@ -176,3 +176,48 @@ auth()
|
|
|
176
176
|
- `groupClass`: if specified with groupsSearchBase, will be used as objectClass in search filter for authenticated user groups
|
|
177
177
|
- `groupMemberAttribute`: if specified with groupClass and groupsSearchBase, will be used as member name (if not specified this defaults to `member`) in search filter for authenticated user groups
|
|
178
178
|
- `groupMemberUserAttribute`: if specified with groupClass and groupsSearchBase, will be used as the attribute on the user object (if not specified this defaults to `dn`) in search filter for authenticated user groups
|
|
179
|
+
|
|
180
|
+
## Returns
|
|
181
|
+
|
|
182
|
+
The user object if `authenticate()` is success.
|
|
183
|
+
|
|
184
|
+
In version 2, The user object has a `raw` field that has the raw data from the LDAP/AD server. It can be used to access buffer objects (profile pics for example).
|
|
185
|
+
|
|
186
|
+
Buffer data can now be accessed by `user.raw.profilePhoto`, etc, instead of `user.profilePhoto`.
|
|
187
|
+
|
|
188
|
+
In version 3, the `raw` field is no longer used. Instead, append `;binary` to the attributes you
|
|
189
|
+
want to get back as buffer. Check the following example on how to get a user's profile photo:
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
export async function verifyLogin(email: string, password: string) {
|
|
193
|
+
|
|
194
|
+
const options = {
|
|
195
|
+
//...other config options
|
|
196
|
+
userPassword: password,
|
|
197
|
+
username: email,
|
|
198
|
+
attributes: ['thumbnailPhoto;binary', 'givenName', 'sn', 'sAMAccountName', 'userPrincipalName', 'memberOf' ]
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const ldapUser = await authenticate(options);
|
|
203
|
+
|
|
204
|
+
if (!ldapUser) {
|
|
205
|
+
return { error: "user not found" };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// accessing the image
|
|
209
|
+
const profilePhoto = ldapUser['thumbnailPhoto;binary'];
|
|
210
|
+
|
|
211
|
+
/* using the image
|
|
212
|
+
<img src={`data:image/*;base64,${user.profilePhoto}`} />
|
|
213
|
+
*/
|
|
214
|
+
return { user: ldapUser };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Supported Node Versions
|
|
220
|
+
|
|
221
|
+
Version 2 supports Node version 12, 14, 15, 16, 17 and 18.
|
|
222
|
+
|
|
223
|
+
Version 3 supports Node version 15, 16, 17 and 18
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
version: "3"
|
|
2
|
+
services:
|
|
3
|
+
ldap:
|
|
4
|
+
image: bitnami/openldap:2.6.3
|
|
5
|
+
ports:
|
|
6
|
+
- '1389:1389'
|
|
7
|
+
- '1636:1636'
|
|
8
|
+
environment:
|
|
9
|
+
- LDAP_ROOT=dc=example,dc=com
|
|
10
|
+
- LDAP_ADMIN_USERNAME=read-only-admin
|
|
11
|
+
- LDAP_ADMIN_PASSWORD=password
|
|
12
|
+
- LDAP_USERS=gauss,einstein
|
|
13
|
+
- LDAP_PASSWORDS=password,password
|
package/index.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
const assert = require('assert')
|
|
2
2
|
const ldap = require('ldapjs')
|
|
3
3
|
|
|
4
|
+
// convert a SearchResultEntry object in ldapjs 3.0
|
|
5
|
+
// to a user object to maintain backward compatibility
|
|
6
|
+
|
|
7
|
+
function _searchResultToUser(pojo) {
|
|
8
|
+
assert(pojo.type == 'SearchResultEntry')
|
|
9
|
+
let user = { dn: pojo.objectName }
|
|
10
|
+
pojo.attributes.forEach((attribute) => {
|
|
11
|
+
user[attribute.type] =
|
|
12
|
+
attribute.values.length == 1 ? attribute.values[0] : attribute.values
|
|
13
|
+
})
|
|
14
|
+
return user
|
|
15
|
+
}
|
|
4
16
|
// bind and return the ldap client
|
|
5
17
|
function _ldapBind(dn, password, starttls, ldapOpts) {
|
|
6
18
|
return new Promise(function (resolve, reject) {
|
|
@@ -86,7 +98,7 @@ async function _searchUser(
|
|
|
86
98
|
return
|
|
87
99
|
}
|
|
88
100
|
res.on('searchEntry', function (entry) {
|
|
89
|
-
user = entry.
|
|
101
|
+
user = _searchResultToUser(entry.pojo)
|
|
90
102
|
})
|
|
91
103
|
res.on('searchReference', function (referral) {
|
|
92
104
|
// TODO: we don't support reference yet
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ldap-authentication",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "A simple async nodejs library for LDAP user authentication",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://github.com/shaozi/ldap-authentication#readme",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"ldapjs": "^
|
|
39
|
+
"ldapjs": "^3.0.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"jasmine": "^4.
|
|
42
|
+
"jasmine": "^4.6.0"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/test/test.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const { authenticate, LdapAuthenticationError } = require('../index.js')
|
|
2
2
|
|
|
3
|
+
const url = process.env.INGITHUB ? 'ldap://localhost:1389' : 'ldap://ldap:1389'
|
|
4
|
+
|
|
3
5
|
describe('ldap-authentication test', () => {
|
|
4
6
|
it('Use an admin user to check if user exists', async () => {
|
|
5
7
|
let options = {
|
|
6
8
|
ldapOpts: {
|
|
7
|
-
url:
|
|
9
|
+
url: url,
|
|
8
10
|
},
|
|
9
11
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
10
12
|
adminPassword: 'password',
|
|
@@ -13,6 +15,7 @@ describe('ldap-authentication test', () => {
|
|
|
13
15
|
usernameAttribute: 'uid',
|
|
14
16
|
username: 'gauss',
|
|
15
17
|
}
|
|
18
|
+
|
|
16
19
|
let user = await authenticate(options)
|
|
17
20
|
expect(user).toBeTruthy()
|
|
18
21
|
expect(user.uid).toEqual('gauss')
|
|
@@ -20,7 +23,7 @@ describe('ldap-authentication test', () => {
|
|
|
20
23
|
it('Use an admin user to authenticate a regular user', async () => {
|
|
21
24
|
let options = {
|
|
22
25
|
ldapOpts: {
|
|
23
|
-
url:
|
|
26
|
+
url: url,
|
|
24
27
|
},
|
|
25
28
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
26
29
|
adminPassword: 'password',
|
|
@@ -29,6 +32,7 @@ describe('ldap-authentication test', () => {
|
|
|
29
32
|
usernameAttribute: 'uid',
|
|
30
33
|
username: 'gauss',
|
|
31
34
|
}
|
|
35
|
+
|
|
32
36
|
let user = await authenticate(options)
|
|
33
37
|
expect(user).toBeTruthy()
|
|
34
38
|
expect(user.uid).toEqual('gauss')
|
|
@@ -36,7 +40,7 @@ describe('ldap-authentication test', () => {
|
|
|
36
40
|
it('Use an admin user to authenticate a regular user and return attrubutes', async () => {
|
|
37
41
|
let options = {
|
|
38
42
|
ldapOpts: {
|
|
39
|
-
url:
|
|
43
|
+
url: url,
|
|
40
44
|
},
|
|
41
45
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
42
46
|
adminPassword: 'password',
|
|
@@ -46,23 +50,25 @@ describe('ldap-authentication test', () => {
|
|
|
46
50
|
username: 'gauss',
|
|
47
51
|
attributes: ['uid', 'sn'],
|
|
48
52
|
}
|
|
53
|
+
|
|
49
54
|
let user = await authenticate(options)
|
|
50
55
|
expect(user).toBeTruthy()
|
|
51
56
|
expect(user.uid).toEqual('gauss')
|
|
52
|
-
expect(user.sn).toEqual('
|
|
57
|
+
expect(user.sn).toEqual('Bar1')
|
|
53
58
|
expect(user.cn).toBeUndefined()
|
|
54
59
|
})
|
|
55
60
|
it('Use an regular user to authenticate iteself', async () => {
|
|
56
61
|
let options = {
|
|
57
62
|
ldapOpts: {
|
|
58
|
-
url:
|
|
63
|
+
url: url,
|
|
59
64
|
},
|
|
60
|
-
userDn: '
|
|
65
|
+
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
61
66
|
userPassword: 'password',
|
|
62
67
|
userSearchBase: 'dc=example,dc=com',
|
|
63
68
|
usernameAttribute: 'uid',
|
|
64
69
|
username: 'einstein',
|
|
65
70
|
}
|
|
71
|
+
|
|
66
72
|
let user = await authenticate(options)
|
|
67
73
|
expect(user).toBeTruthy()
|
|
68
74
|
expect(user.uid).toEqual('einstein')
|
|
@@ -70,36 +76,38 @@ describe('ldap-authentication test', () => {
|
|
|
70
76
|
it('Use an regular user to authenticate iteself and return attributes', async () => {
|
|
71
77
|
let options = {
|
|
72
78
|
ldapOpts: {
|
|
73
|
-
url:
|
|
79
|
+
url: url,
|
|
74
80
|
},
|
|
75
|
-
userDn: '
|
|
81
|
+
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
76
82
|
userPassword: 'password',
|
|
77
83
|
userSearchBase: 'dc=example,dc=com',
|
|
78
84
|
usernameAttribute: 'uid',
|
|
79
85
|
username: 'einstein',
|
|
80
86
|
attributes: ['uid', 'sn'],
|
|
81
87
|
}
|
|
88
|
+
|
|
82
89
|
let user = await authenticate(options)
|
|
83
90
|
expect(user).toBeTruthy()
|
|
84
91
|
expect(user.uid).toEqual('einstein')
|
|
85
|
-
expect(user.sn).toEqual('
|
|
92
|
+
expect(user.sn).toEqual('Bar2')
|
|
86
93
|
expect(user.cn).toBeUndefined()
|
|
87
94
|
})
|
|
88
95
|
it('Use an regular user to authenticate iteself without search', async () => {
|
|
89
96
|
let options = {
|
|
90
97
|
ldapOpts: {
|
|
91
|
-
url:
|
|
98
|
+
url: url,
|
|
92
99
|
},
|
|
93
|
-
userDn: '
|
|
100
|
+
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
94
101
|
userPassword: 'password',
|
|
95
102
|
}
|
|
103
|
+
|
|
96
104
|
let user = await authenticate(options)
|
|
97
105
|
expect(user).toBeTruthy()
|
|
98
106
|
})
|
|
99
107
|
it('Use an admin user to authenticate a regular user and fetch user group information', async () => {
|
|
100
108
|
let options = {
|
|
101
109
|
ldapOpts: {
|
|
102
|
-
url:
|
|
110
|
+
url: url,
|
|
103
111
|
},
|
|
104
112
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
105
113
|
adminPassword: 'password',
|
|
@@ -108,10 +116,11 @@ describe('ldap-authentication test', () => {
|
|
|
108
116
|
usernameAttribute: 'uid',
|
|
109
117
|
username: 'gauss',
|
|
110
118
|
groupsSearchBase: 'dc=example,dc=com',
|
|
111
|
-
groupClass: '
|
|
112
|
-
groupMemberAttribute: '
|
|
119
|
+
groupClass: 'groupOfNames',
|
|
120
|
+
groupMemberAttribute: 'member',
|
|
113
121
|
groupMemberUserAttribute: 'dn',
|
|
114
122
|
}
|
|
123
|
+
|
|
115
124
|
let user = await authenticate(options)
|
|
116
125
|
expect(user).toBeTruthy()
|
|
117
126
|
expect(user.groups.length).toBeGreaterThan(0)
|
|
@@ -119,18 +128,19 @@ describe('ldap-authentication test', () => {
|
|
|
119
128
|
it('Use regular user to authenticate and fetch user group information', async () => {
|
|
120
129
|
let options = {
|
|
121
130
|
ldapOpts: {
|
|
122
|
-
url:
|
|
131
|
+
url: url,
|
|
123
132
|
},
|
|
124
|
-
userDn: '
|
|
133
|
+
userDn: 'cn=gauss,ou=users,dc=example,dc=com',
|
|
125
134
|
userPassword: 'password',
|
|
126
135
|
userSearchBase: 'dc=example,dc=com',
|
|
127
136
|
usernameAttribute: 'uid',
|
|
128
137
|
username: 'gauss',
|
|
129
138
|
groupsSearchBase: 'dc=example,dc=com',
|
|
130
|
-
groupClass: '
|
|
131
|
-
groupMemberAttribute: '
|
|
139
|
+
groupClass: 'groupOfNames',
|
|
140
|
+
groupMemberAttribute: 'member',
|
|
132
141
|
groupMemberUserAttribute: 'dn',
|
|
133
142
|
}
|
|
143
|
+
|
|
134
144
|
let user = await authenticate(options)
|
|
135
145
|
expect(user).toBeTruthy()
|
|
136
146
|
expect(user.groups.length).toBeGreaterThan(0)
|
|
@@ -138,9 +148,9 @@ describe('ldap-authentication test', () => {
|
|
|
138
148
|
it('Not specifying groupMemberAttribute or groupMemberUserAttribute should not cause an error and fallback to default values', async () => {
|
|
139
149
|
let options = {
|
|
140
150
|
ldapOpts: {
|
|
141
|
-
url:
|
|
151
|
+
url: url,
|
|
142
152
|
},
|
|
143
|
-
userDn: '
|
|
153
|
+
userDn: 'cn=gauss,ou=users,dc=example,dc=com',
|
|
144
154
|
userPassword: 'password',
|
|
145
155
|
userSearchBase: 'dc=example,dc=com',
|
|
146
156
|
usernameAttribute: 'uid',
|
|
@@ -148,6 +158,7 @@ describe('ldap-authentication test', () => {
|
|
|
148
158
|
groupsSearchBase: 'dc=example,dc=com',
|
|
149
159
|
groupClass: 'groupOfUniqueNames',
|
|
150
160
|
}
|
|
161
|
+
|
|
151
162
|
let user = await authenticate(options)
|
|
152
163
|
expect(user).toBeTruthy()
|
|
153
164
|
expect(user.groups.length).toBeLessThan(1)
|
|
@@ -158,7 +169,7 @@ describe('ldap-authentication negative test', () => {
|
|
|
158
169
|
it('wrong admin user should fail', async () => {
|
|
159
170
|
let options = {
|
|
160
171
|
ldapOpts: {
|
|
161
|
-
url:
|
|
172
|
+
url: url,
|
|
162
173
|
},
|
|
163
174
|
adminDn: 'cn=not-exist,dc=example,dc=com',
|
|
164
175
|
adminPassword: 'password',
|
|
@@ -167,18 +178,20 @@ describe('ldap-authentication negative test', () => {
|
|
|
167
178
|
usernameAttribute: 'uid',
|
|
168
179
|
username: 'gauss',
|
|
169
180
|
}
|
|
181
|
+
|
|
170
182
|
let e = null
|
|
171
183
|
try {
|
|
172
184
|
await authenticate(options)
|
|
173
185
|
} catch (error) {
|
|
174
186
|
e = error
|
|
175
187
|
}
|
|
188
|
+
|
|
176
189
|
expect(e).toBeTruthy()
|
|
177
190
|
})
|
|
178
191
|
it('wrong admin password should fail', async () => {
|
|
179
192
|
let options = {
|
|
180
193
|
ldapOpts: {
|
|
181
|
-
url:
|
|
194
|
+
url: url,
|
|
182
195
|
},
|
|
183
196
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
184
197
|
adminPassword: '',
|
|
@@ -187,18 +200,20 @@ describe('ldap-authentication negative test', () => {
|
|
|
187
200
|
usernameAttribute: 'uid',
|
|
188
201
|
username: 'gauss',
|
|
189
202
|
}
|
|
203
|
+
|
|
190
204
|
let e = null
|
|
191
205
|
try {
|
|
192
206
|
await authenticate(options)
|
|
193
207
|
} catch (error) {
|
|
194
208
|
e = error
|
|
195
209
|
}
|
|
210
|
+
|
|
196
211
|
expect(e).toBeTruthy()
|
|
197
212
|
})
|
|
198
213
|
it('admin auth wrong username should fail', async () => {
|
|
199
214
|
let options = {
|
|
200
215
|
ldapOpts: {
|
|
201
|
-
url:
|
|
216
|
+
url: url,
|
|
202
217
|
},
|
|
203
218
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
204
219
|
adminPassword: 'password',
|
|
@@ -207,18 +222,20 @@ describe('ldap-authentication negative test', () => {
|
|
|
207
222
|
usernameAttribute: 'uid',
|
|
208
223
|
username: 'wrong',
|
|
209
224
|
}
|
|
225
|
+
|
|
210
226
|
let e = null
|
|
211
227
|
try {
|
|
212
228
|
await authenticate(options)
|
|
213
229
|
} catch (error) {
|
|
214
230
|
e = error
|
|
215
231
|
}
|
|
232
|
+
|
|
216
233
|
expect(e).toBeTruthy()
|
|
217
234
|
})
|
|
218
235
|
it('admin auth wrong user password should fail', async () => {
|
|
219
236
|
let options = {
|
|
220
237
|
ldapOpts: {
|
|
221
|
-
url:
|
|
238
|
+
url: url,
|
|
222
239
|
},
|
|
223
240
|
adminDn: 'cn=read-only-admin,dc=example,dc=com',
|
|
224
241
|
adminPassword: 'password',
|
|
@@ -227,18 +244,20 @@ describe('ldap-authentication negative test', () => {
|
|
|
227
244
|
usernameAttribute: 'uid',
|
|
228
245
|
username: 'gauss',
|
|
229
246
|
}
|
|
247
|
+
|
|
230
248
|
let e = null
|
|
231
249
|
try {
|
|
232
250
|
await authenticate(options)
|
|
233
251
|
} catch (error) {
|
|
234
252
|
e = error
|
|
235
253
|
}
|
|
254
|
+
|
|
236
255
|
expect(e).toBeTruthy()
|
|
237
256
|
})
|
|
238
257
|
it('user auth wrong username should fail', async () => {
|
|
239
258
|
let options = {
|
|
240
259
|
ldapOpts: {
|
|
241
|
-
url:
|
|
260
|
+
url: url,
|
|
242
261
|
},
|
|
243
262
|
userDn: 'cn=not-exist,dc=example,dc=com',
|
|
244
263
|
userPassword: 'password',
|
|
@@ -246,18 +265,20 @@ describe('ldap-authentication negative test', () => {
|
|
|
246
265
|
usernameAttribute: 'uid',
|
|
247
266
|
username: 'gauss',
|
|
248
267
|
}
|
|
268
|
+
|
|
249
269
|
let e = null
|
|
250
270
|
try {
|
|
251
271
|
await authenticate(options)
|
|
252
272
|
} catch (error) {
|
|
253
273
|
e = error
|
|
254
274
|
}
|
|
275
|
+
|
|
255
276
|
expect(e).toBeTruthy()
|
|
256
277
|
})
|
|
257
278
|
it('user auth wrong user password should fail', async () => {
|
|
258
279
|
let options = {
|
|
259
280
|
ldapOpts: {
|
|
260
|
-
url:
|
|
281
|
+
url: url,
|
|
261
282
|
},
|
|
262
283
|
userDn: 'cn=gauss,dc=example,dc=com',
|
|
263
284
|
userPassword: 'wrongpassword',
|
|
@@ -265,45 +286,51 @@ describe('ldap-authentication negative test', () => {
|
|
|
265
286
|
usernameAttribute: 'uid',
|
|
266
287
|
username: 'gauss',
|
|
267
288
|
}
|
|
289
|
+
|
|
268
290
|
let e = null
|
|
269
291
|
try {
|
|
270
292
|
await authenticate(options)
|
|
271
293
|
} catch (error) {
|
|
272
294
|
e = error
|
|
273
295
|
}
|
|
296
|
+
|
|
274
297
|
expect(e).toBeTruthy()
|
|
275
298
|
})
|
|
276
299
|
it('Use an regular user to authenticate iteself without search with wrong password should fail', async () => {
|
|
277
300
|
let options = {
|
|
278
301
|
ldapOpts: {
|
|
279
|
-
url:
|
|
302
|
+
url: url,
|
|
280
303
|
},
|
|
281
304
|
userDn: 'uid=einstein,dc=example,dc=com',
|
|
282
305
|
userPassword: '',
|
|
283
306
|
}
|
|
307
|
+
|
|
284
308
|
try {
|
|
285
309
|
await authenticate(options)
|
|
286
310
|
} catch (error) {
|
|
287
311
|
e = error
|
|
288
312
|
}
|
|
313
|
+
|
|
289
314
|
expect(e).toBeTruthy()
|
|
290
315
|
})
|
|
291
316
|
it('Wrong options give LdapAuthenticationError', async () => {
|
|
292
317
|
let options = {
|
|
293
318
|
ldapOpts: {
|
|
294
|
-
url:
|
|
319
|
+
url: url,
|
|
295
320
|
},
|
|
296
|
-
userDn: '
|
|
321
|
+
userDn: 'cn=einstein,ou=users,dc=example,dc=com',
|
|
297
322
|
userPassword: 'password',
|
|
298
|
-
usernameAttribute: '
|
|
323
|
+
usernameAttribute: 'wrongattribute',
|
|
299
324
|
userSearchBase: 'dc=example,dc=com',
|
|
300
325
|
username: 'einstein',
|
|
301
326
|
}
|
|
327
|
+
|
|
302
328
|
try {
|
|
303
329
|
await authenticate(options)
|
|
304
330
|
} catch (error) {
|
|
305
331
|
e = error
|
|
306
332
|
}
|
|
333
|
+
|
|
307
334
|
expect(e).toBeTruthy()
|
|
308
335
|
expect(e).toBeInstanceOf(LdapAuthenticationError)
|
|
309
336
|
})
|
|
@@ -319,11 +346,13 @@ describe('ldap-authentication negative test', () => {
|
|
|
319
346
|
userSearchBase: 'dc=example,dc=com',
|
|
320
347
|
username: 'einstein',
|
|
321
348
|
}
|
|
349
|
+
|
|
322
350
|
try {
|
|
323
351
|
await authenticate(options)
|
|
324
352
|
} catch (error) {
|
|
325
353
|
e = error
|
|
326
354
|
}
|
|
355
|
+
|
|
327
356
|
expect(e).toBeTruthy()
|
|
328
357
|
})
|
|
329
358
|
it('Unreachable ldap server should throw error (with starttls=true)', async () => {
|
|
@@ -339,28 +368,31 @@ describe('ldap-authentication negative test', () => {
|
|
|
339
368
|
username: 'einstein',
|
|
340
369
|
starttls: true,
|
|
341
370
|
}
|
|
371
|
+
|
|
342
372
|
try {
|
|
343
373
|
await authenticate(options)
|
|
344
374
|
} catch (error) {
|
|
345
375
|
e = error
|
|
346
376
|
}
|
|
377
|
+
|
|
347
378
|
expect(e).toBeTruthy()
|
|
348
379
|
})
|
|
349
380
|
it('Unmatched supplied groupMemberUserAttribute should return empty group list', async () => {
|
|
350
381
|
let options = {
|
|
351
382
|
ldapOpts: {
|
|
352
|
-
url:
|
|
383
|
+
url: url,
|
|
353
384
|
},
|
|
354
|
-
userDn: '
|
|
385
|
+
userDn: 'cn=gauss,ou=users,dc=example,dc=com',
|
|
355
386
|
userPassword: 'password',
|
|
356
387
|
userSearchBase: 'dc=example,dc=com',
|
|
357
388
|
usernameAttribute: 'uid',
|
|
358
389
|
username: 'gauss',
|
|
359
390
|
groupsSearchBase: 'dc=example,dc=com',
|
|
360
|
-
groupClass: '
|
|
361
|
-
groupMemberAttribute: '
|
|
362
|
-
groupMemberUserAttribute: '
|
|
391
|
+
groupClass: 'groupOfNames',
|
|
392
|
+
groupMemberAttribute: 'member',
|
|
393
|
+
groupMemberUserAttribute: 'dnWRONG',
|
|
363
394
|
}
|
|
395
|
+
|
|
364
396
|
let user = await authenticate(options)
|
|
365
397
|
expect(user).toBeTruthy()
|
|
366
398
|
expect(user.groups.length).toBeLessThan(1)
|
package/.travis.yml
DELETED