directoryserver: test all combinations of 2fa checks

directory server cannot know the source of the requesting client.
there are 3 sources - external app, cloudron app, cloudron dashboard.

the 2fa is requested by client by passing `+totpToken=xxx` . totpToken
is ignored if the user has no 2fa setup. If present, it is validated.
This commit is contained in:
Girish Ramakrishnan
2024-01-22 13:09:43 +01:00
parent 0ed144fe81
commit 3220721f84

View File

@@ -135,29 +135,59 @@ describe('Directory Server (LDAP)', function () {
await ldapBind(`mail=${admin.email},ou=users,dc=cloudron`, admin.password);
});
it('enable 2fa', async function () {
// directory server cannot know the source of the requesting client.
// there are 3 sources - external app, cloudron app, cloudron dashboard.
// the 2fa is requested by client by passing `+totpToken=xxx` . totpToken
// is ignored if the user has no 2fa setup. If present, it is validated.
it('enable 2fa for admin', async function () {
twofa = await users.setTwoFactorAuthenticationSecret(admin, auditSource);
const totpToken = speakeasy.totp({ secret: twofa.secret, encoding: 'base32' });
await users.enableTwoFactorAuthentication(await users.get(admin.id), totpToken, auditSource);
});
it('fails with empty 2fa', async function () {
it('totp check not requested - fails with bad password', async function () {
const [error] = await safe(ldapBind(`cn=${admin.id},ou=users,dc=cloudron`, admin.password + 'random'));
expect(error).to.be.a(ldap.InvalidCredentialsError);
expect(error.lde_message).to.be('Username and password does not match');
});
it('totp check not requested - succeeds with good password', async function () {
await ldapBind(`cn=${admin.id},ou=users,dc=cloudron`, admin.password);
});
it('totp check requested - fails with empty 2fa if user has 2fa', async function () {
const [error] = await safe(ldapBind(`cn=${admin.id}+totptoken=,ou=users,dc=cloudron`, admin.password));
expect(error).to.be.a(ldap.InvalidCredentialsError);
expect(error.lde_message).to.be('A totpToken must be provided');
});
it('fails with invalid 2fa', async function () {
it('totp check requested - succeeds with empty 2fa if user has no 2fa', async function () {
await ldapBind(`cn=${user.id}+totptoken=,ou=users,dc=cloudron`, user.password);
});
it('totp check requested - fails with invalid 2fa', async function () {
const [error] = await safe(ldapBind(`cn=${admin.id}+totptoken=schlecht,ou=users,dc=cloudron`, admin.password));
expect(error).to.be.a(ldap.InvalidCredentialsError);
expect(error.lde_message).to.be('Invalid totpToken');
});
it('fails with no 2fa', async function () {
await ldapBind(`cn=${admin.id},ou=users,dc=cloudron`, admin.password);
it('totp check requested - succeeds with invalid 2fa if user has no 2fa', async function () {
await ldapBind(`cn=${user.id}+totptoken=schlecht,ou=users,dc=cloudron`, user.password);
});
it('succeeds with valid 2fa', async function () {
it('totp check requested - fails with bad password if user has 2fa', async function () {
const totpToken = speakeasy.totp({ secret: twofa.secret, encoding: 'base32' });
const [error] = await safe(ldapBind(`cn=${admin.email}+totpToken=${totpToken},ou=users,dc=cloudron`, admin.password + 'random'));
expect(error.lde_message).to.be('Username and password does not match');
});
it('totp check requested - fails with bad password if user has no 2fa', async function () {
const totpToken = speakeasy.totp({ secret: twofa.secret, encoding: 'base32' });
const [error] = await safe(ldapBind(`cn=${admin.email}+totpToken=${totpToken},ou=users,dc=cloudron`, admin.password + 'random'));
expect(error.lde_message).to.be('Username and password does not match');
});
it('totp check requested - succeeds with valid 2fa', async function () {
const totpToken = speakeasy.totp({ secret: twofa.secret, encoding: 'base32' });
await ldapBind(`cn=${admin.email}+totpToken=${totpToken},ou=users,dc=cloudron`, admin.password);
});