Files
cloudron-box/src/test/ldap-test.js

1128 lines
46 KiB
JavaScript
Raw Normal View History

2015-08-12 15:00:38 +02:00
/* jslint node:true */
/* global it:false */
/* global describe:false */
2015-08-12 15:00:38 +02:00
/* global before:false */
/* global after:false */
'use strict';
var appdb = require('../appdb.js'),
apps = require('../apps.js'),
2015-08-12 15:00:38 +02:00
async = require('async'),
constants = require('../constants.js'),
database = require('../database.js'),
domains = require('../domains.js'),
EventEmitter = require('events').EventEmitter,
expect = require('expect.js'),
2016-09-27 15:56:02 -07:00
groups = require('../groups.js'),
2015-08-12 15:00:38 +02:00
ldapServer = require('../ldap.js'),
2018-01-21 00:27:13 -08:00
maildb = require('../maildb.js'),
2017-03-26 20:42:46 -07:00
mailboxdb = require('../mailboxdb.js'),
ldap = require('ldapjs'),
2020-11-12 23:25:33 -08:00
mail = require('../mail.js'),
settings = require('../settings.js'),
2018-04-29 10:58:45 -07:00
users = require('../users.js');
2015-08-12 15:00:38 +02:00
const DOMAIN_0 = {
domain: 'example.com',
zoneName: 'example.com',
config: {},
provider: 'manual',
fallbackCertificate: null,
tlsConfig: { provider: 'fallback' },
wellKnown: null
};
2018-01-22 20:35:21 +01:00
// owner
2015-08-12 15:00:38 +02:00
var USER_0 = {
username: 'userName0',
password: 'Username0pass?1234',
email: 'user0@' + DOMAIN_0.domain.toUpperCase(),
2020-02-13 22:06:54 -08:00
displayName: 'User 0',
role: 'owner'
2015-08-12 15:00:38 +02:00
};
2016-09-28 10:26:41 -07:00
var USER_0_ALIAS = 'Asterix';
// normal user
2015-08-12 15:00:38 +02:00
var USER_1 = {
username: 'Username1',
password: 'Username1pass?12345',
email: 'USER1@' + DOMAIN_0.domain,
2020-02-13 22:06:54 -08:00
displayName: 'User 1',
role: 'user'
2015-08-12 15:00:38 +02:00
};
var USER_2 = {
username: 'Username2',
password: 'Username2pass?12345',
email: 'USER2@' + DOMAIN_0.domain,
2020-02-13 22:06:54 -08:00
displayName: 'User 2',
role: 'user'
};
2015-08-12 15:00:38 +02:00
2016-09-30 09:18:41 -07:00
var GROUP_ID, GROUP_NAME = 'developers';
2016-09-27 15:56:02 -07:00
2016-05-01 20:01:34 -07:00
var AUDIT_SOURCE = {
ip: '1.2.3.4'
};
var APP_0 = {
id: 'appid-0',
appStoreId: 'appStoreId-0',
2019-08-30 13:12:49 -07:00
installationState: apps.ISTATE_INSTALLED,
2019-08-30 09:45:43 -07:00
error: null,
2019-08-30 13:12:49 -07:00
runState: apps.RSTATE_RUNNING,
location: 'some-location-0',
domain: DOMAIN_0.domain,
manifest: { version: '0.1', dockerImage: 'docker/app0', healthCheckPath: '/', httpPort: 80, title: 'app0' },
containerId: 'someContainerId',
portBindings: { port: 5678 },
health: null,
accessRestriction: null,
memoryLimit: 4294967296,
mailboxName: 'some-location-0.app',
mailboxDomain: DOMAIN_0.domain
};
2015-08-12 15:00:38 +02:00
function setup(done) {
async.series([
database.initialize.bind(null),
database._clear.bind(null),
ldapServer.start.bind(null),
2021-05-05 12:29:04 -07:00
settings.setDashboardLocation.bind(null, DOMAIN_0.domain, 'my.' + DOMAIN_0.domain),
2018-11-10 00:43:46 -08:00
domains.add.bind(null, DOMAIN_0.domain, DOMAIN_0, AUDIT_SOURCE),
2016-04-04 16:36:42 +02:00
function (callback) {
2018-04-29 10:58:45 -07:00
users.createOwner(USER_0.username, USER_0.password, USER_0.email, USER_0.displayName, AUDIT_SOURCE, function (error, result) {
2016-04-04 16:36:42 +02:00
if (error) return callback(error);
2019-07-02 20:22:17 -07:00
USER_0.id = result.id;
2016-04-04 16:36:42 +02:00
2019-07-02 20:22:17 -07:00
callback();
2016-04-04 16:36:42 +02:00
});
},
2019-08-20 11:45:00 -07:00
function (callback) {
appdb.add(APP_0.id, APP_0.appStoreId, APP_0.manifest, APP_0.location, APP_0.domain, apps._translatePortBindings(APP_0.portBindings, APP_0.manifest), APP_0, function (error) {
if (error) return callback(error);
apps._MOCK_GET_BY_IP_APP_ID = APP_0.id;
callback();
});
},
(done) => mailboxdb.addMailbox(USER_0.username.toLowerCase(), DOMAIN_0.domain, { ownerId: USER_0.id, ownerType: mail.OWNERTYPE_USER, active: true }, done),
(done) => mailboxdb.setAliasesForName(USER_0.username.toLowerCase(), DOMAIN_0.domain, [ { name: USER_0_ALIAS.toLocaleLowerCase(), domain: DOMAIN_0.domain} ], done),
appdb.update.bind(null, APP_0.id, { containerId: APP_0.containerId }),
appdb.setAddonConfig.bind(null, APP_0.id, 'sendmail', [{ name: 'MAIL_SMTP_USERNAME', value : `${APP_0.location}.app@${DOMAIN_0.domain}` }, { name: 'MAIL_SMTP_PASSWORD', value : 'sendmailpassword' }]),
appdb.setAddonConfig.bind(null, APP_0.id, 'recvmail', [{ name: 'MAIL_IMAP_USERNAME', value : `${APP_0.location}.app@${DOMAIN_0.domain}` }, { name: 'MAIL_IMAP_PASSWORD', value : 'recvmailpassword' }]),
mailboxdb.addMailbox.bind(null, APP_0.location + '.app', APP_0.domain, { ownerId: APP_0.id, ownerType: mail.OWNERTYPE_USER, active: true }),
2016-04-04 16:36:42 +02:00
function (callback) {
users.create(USER_1.username, USER_1.password, USER_1.email, USER_0.displayName, { }, AUDIT_SOURCE, function (error, result) {
2016-04-04 16:36:42 +02:00
if (error) return callback(error);
USER_1.id = result.id;
callback(null);
});
2016-09-27 15:56:02 -07:00
},
function (callback) {
users.create(USER_2.username, USER_2.password, USER_2.email, USER_0.displayName, { }, AUDIT_SOURCE, function (error, result) {
if (error) return callback(error);
USER_2.id = result.id;
callback(null);
});
},
2021-06-28 15:15:28 -07:00
async function () {
const result = await groups.add({ name: GROUP_NAME, source: '' });
2016-09-30 09:18:41 -07:00
2021-06-28 15:15:28 -07:00
GROUP_ID = result.id;
2016-09-30 09:18:41 -07:00
},
2021-06-28 15:15:28 -07:00
async function () {
await groups.addMember(GROUP_ID, USER_0.id);
await groups.addMember(GROUP_ID, USER_1.id);
2016-04-04 16:36:42 +02:00
}
], done);
2015-08-12 15:00:38 +02:00
}
function cleanup(done) {
2019-08-20 11:45:00 -07:00
apps._MOCK_GET_BY_IP_APP_ID = '';
2016-05-23 21:48:25 -07:00
async.series([
ldapServer.stop,
database._clear,
database.uninitialize
], done);
2015-08-12 15:00:38 +02:00
}
describe('Ldap', function () {
before(setup);
after(cleanup);
describe('bind', function () {
it('fails for nonexisting user', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:00:38 +02:00
client.bind('cn=doesnotexist,ou=users,dc=cloudron', 'password', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2015-08-12 15:00:38 +02:00
});
});
it('fails with wrong password', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:00:38 +02:00
client.bind('cn=' + USER_0.id + ',ou=users,dc=cloudron', 'wrongpassword', function (error) {
2015-08-12 15:00:38 +02:00
expect(error).to.be.a(ldap.InvalidCredentialsError);
client.unbind();
done();
2015-08-12 15:00:38 +02:00
});
});
it('succeeds without accessRestriction', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:00:38 +02:00
client.bind('cn=' + USER_0.id + ',ou=users,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be(null);
client.unbind();
done();
});
});
it('succeeds with username and without accessRestriction', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:00:38 +02:00
client.bind('cn=' + USER_0.username + ',ou=users,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be(null);
client.unbind();
done();
2015-08-12 15:00:38 +02:00
});
});
it('succeeds with email and without accessRestriction', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.email + ',ou=users,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be(null);
client.unbind();
done();
});
});
it('succeeds without accessRestriction when email is enabled', function (done) {
2018-01-21 00:27:13 -08:00
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2018-01-22 17:53:17 +01:00
client.bind('cn=' + USER_0.email.toLowerCase() + ',ou=users,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be(null);
2017-11-27 12:06:23 -08:00
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('fails with username for mail attribute and without accessRestriction', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('mail=' + USER_0.username + ',ou=users,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
});
});
it('fails with accessRestriction denied', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
appdb.update(APP_0.id, { accessRestriction: { users: [ USER_0.id ], groups: [] }}, function (error) {
expect(error).to.eql(null);
client.bind('cn=' + USER_1.id + ',ou=users,dc=cloudron', USER_1.password, function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
});
});
});
it('succeeds with accessRestriction allowed', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2016-04-04 16:36:42 +02:00
appdb.update(APP_0.id, { accessRestriction: { users: [ USER_1.id, USER_0.id ], groups: [] }}, function (error) {
expect(error).to.eql(null);
client.bind('cn=' + USER_0.id + ',ou=users,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be(null);
client.unbind();
done();
});
});
});
2015-08-12 15:00:38 +02:00
});
2015-08-12 15:31:54 +02:00
2015-08-12 17:38:31 +02:00
describe('search users', function () {
2015-08-12 15:31:54 +02:00
it ('fails for non existing tree', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:31:54 +02:00
var opts = {
filter: '(&(l=Seattle)(email=*@' + DOMAIN_0.domain + '))'
2015-08-12 15:31:54 +02:00
};
client.search('o=example', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
result.on('error', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2015-08-12 15:31:54 +02:00
});
result.on('end', function (result) {
done(new Error('Should not succeed. Status ' + result.status));
});
});
});
it ('succeeds with basic filter', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:31:54 +02:00
var opts = {
filter: 'objectcategory=person'
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
2016-04-04 16:36:42 +02:00
entries.sort(function (a, b) { return a.username > b.username; });
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
expect(entries[0].mail).to.equal(USER_0.email.toLowerCase());
expect(entries[1].username).to.equal(USER_1.username.toLowerCase());
expect(entries[1].mail).to.equal(USER_1.email.toLowerCase());
client.unbind();
done();
2015-08-12 15:31:54 +02:00
});
});
});
2017-10-27 01:25:07 +02:00
it ('succeeds with pagination', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-10-27 01:25:07 +02:00
var opts = {
filter: 'objectcategory=person',
paged: true
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
entries.sort(function (a, b) { return a.username > b.username; });
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
expect(entries[0].mail).to.equal(USER_0.email.toLowerCase());
expect(entries[1].username).to.equal(USER_1.username.toLowerCase());
expect(entries[1].mail).to.equal(USER_1.email.toLowerCase());
client.unbind();
done();
2017-10-27 01:25:07 +02:00
});
});
});
it ('succeeds with basic filter and email enabled', function (done) {
// user settingsdb instead of settings, to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
var opts = {
filter: 'objectcategory=person'
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
entries.sort(function (a, b) { return a.username > b.username; });
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
expect(entries[0].mailAlternateAddress).to.equal(USER_0.email.toLowerCase());
2018-01-22 11:52:58 +01:00
expect(entries[0].mail).to.equal(USER_0.email.toLowerCase());
expect(entries[1].username).to.equal(USER_1.username.toLowerCase());
expect(entries[1].mailAlternateAddress).to.equal(USER_1.email.toLowerCase());
2018-01-22 11:52:58 +01:00
expect(entries[1].mail).to.equal(USER_1.email.toLowerCase());
2017-11-27 12:06:23 -08:00
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
});
2015-08-12 15:31:54 +02:00
it ('succeeds with username wildcard filter', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:31:54 +02:00
var opts = {
filter: '&(objectcategory=person)(username=username*)'
2015-08-12 15:31:54 +02:00
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
2016-04-04 16:36:42 +02:00
entries.sort(function (a, b) { return a.username > b.username; });
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
expect(entries[1].username).to.equal(USER_1.username.toLowerCase());
client.unbind();
done();
2015-08-12 15:31:54 +02:00
});
});
});
it ('succeeds with username filter', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 15:31:54 +02:00
var opts = {
filter: '&(objectcategory=person)(username=' + USER_0.username + ')'
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(1);
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
2015-08-12 15:31:54 +02:00
expect(entries[0].memberof.length).to.equal(2);
client.unbind();
done();
2015-08-12 15:31:54 +02:00
});
});
});
it ('always lists admins', function (done) {
appdb.update(APP_0.id, { accessRestriction: { users: [], groups: [] } }, function (error) {
expect(error).to.be(null);
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
var opts = {
filter: 'objectcategory=person'
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(1);
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
expect(entries[0].memberof.length).to.equal(2);
2017-11-27 12:06:23 -08:00
client.unbind();
appdb.update(APP_0.id, { accessRestriction: null }, done);
});
});
});
});
it ('does only list users who have access', function (done) {
appdb.update(APP_0.id, { accessRestriction: { users: [], groups: [ GROUP_ID ] } }, function (error) {
expect(error).to.be(null);
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
var opts = {
filter: 'objectcategory=person'
};
client.search('ou=users,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
entries.sort(function (a, b) { return a.username > b.username; });
expect(entries[0].username).to.equal(USER_0.username.toLowerCase());
expect(entries[1].username).to.equal(USER_1.username.toLowerCase());
2017-11-27 12:06:23 -08:00
client.unbind();
appdb.update(APP_0.id, { accessRestriction: null }, done);
});
});
});
});
2015-08-12 15:31:54 +02:00
});
2015-08-12 17:38:31 +02:00
describe('search groups', function () {
it ('succeeds with basic filter', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 17:38:31 +02:00
var opts = {
filter: 'objectclass=group'
};
client.search('ou=groups,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
// ensure order for testability
entries.sort(function (a, b) { return a.username < b.username; });
2015-08-12 17:38:31 +02:00
expect(entries[0].cn).to.equal('users');
expect(entries[0].memberuid.length).to.equal(3);
2016-04-04 16:36:42 +02:00
expect(entries[0].memberuid[0]).to.equal(USER_0.id);
expect(entries[0].memberuid[1]).to.equal(USER_1.id);
expect(entries[0].memberuid[2]).to.equal(USER_2.id);
2015-08-12 17:38:31 +02:00
expect(entries[1].cn).to.equal('admins');
// if only one entry, the array becomes a string :-/
2016-04-04 16:36:42 +02:00
expect(entries[1].memberuid).to.equal(USER_0.id);
client.unbind();
done();
2015-08-12 17:38:31 +02:00
});
});
});
it ('succeeds with cn wildcard filter', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 17:38:31 +02:00
var opts = {
filter: '&(objectclass=group)(cn=*)'
};
client.search('ou=groups,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
expect(entries[0].cn).to.equal('users');
expect(entries[0].memberuid.length).to.equal(3);
2016-04-04 16:36:42 +02:00
expect(entries[0].memberuid[0]).to.equal(USER_0.id);
expect(entries[0].memberuid[1]).to.equal(USER_1.id);
expect(entries[0].memberuid[2]).to.equal(USER_2.id);
2015-08-12 17:38:31 +02:00
expect(entries[1].cn).to.equal('admins');
// if only one entry, the array becomes a string :-/
2016-04-04 16:36:42 +02:00
expect(entries[1].memberuid).to.equal(USER_0.id);
client.unbind();
done();
2015-08-12 17:38:31 +02:00
});
});
});
it('succeeds with memberuid filter', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2015-08-12 17:38:31 +02:00
var opts = {
2016-04-04 16:36:42 +02:00
filter: '&(objectclass=group)(memberuid=' + USER_1.id + ')'
2015-08-12 17:38:31 +02:00
};
client.search('ou=groups,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(1);
expect(entries[0].cn).to.equal('users');
expect(entries[0].memberuid.length).to.equal(3);
client.unbind();
done();
2015-08-12 17:38:31 +02:00
});
});
});
it ('does only list users who have access', function (done) {
appdb.update(APP_0.id, { accessRestriction: { users: [], groups: [ GROUP_ID ] } }, function (error) {
expect(error).to.be(null);
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
var opts = {
filter: '&(objectclass=group)(cn=*)'
};
client.search('ou=groups,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
expect(entries[0].cn).to.equal('users');
expect(entries[0].memberuid.length).to.equal(2);
expect(entries[0].memberuid[0]).to.equal(USER_0.id);
expect(entries[0].memberuid[1]).to.equal(USER_1.id);
expect(entries[1].cn).to.equal('admins');
// if only one entry, the array becomes a string :-/
expect(entries[1].memberuid).to.equal(USER_0.id);
2017-11-27 12:06:23 -08:00
client.unbind();
appdb.update(APP_0.id, { accessRestriction: null }, done);
});
});
});
});
2017-10-27 01:25:07 +02:00
it ('succeeds with pagination', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-10-27 01:25:07 +02:00
var opts = {
filter: 'objectclass=group',
paged: true
};
client.search('ou=groups,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
// ensure order for testability
entries.sort(function (a, b) { return a.username < b.username; });
expect(entries[0].cn).to.equal('users');
expect(entries[0].memberuid.length).to.equal(3);
expect(entries[0].memberuid[0]).to.equal(USER_0.id);
expect(entries[0].memberuid[1]).to.equal(USER_1.id);
expect(entries[0].memberuid[2]).to.equal(USER_2.id);
expect(entries[1].cn).to.equal('admins');
// if only one entry, the array becomes a string :-/
expect(entries[1].memberuid).to.equal(USER_0.id);
client.unbind();
done();
2017-10-27 01:25:07 +02:00
});
});
});
2015-08-12 17:38:31 +02:00
});
2016-09-26 10:18:58 -07:00
// ldapsearch -LLL -E pr=10/noprompt -x -h localhost -p 3002 -b cn=userName0@example.com,ou=mailboxes,dc=cloudron objectclass=mailbox
2016-09-26 10:18:58 -07:00
function ldapSearch(dn, filter, callback) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2016-09-26 10:18:58 -07:00
var opts = {
2017-10-27 01:25:07 +02:00
filter: filter,
paged: true
2016-09-26 10:18:58 -07:00
};
2017-11-27 12:06:23 -08:00
function done(error, entries) {
client.unbind();
callback(error, entries);
2017-11-27 12:06:23 -08:00
}
2016-09-26 10:18:58 -07:00
client.search(dn, opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
2017-11-27 12:06:23 -08:00
result.on('error', done);
2016-09-26 10:18:58 -07:00
result.on('end', function (result) {
expect(result.status).to.equal(0);
2017-11-27 12:06:23 -08:00
done(null, entries);
2016-09-26 10:18:58 -07:00
});
});
}
describe('search mailbox', function () {
it('get specific mailbox by email', function (done) {
ldapSearch('cn=' + USER_0.username + '@example.com,ou=mailboxes,dc=cloudron', 'objectclass=mailbox', function (error, entries) {
2016-09-26 10:18:58 -07:00
if (error) return done(error);
expect(entries.length).to.equal(1);
expect(entries[0].cn).to.equal(USER_0.username.toLowerCase() + '@example.com');
2016-09-26 10:18:58 -07:00
done();
});
});
it('cannot get mailbox with just name', function (done) {
ldapSearch('cn=' + USER_0.username + ',ou=mailboxes,dc=cloudron', 'objectclass=mailbox', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
2016-09-26 21:03:07 -07:00
done();
});
});
2016-09-28 10:26:41 -07:00
it('cannot get alias as a mailbox', function (done) {
ldapSearch('cn=' + USER_0_ALIAS + '@example.com,ou=mailboxes,dc=cloudron', 'objectclass=mailbox', function (error) {
2016-09-28 10:26:41 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
});
2016-09-26 10:18:58 -07:00
it('non-existent mailbox', function (done) {
ldapSearch('cn=random@example.com,ou=mailboxes,dc=cloudron', 'objectclass=mailbox', function (error) {
2016-09-26 14:38:23 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
});
it('cannot get inactive mailbox', function (done) {
mailboxdb.updateMailbox(USER_0.username.toLowerCase(), DOMAIN_0.domain, { ownerId: USER_0.id, ownerType: mail.OWNERTYPE_USER, active: false }, function (error) {
if (error) return done(error);
ldapSearch('cn=' + USER_0.username + '@example.com,ou=mailboxes,dc=cloudron', 'objectclass=mailbox', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
mailboxdb.updateMailbox(USER_0.username.toLowerCase(), DOMAIN_0.domain, { ownerId: USER_0.id, ownerType: mail.OWNERTYPE_USER, active: true }, done);
});
});
});
2016-09-26 14:38:23 -07:00
});
describe('search aliases', function () {
2016-09-27 15:56:02 -07:00
it('get specific alias', function (done) {
ldapSearch('cn=' + USER_0_ALIAS + '@example.com,ou=mailaliases,dc=cloudron', 'objectclass=nismailalias', function (error, entries) {
2016-09-27 15:56:02 -07:00
if (error) return done(error);
expect(entries.length).to.equal(1);
expect(entries[0].cn).to.equal('asterix@example.com');
expect(entries[0].rfc822MailMember).to.equal(USER_0.username.toLowerCase() + '@example.com');
2016-09-27 15:56:02 -07:00
done();
});
});
2016-09-28 10:26:41 -07:00
it('cannot get mailbox as alias', function (done) {
ldapSearch('cn=' + USER_0.username + '@example.com,ou=mailaliases,dc=cloudron', 'objectclass=nismailalias', function (error) {
2016-09-28 10:26:41 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
});
2016-09-27 15:56:02 -07:00
it('non-existent alias', function (done) {
ldapSearch('cn=random@example.com,ou=mailaliases,dc=cloudron', 'objectclass=mailbox', function (error) {
2016-09-27 15:56:02 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
2016-09-26 14:38:23 -07:00
});
2016-09-27 15:56:02 -07:00
});
2016-09-26 14:38:23 -07:00
2016-09-27 15:56:02 -07:00
describe('search groups', function () {
2016-09-26 14:38:23 -07:00
it('get specific alias', function (done) {
ldapSearch('cn=' + USER_0_ALIAS + '@example.com,ou=mailaliases,dc=cloudron', 'objectclass=nismailalias', function (error, entries) {
2016-09-26 14:38:23 -07:00
if (error) return done(error);
expect(entries.length).to.equal(1);
expect(entries[0].cn).to.equal('asterix@example.com');
expect(entries[0].rfc822MailMember).to.equal(USER_0.username.toLowerCase() + '@example.com');
2016-09-26 14:38:23 -07:00
done();
});
});
it('non-existent alias', function (done) {
ldapSearch('cn=random@example.com,ou=mailaliases,dc=cloudron', 'objectclass=mailbox', function (error) {
2016-09-26 10:18:58 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
});
});
2016-09-27 16:27:22 -07:00
describe('search mailing list', function () {
2018-01-29 13:35:22 +01:00
before(function (done) {
mailboxdb.addList('devs', DOMAIN_0.domain, { members: [ USER_0.username.toLowerCase() + '@' + DOMAIN_0.domain , USER_1.username.toLowerCase() + '@external.com' ], membersOnly: false, active: true }, done);
2018-01-29 13:35:22 +01:00
});
2016-09-27 16:27:22 -07:00
it('get specific list', function (done) {
ldapSearch('cn=devs@example.com,ou=mailinglists,dc=cloudron', 'objectclass=mailGroup', function (error, entries) {
2016-09-27 16:27:22 -07:00
if (error) return done(error);
expect(entries.length).to.equal(1);
expect(entries[0].cn).to.equal('devs@example.com');
expect(entries[0].mgrpRFC822MailMember).to.eql([ USER_0.username.toLowerCase() + '@example.com', USER_1.username.toLowerCase() + '@external.com' ]);
2016-09-27 16:27:22 -07:00
done();
});
});
it('non-existent list', function (done) {
ldapSearch('cn=random@example.com,ou=mailinglists,dc=cloudron', 'objectclass=mailGroup', function (error) {
2016-09-27 16:27:22 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
});
it('inactive list', function (done) {
mailboxdb.updateList('devs', DOMAIN_0.domain, { members: [ USER_0.username.toLowerCase() + '@' + DOMAIN_0.domain , USER_1.username.toLowerCase() + '@external.com' ], membersOnly: false, active: false }, function (error) {
if (error) return done(error);
ldapSearch('cn=devs@example.com,ou=mailinglists,dc=cloudron', 'objectclass=mailGroup', function (error, entries) {
expect(error).to.be.a(ldap.NoSuchObjectError);
done();
});
});
});
2016-09-27 16:27:22 -07:00
});
describe('user mailbox bind', function () {
it('email disabled - cannot find domain email', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,domain=example.com,ou=mailboxes,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
});
});
it('email enabled - does not allow with invalid password', function (done) {
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,domain=example.com,ou=mailboxes,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.InvalidCredentialsError);
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('email enabled - allows with valid password', function (done) {
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,domain=example.com,ou=mailboxes,dc=cloudron', USER_0.password, function (error) {
expect(error).not.to.be.ok();
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('email enabled - cannot auth with alias', function (done) {
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0_ALIAS + '@example.com,domain=example.com,ou=mailboxes,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
});
2017-03-26 20:42:46 -07:00
describe('user sendmail bind', function () {
it('email disabled - cannot find domain email', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2016-09-26 10:18:58 -07:00
client.bind('cn=' + USER_0.username + '@example.com,ou=sendmail,dc=cloudron', USER_0.password + 'nope', function (error) {
rework how app mailboxes are allocated Our current setup had a mailbox allocated for an app during app install (into the mailboxes table). This has many issues: * When set to a custom mailbox location, there was no way to access this mailbox even via IMAP. Even when using app credentials, we cannot use IMAP since the ldap logic was testing on the addon type (most of our apps only use sendmail addon and thus cannot recvmail). * The mailboxes table was being used to add hidden 'app' type entries. This made it very hard for the user to understand why a mailbox conflicts. For example, if you set an app to use custom mailbox 'blog', this is hidden from all views. The solution is to let an app send email as whatever mailbox name is allocated to it (which we now track in the apps table. the default is in the db already so that REST response contains it). When not using Cloudron email, it will just send mail as that mailbox and the auth checks the "app password" in the addons table. Any replies to that mailbox will end up in the domain's mail server (not our problem). When using cloudron email, the app can send mail like above. Any responses will not end anywhere and bounce since there is no 'mailbox'. This is the expected behavior. If user wants to access this mailbox name, he can create a concrete mailbox and set himself as owner OR set this as an alias. For apps using the recvmail addon, the workflow is to actually create a mailbox at some point. Currently, we have no UI for this 'flow'. It's fine because we have only meemo using it. Intuitive much!
2018-12-06 21:08:19 -08:00
expect(error).to.be.a(ldap.InvalidCredentialsError);
client.unbind();
done();
2016-09-26 10:18:58 -07:00
});
});
it('email disabled - cannot find reset email', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2016-09-26 10:18:58 -07:00
client.bind('cn=' + USER_0.email + ',ou=sendmail,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2016-09-26 10:18:58 -07:00
});
});
it('email enabled - allows with valid email', function (done) {
2018-01-21 00:27:13 -08:00
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2018-01-29 13:35:22 +01:00
client.bind('cn=' + USER_0.username.toLocaleLowerCase() + '@' + DOMAIN_0.domain + ',ou=sendmail,dc=cloudron', USER_0.password, function (error) {
expect(error).not.to.be.ok();
2017-11-27 12:06:23 -08:00
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('email enabled - does not allow with invalid password', function (done) {
2018-01-21 00:27:13 -08:00
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,ou=sendmail,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.InvalidCredentialsError);
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('does not allow for inactive mailbox', function (done) {
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
if (error) return done(error);
mailboxdb.updateMailbox(USER_0.username.toLowerCase(), DOMAIN_0.domain, { ownerId: USER_0.id, ownerType: mail.OWNERTYPE_USER, active: false }, function (error) {
if(error) return done(error);
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username.toLocaleLowerCase() + '@' + DOMAIN_0.domain + ',ou=sendmail,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
});
2016-09-26 10:18:58 -07:00
});
2017-03-26 20:42:46 -07:00
describe('app sendmail bind', function () {
// these tests should work even when email is disabled
before(function (done) {
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
2017-03-26 20:42:46 -07:00
it('does not allow with invalid app', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-03-26 20:42:46 -07:00
client.bind('cn=hacker.app@example.com,ou=sendmail,dc=cloudron', 'nope', function (error) {
2017-03-26 20:42:46 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2017-03-26 20:42:46 -07:00
});
});
it('does not allow with invalid password', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-03-26 20:42:46 -07:00
client.bind('cn=' + APP_0.location + '.app@example.com,ou=sendmail,dc=cloudron', 'nope', function (error) {
rework how app mailboxes are allocated Our current setup had a mailbox allocated for an app during app install (into the mailboxes table). This has many issues: * When set to a custom mailbox location, there was no way to access this mailbox even via IMAP. Even when using app credentials, we cannot use IMAP since the ldap logic was testing on the addon type (most of our apps only use sendmail addon and thus cannot recvmail). * The mailboxes table was being used to add hidden 'app' type entries. This made it very hard for the user to understand why a mailbox conflicts. For example, if you set an app to use custom mailbox 'blog', this is hidden from all views. The solution is to let an app send email as whatever mailbox name is allocated to it (which we now track in the apps table. the default is in the db already so that REST response contains it). When not using Cloudron email, it will just send mail as that mailbox and the auth checks the "app password" in the addons table. Any replies to that mailbox will end up in the domain's mail server (not our problem). When using cloudron email, the app can send mail like above. Any responses will not end anywhere and bounce since there is no 'mailbox'. This is the expected behavior. If user wants to access this mailbox name, he can create a concrete mailbox and set himself as owner OR set this as an alias. For apps using the recvmail addon, the workflow is to actually create a mailbox at some point. Currently, we have no UI for this 'flow'. It's fine because we have only meemo using it. Intuitive much!
2018-12-06 21:08:19 -08:00
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2017-03-26 20:42:46 -07:00
});
});
it('allows with valid password', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-03-26 20:42:46 -07:00
client.bind('cn=' + APP_0.location + '.app@example.com,ou=sendmail,dc=cloudron', 'sendmailpassword', function (error) {
2017-11-27 12:06:23 -08:00
client.unbind();
2017-03-26 20:42:46 -07:00
done(error);
});
});
});
describe('user recvmail bind', function () {
2018-01-29 13:35:22 +01:00
before(function (done) {
async.series([
maildb.update.bind(null, DOMAIN_0.domain, { enabled: false }),
mailboxdb.updateMailbox.bind(null, USER_0.username.toLowerCase(), DOMAIN_0.domain, { ownerId: USER_0.id, ownerType: mail.OWNERTYPE_USER, active: true })
], done);
2018-01-29 13:35:22 +01:00
});
it('email disabled - cannot find domain email', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,ou=recvmail,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
});
});
it('email disabled - cannot find reset email', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.email + ',ou=recvmail,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
});
});
it('email enabled - allows with valid email', function (done) {
2018-01-21 00:27:13 -08:00
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,ou=recvmail,dc=cloudron', USER_0.password, function (error) {
expect(error).not.to.be.ok();
2017-11-27 12:06:23 -08:00
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('email enabled - does not allow with invalid password', function (done) {
2018-01-21 00:27:13 -08:00
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,ou=recvmail,dc=cloudron', USER_0.password + 'nope', function (error) {
expect(error).to.be.a(ldap.InvalidCredentialsError);
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
it('does not allow for inactive mailbox', function (done) {
// use maildb to not trigger further events
maildb.update(DOMAIN_0.domain, { enabled: true }, function (error) {
expect(error).not.to.be.ok();
mailboxdb.updateMailbox(USER_0.username.toLowerCase(), DOMAIN_0.domain, { ownerId: USER_0.id, ownerType: mail.OWNERTYPE_USER, active: false }, function (error) {
if (error) return done(error);
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
client.bind('cn=' + USER_0.username + '@example.com,ou=recvmail,dc=cloudron', USER_0.password, function (error) {
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
maildb.update(DOMAIN_0.domain, { enabled: false }, done);
});
});
});
});
});
2017-03-26 20:42:46 -07:00
describe('app recvmail bind', function () {
2018-01-29 13:35:22 +01:00
before(function (done) {
maildb.update(DOMAIN_0.domain, { enabled: true }, done);
});
2017-03-26 20:42:46 -07:00
it('does not allow with invalid app', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-03-26 20:42:46 -07:00
client.bind('cn=hacker.app@example.com,ou=recvmail,dc=cloudron', 'nope', function (error) {
2017-03-26 20:42:46 -07:00
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2017-03-26 20:42:46 -07:00
});
});
it('does not allow with invalid password', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-03-26 20:42:46 -07:00
client.bind('cn=' + APP_0.location + '.app@example.com,ou=recvmail,dc=cloudron', 'nope', function (error) {
rework how app mailboxes are allocated Our current setup had a mailbox allocated for an app during app install (into the mailboxes table). This has many issues: * When set to a custom mailbox location, there was no way to access this mailbox even via IMAP. Even when using app credentials, we cannot use IMAP since the ldap logic was testing on the addon type (most of our apps only use sendmail addon and thus cannot recvmail). * The mailboxes table was being used to add hidden 'app' type entries. This made it very hard for the user to understand why a mailbox conflicts. For example, if you set an app to use custom mailbox 'blog', this is hidden from all views. The solution is to let an app send email as whatever mailbox name is allocated to it (which we now track in the apps table. the default is in the db already so that REST response contains it). When not using Cloudron email, it will just send mail as that mailbox and the auth checks the "app password" in the addons table. Any replies to that mailbox will end up in the domain's mail server (not our problem). When using cloudron email, the app can send mail like above. Any responses will not end anywhere and bounce since there is no 'mailbox'. This is the expected behavior. If user wants to access this mailbox name, he can create a concrete mailbox and set himself as owner OR set this as an alias. For apps using the recvmail addon, the workflow is to actually create a mailbox at some point. Currently, we have no UI for this 'flow'. It's fine because we have only meemo using it. Intuitive much!
2018-12-06 21:08:19 -08:00
expect(error).to.be.a(ldap.NoSuchObjectError);
client.unbind();
done();
2017-03-26 20:42:46 -07:00
});
});
it('allows with valid password', function (done) {
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + constants.LDAP_PORT });
2017-03-26 20:42:46 -07:00
client.bind('cn=' + APP_0.location + '.app@example.com,ou=recvmail,dc=cloudron', 'recvmailpassword', function (error) {
2017-11-27 12:06:23 -08:00
client.unbind();
2017-03-26 20:42:46 -07:00
done(error);
});
});
});
2015-08-12 15:00:38 +02:00
});