* initial run * Update ParseGraphQLServer.spec.js * temporarily enable reporter * Bump retry limit * fix undefined database * try to catch error * Handle LiveQueryServers * Update Config.js * fast-fail false * Remove usage of AppCache * oops * Update contributing guide * enable debugger, try network retry attempt 1 * Fix ldap unbinding * move non specs to support * add missing mock adapter * fix Parse.Push * RestController should match batch.spec.js * Remove request attempt limit * handle index.spec.js * Update CHANGELOG.md * Handle error: tuple concurrently updated * test transactions * Clear RedisCache after every test * LoggerController.spec.js * Update schemas.spec.js * finally fix transactions * fix geopoint deadlock * transaction with clean database * batch.spec.js
213 lines
7.5 KiB
JavaScript
213 lines
7.5 KiB
JavaScript
const ldap = require('../lib/Adapters/Auth/ldap');
|
|
const mockLdapServer = require('./support/MockLdapServer');
|
|
const fs = require('fs');
|
|
const port = 12345;
|
|
const sslport = 12346;
|
|
|
|
describe('Ldap Auth', () => {
|
|
it('Should fail with missing options', done => {
|
|
ldap
|
|
.validateAuthData({ id: 'testuser', password: 'testpw' })
|
|
.then(done.fail)
|
|
.catch(err => {
|
|
jequal(err.message, 'LDAP auth configuration missing');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Should return a resolved promise when validating the app id', done => {
|
|
ldap.validateAppId().then(done).catch(done.fail);
|
|
});
|
|
|
|
it('Should succeed with right credentials', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example');
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
};
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should succeed with right credentials when LDAPS is used and certifcate is not checked', async done => {
|
|
const server = await mockLdapServer(sslport, 'uid=testuser, o=example', false, true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldaps://localhost:${sslport}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
tlsOptions: { rejectUnauthorized: false },
|
|
};
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should succeed when LDAPS is used and the presented certificate is the expected certificate', async done => {
|
|
const server = await mockLdapServer(sslport, 'uid=testuser, o=example', false, true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldaps://localhost:${sslport}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
tlsOptions: {
|
|
ca: fs.readFileSync(__dirname + '/support/cert/cert.pem'),
|
|
rejectUnauthorized: true,
|
|
},
|
|
};
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should fail when LDAPS is used and the presented certificate is not the expected certificate', async done => {
|
|
const server = await mockLdapServer(sslport, 'uid=testuser, o=example', false, true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldaps://localhost:${sslport}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
tlsOptions: {
|
|
ca: fs.readFileSync(__dirname + '/support/cert/anothercert.pem'),
|
|
rejectUnauthorized: true,
|
|
},
|
|
};
|
|
try {
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
fail();
|
|
} catch (err) {
|
|
expect(err.message).toBe('LDAPS: Certificate mismatch');
|
|
}
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should fail when LDAPS is used certifcate matches but credentials are wrong', async done => {
|
|
const server = await mockLdapServer(sslport, 'uid=testuser, o=example', false, true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldaps://localhost:${sslport}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
tlsOptions: {
|
|
ca: fs.readFileSync(__dirname + '/support/cert/cert.pem'),
|
|
rejectUnauthorized: true,
|
|
},
|
|
};
|
|
try {
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'wrong!' }, options);
|
|
fail();
|
|
} catch (err) {
|
|
expect(err.message).toBe('LDAP: Wrong username or password');
|
|
}
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should fail with wrong credentials', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example');
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
};
|
|
try {
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'wrong!' }, options);
|
|
fail();
|
|
} catch (err) {
|
|
expect(err.message).toBe('LDAP: Wrong username or password');
|
|
}
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should succeed if user is in given group', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example');
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
groupCn: 'powerusers',
|
|
groupFilter: '(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
|
|
};
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should fail if user is not in given group', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example');
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
groupCn: 'groupTheUserIsNotIn',
|
|
groupFilter: '(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
|
|
};
|
|
try {
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
fail();
|
|
} catch (err) {
|
|
expect(err.message).toBe('LDAP: User not in group');
|
|
}
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should fail if the LDAP server does not allow searching inside the provided suffix', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example');
|
|
const options = {
|
|
suffix: 'o=invalid',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
groupCn: 'powerusers',
|
|
groupFilter: '(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
|
|
};
|
|
try {
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
fail();
|
|
} catch (err) {
|
|
expect(err.message).toBe('LDAP group search failed');
|
|
}
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should fail if the LDAP server encounters an error while searching', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example', true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
groupCn: 'powerusers',
|
|
groupFilter: '(&(uniqueMember=uid={{id}}, o=example)(objectClass=groupOfUniqueNames))',
|
|
};
|
|
try {
|
|
await ldap.validateAuthData({ id: 'testuser', password: 'secret' }, options);
|
|
fail();
|
|
} catch (err) {
|
|
expect(err.message).toBe('LDAP group search failed');
|
|
}
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should delete the password from authData after validation', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example', true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
};
|
|
const authData = { id: 'testuser', password: 'secret' };
|
|
await ldap.validateAuthData(authData, options);
|
|
expect(authData).toEqual({ id: 'testuser' });
|
|
server.close(done);
|
|
});
|
|
|
|
it('Should not save the password in the user record after authentication', async done => {
|
|
const server = await mockLdapServer(port, 'uid=testuser, o=example', true);
|
|
const options = {
|
|
suffix: 'o=example',
|
|
url: `ldap://localhost:${port}`,
|
|
dn: 'uid={{id}}, o=example',
|
|
};
|
|
await reconfigureServer({ auth: { ldap: options } });
|
|
const authData = { authData: { id: 'testuser', password: 'secret' } };
|
|
const returnedUser = await Parse.User.logInWith('ldap', authData);
|
|
const query = new Parse.Query('User');
|
|
const user = await query.equalTo('objectId', returnedUser.id).first({ useMasterKey: true });
|
|
expect(user.get('authData')).toEqual({ ldap: { id: 'testuser' } });
|
|
expect(user.get('authData').ldap.password).toBeUndefined();
|
|
server.close(done);
|
|
});
|
|
});
|