Remove code to push aliases
The mail-addon will query via LDAP
This commit is contained in:
+15
-4
@@ -23,6 +23,7 @@ var assert = require('assert'),
|
||||
constants = require('./constants.js'),
|
||||
DatabaseError = require('./databaseerror.js'),
|
||||
groupdb = require('./groupdb.js'),
|
||||
mailboxdb = require('./mailboxdb.js'),
|
||||
util = require('util');
|
||||
|
||||
// http://dustinsenos.com/articles/customErrorsInNode
|
||||
@@ -77,11 +78,16 @@ function create(name, callback) {
|
||||
var error = validateGroupname(name);
|
||||
if (error) return callback(error);
|
||||
|
||||
groupdb.add(name /* id */, name, function (error) {
|
||||
mailboxdb.add(name, name /* owner */, mailboxdb.TYPE_GROUP, function (error) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new GroupError(GroupError.ALREADY_EXISTS));
|
||||
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
|
||||
|
||||
callback(null, { id: name, name: name });
|
||||
groupdb.add(name /* id */, name, function (error) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new GroupError(GroupError.ALREADY_EXISTS));
|
||||
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
|
||||
|
||||
callback(null, { id: name, name: name });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -92,11 +98,16 @@ function remove(id, callback) {
|
||||
// never allow admin group to be deleted
|
||||
if (id === constants.ADMIN_GROUP_ID) return callback(new GroupError(GroupError.NOT_ALLOWED));
|
||||
|
||||
groupdb.del(id, function (error) {
|
||||
mailboxdb.delByOwnerId(id, function (error) {
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
|
||||
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
|
||||
|
||||
callback(null);
|
||||
groupdb.del(id, function (error) {
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
|
||||
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
|
||||
|
||||
callback(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+27
-5
@@ -7,8 +7,13 @@ exports = module.exports = {
|
||||
getAll: getAll,
|
||||
getAliases: getAliases,
|
||||
setAliases: setAliases,
|
||||
delByOwnerId: delByOwnerId,
|
||||
|
||||
_clear: clear
|
||||
_clear: clear,
|
||||
|
||||
TYPE_USER: 'user',
|
||||
TYPE_APP: 'app',
|
||||
TYPE_GROUP: 'group'
|
||||
};
|
||||
|
||||
var assert = require('assert'),
|
||||
@@ -18,11 +23,13 @@ var assert = require('assert'),
|
||||
|
||||
var MAILBOX_FIELDS = [ 'name', 'ownerId', 'ownerType', 'aliasTarget', 'creationTime' ].join(',');
|
||||
|
||||
function add(name, callback) {
|
||||
function add(name, ownerId, ownerType, callback) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
assert.strictEqual(typeof ownerId, 'string');
|
||||
assert.strictEqual(typeof ownerType, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
database.query('INSERT INTO mailboxes (name) VALUES (?)', [ name ], function (error) {
|
||||
database.query('INSERT INTO mailboxes (name, ownerId, ownerType) VALUES (?, ?, ?)', [ name, ownerId, ownerType ], function (error) {
|
||||
if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS));
|
||||
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
||||
|
||||
@@ -52,6 +59,19 @@ function del(name, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function delByOwnerId(id, callback) {
|
||||
assert.strictEqual(typeof id, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
// deletes aliases as well
|
||||
database.query('DELETE FROM mailboxes WHERE ownerId=?', [ id ], function (error, result) {
|
||||
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
||||
if (result.affectedRows === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND));
|
||||
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
function postProcess(result) {
|
||||
result.aliases = result.aliases ? result.aliases.split(',') : [ ];
|
||||
}
|
||||
@@ -94,16 +114,18 @@ function getAll(callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function setAliases(name, aliases, callback) {
|
||||
function setAliases(name, aliases, ownerId, ownerType, callback) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
assert(util.isArray(aliases));
|
||||
assert.strictEqual(typeof ownerId, 'string');
|
||||
assert.strictEqual(typeof ownerType, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
// also cleanup the groupMembers table
|
||||
var queries = [];
|
||||
queries.push({ query: 'DELETE FROM mailboxes WHERE aliasTarget = ?', args: [ name ] });
|
||||
aliases.forEach(function (alias) {
|
||||
queries.push({ query: 'INSERT INTO mailboxes (name, aliasTarget) VALUES (?, ?)', args: [ alias, name ] });
|
||||
queries.push({ query: 'INSERT INTO mailboxes (name, aliasTarget, ownerId, ownerType) VALUES (?, ?, ?, ?)', args: [ alias, name, ownerId, ownerType ] });
|
||||
});
|
||||
|
||||
database.transaction(queries, function (error) {
|
||||
|
||||
+10
-56
@@ -8,16 +8,12 @@ exports = module.exports = {
|
||||
setAliases: setAliases,
|
||||
getAliases: getAliases,
|
||||
|
||||
setupAliases: setupAliases,
|
||||
|
||||
MailboxError: MailboxError
|
||||
};
|
||||
|
||||
var assert = require('assert'),
|
||||
async = require('async'),
|
||||
DatabaseError = require('./databaseerror.js'),
|
||||
debug = require('debug')('box:mailboxes'),
|
||||
docker = require('./docker.js'),
|
||||
mailboxdb = require('./mailboxdb.js'),
|
||||
util = require('util');
|
||||
|
||||
@@ -85,35 +81,17 @@ function add(name, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function pushAlias(name, aliases, callback) {
|
||||
if (process.env.BOX_ENV === 'test') return callback();
|
||||
|
||||
var cmd = [ '/addons/mail/service.sh', 'set-alias', name ].concat(aliases);
|
||||
|
||||
debug('pushing alias for %s : %j', name, aliases);
|
||||
|
||||
docker.execContainer('mail', cmd, { }, function (error) {
|
||||
if (error) return callback(new MailboxError(MailboxError.EXTERNAL_ERROR, error));
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function del(name, callback) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
pushAlias(name, [ ], function (error) {
|
||||
if (error) return callback(error);
|
||||
mailboxdb.del(name, function (error) {
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailboxError(MailboxError.NOT_FOUND));
|
||||
if (error) return callback(new MailboxError(MailboxError.INTERNAL_ERROR, error));
|
||||
|
||||
mailboxdb.del(name, function (error) {
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailboxError(MailboxError.NOT_FOUND));
|
||||
if (error) return callback(new MailboxError(MailboxError.INTERNAL_ERROR, error));
|
||||
debug('deleted mailbox %s', name);
|
||||
|
||||
debug('deleted mailbox %s', name);
|
||||
|
||||
callback();
|
||||
});
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -151,17 +129,13 @@ function setAliases(name, aliases, callback) {
|
||||
if (error) return callback(error);
|
||||
}
|
||||
|
||||
pushAlias(name, aliases, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
mailboxdb.setAliases(name, aliases, function (error) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailboxError(MailboxError.ALREADY_EXISTS, error.message));
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailboxError(MailboxError.NOT_FOUND));
|
||||
if (error) return callback(new MailboxError(MailboxError.INTERNAL_ERROR, error));
|
||||
mailboxdb.setAliases(name, aliases, function (error) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailboxError(MailboxError.ALREADY_EXISTS, error.message));
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailboxError(MailboxError.NOT_FOUND));
|
||||
if (error) return callback(new MailboxError(MailboxError.INTERNAL_ERROR, error));
|
||||
|
||||
|
||||
callback(null);
|
||||
});
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -176,23 +150,3 @@ function getAliases(name, callback) {
|
||||
callback(null, aliases);
|
||||
});
|
||||
}
|
||||
|
||||
// push aliases to the mail container on startup
|
||||
function setupAliases(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
getAll(function (error, mailboxes) {
|
||||
if (error) return callback(error);
|
||||
|
||||
async.each(mailboxes, function (mailbox, iteratorDone) {
|
||||
getAliases(mailbox.name, function (error, aliases) {
|
||||
if (error) return iteratorDone(error);
|
||||
|
||||
if (aliases.length === 0) return iteratorDone();
|
||||
|
||||
pushAlias(mailbox.name, aliases, iteratorDone);
|
||||
});
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+10
-15
@@ -19,7 +19,6 @@ var apps = require('./apps.js'),
|
||||
fs = require('fs'),
|
||||
hat = require('hat'),
|
||||
infra = require('./infra_version.js'),
|
||||
mailboxes = require('./mailboxes.js'),
|
||||
paths = require('./paths.js'),
|
||||
safe = require('safetydance'),
|
||||
settings = require('./settings.js'),
|
||||
@@ -262,22 +261,18 @@ function startMail(callback) {
|
||||
|
||||
shell.execSync('startMail', cmd);
|
||||
|
||||
mailboxes.setupAliases(function (error) {
|
||||
if (error) return callback(error);
|
||||
if (!mailConfig.enabled || process.env.BOX_ENV === 'test') return callback();
|
||||
|
||||
if (!mailConfig.enabled || process.env.BOX_ENV === 'test') return callback();
|
||||
// Add MX and DMARC record. Note that DMARC policy depends on DKIM signing and thus works
|
||||
// only if we use our internal mail server.
|
||||
var records = [
|
||||
{ subdomain: '_dmarc', type: 'TXT', values: [ '"v=DMARC1; p=reject; pct=100"' ] },
|
||||
{ subdomain: '', type: 'MX', values: [ '10 ' + config.mailFqdn() + '.' ] }
|
||||
];
|
||||
|
||||
// Add MX and DMARC record. Note that DMARC policy depends on DKIM signing and thus works
|
||||
// only if we use our internal mail server.
|
||||
var records = [
|
||||
{ subdomain: '_dmarc', type: 'TXT', values: [ '"v=DMARC1; p=reject; pct=100"' ] },
|
||||
{ subdomain: '', type: 'MX', values: [ '10 ' + config.mailFqdn() + '.' ] }
|
||||
];
|
||||
|
||||
async.mapSeries(records, function (record, iteratorCallback) {
|
||||
subdomains.upsert(record.subdomain, record.type, record.values, iteratorCallback);
|
||||
}, callback);
|
||||
});
|
||||
async.mapSeries(records, function (record, iteratorCallback) {
|
||||
subdomains.upsert(record.subdomain, record.type, record.values, iteratorCallback);
|
||||
}, callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1181,14 +1181,14 @@ describe('database', function () {
|
||||
|
||||
describe('mailboxes', function () {
|
||||
it('add succeeds', function (done) {
|
||||
mailboxdb.add('support', function (error, mailbox) {
|
||||
mailboxdb.add('support', 'osticket', mailboxdb.TYPE_APP, function (error, mailbox) {
|
||||
expect(error).to.be(null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('cannot add dup entry', function (done) {
|
||||
mailboxdb.add('support', function (error, mailbox) {
|
||||
mailboxdb.add('support', 'support', mailboxdb.TYPE_USER, function (error, mailbox) {
|
||||
expect(error.reason).to.be(DatabaseError.ALREADY_EXISTS);
|
||||
done();
|
||||
});
|
||||
@@ -1216,27 +1216,27 @@ describe('database', function () {
|
||||
});
|
||||
|
||||
it('can set alias', function (done) {
|
||||
mailboxdb.setAliases('support2', [ 'support2', 'help' ], function (error) {
|
||||
mailboxdb.setAliases('support', [ 'support2', 'help' ], 'support', 'user', function (error) {
|
||||
expect(error).to.be(null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can get alias', function (done) {
|
||||
mailboxdb.getAliases('support2', function (error, results) {
|
||||
mailboxdb.getAliases('support', function (error, results) {
|
||||
expect(error).to.be(null);
|
||||
expect(results.length).to.be(2);
|
||||
expect(results[0]).to.be('help');
|
||||
expect(results[1]).to.be('support2')
|
||||
expect(results[1]).to.be('support2');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('unset aliases', function (done) {
|
||||
mailboxdb.setAliases('support2', [ ], function (error) {
|
||||
mailboxdb.setAliases('support', [ ], 'support', 'user', function (error) {
|
||||
expect(error).to.be(null);
|
||||
|
||||
mailboxdb.getAliases('support2', function (error, results) {
|
||||
mailboxdb.getAliases('support', function (error, results) {
|
||||
expect(error).to.be(null);
|
||||
expect(results.length).to.be(0);
|
||||
done();
|
||||
@@ -1252,4 +1252,3 @@ describe('database', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+36
-15
@@ -35,7 +35,7 @@ var assert = require('assert'),
|
||||
GroupError = groups.GroupError,
|
||||
hat = require('hat'),
|
||||
mailer = require('./mailer.js'),
|
||||
mailboxes = require('./mailboxes.js'),
|
||||
mailboxdb = require('./mailboxdb.js'),
|
||||
safe = require('safetydance'),
|
||||
tokendb = require('./tokendb.js'),
|
||||
userdb = require('./userdb.js'),
|
||||
@@ -51,6 +51,12 @@ var CRYPTO_KEY_LENGTH = 512; // bits
|
||||
|
||||
var NOOP_CALLBACK = function (error) { if (error) debug(error); };
|
||||
|
||||
function asyncIf(cond, func, next) {
|
||||
if (!cond) return next();
|
||||
|
||||
func(next);
|
||||
}
|
||||
|
||||
// http://dustinsenos.com/articles/customErrorsInNode
|
||||
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
|
||||
function UserError(reason, errorOrMessage) {
|
||||
@@ -176,17 +182,23 @@ function createUser(username, password, email, displayName, auditSource, options
|
||||
showTutorial: true
|
||||
};
|
||||
|
||||
userdb.add(user.id, user, function (error) {
|
||||
asyncIf(!!username, mailboxdb.add.bind(null, username, user.id /* owner */, mailboxdb.TYPE_USER), function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new UserError(UserError.ALREADY_EXISTS, error.message));
|
||||
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
|
||||
|
||||
eventlog.add(eventlog.ACTION_USER_ADD, auditSource, { userId: user.id, email: user.email });
|
||||
if (username) mailboxes.add(username, NOOP_CALLBACK);
|
||||
userdb.add(user.id, user, function (error) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new UserError(UserError.ALREADY_EXISTS, error.message));
|
||||
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
|
||||
|
||||
callback(null, user);
|
||||
eventlog.add(eventlog.ACTION_USER_ADD, auditSource, { userId: user.id, email: user.email });
|
||||
|
||||
if (!owner) mailer.userAdded(user, sendInvite);
|
||||
if (sendInvite) mailer.sendInvite(user, invitor);
|
||||
callback(null, user);
|
||||
|
||||
if (!owner) mailer.userAdded(user, sendInvite);
|
||||
if (sendInvite) mailer.sendInvite(user, invitor);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -272,9 +284,8 @@ function removeUser(userId, auditSource, callback) {
|
||||
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
|
||||
|
||||
eventlog.add(eventlog.ACTION_USER_REMOVE, auditSource, { userId: userId });
|
||||
if (user.username) mailboxes.del(user.username, NOOP_CALLBACK);
|
||||
|
||||
callback(null);
|
||||
if (user.username) mailboxdb.delByOwnerId(user.id, callback); else callback();
|
||||
|
||||
mailer.userRemoved(user);
|
||||
});
|
||||
@@ -361,16 +372,26 @@ function updateUser(userId, data, auditSource, callback) {
|
||||
if (error) return callback(error);
|
||||
}
|
||||
|
||||
userdb.update(userId, data, function (error) {
|
||||
function doUpdate(error, callback) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new UserError(UserError.ALREADY_EXISTS, error.message));
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new UserError(UserError.NOT_FOUND, error));
|
||||
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
|
||||
|
||||
eventlog.add(eventlog.ACTION_USER_UPDATE, auditSource, { userId: userId });
|
||||
if (data.username) mailboxes.add(data.username, NOOP_CALLBACK); // TODO: do this only when username actually changes
|
||||
userdb.update(userId, data, function (error) {
|
||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new UserError(UserError.ALREADY_EXISTS, error.message));
|
||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new UserError(UserError.NOT_FOUND, error));
|
||||
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
|
||||
|
||||
callback(null);
|
||||
});
|
||||
eventlog.add(eventlog.ACTION_USER_UPDATE, auditSource, { userId: userId });
|
||||
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
if (data.username) {
|
||||
mailboxdb.add(data.username, userId /* owner */, mailboxdb.TYPE_USER, doUpdate); // TODO: do this only when username actually changes
|
||||
} else {
|
||||
doUpdate(null, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function setGroups(userId, groupIds, callback) {
|
||||
|
||||
Reference in New Issue
Block a user