Files
cloudron-box/src/groups.js

220 lines
7.5 KiB
JavaScript
Raw Normal View History

2016-02-07 20:25:08 -08:00
'use strict';
exports = module.exports = {
GroupError: GroupError,
create: create,
remove: remove,
2016-02-08 09:41:21 -08:00
get: get,
2016-02-09 15:26:34 -08:00
getWithMembers: getWithMembers,
2016-02-09 13:33:30 -08:00
getAll: getAll,
getAllWithMembers: getAllWithMembers,
2016-02-08 09:41:21 -08:00
getMembers: getMembers,
addMember: addMember,
2016-02-08 10:53:01 -08:00
removeMember: removeMember,
2016-02-08 09:26:52 -08:00
isMember: isMember,
2016-02-08 20:38:50 -08:00
getGroups: getGroups,
2016-02-09 15:47:02 -08:00
setGroups: setGroups,
2016-02-08 20:38:50 -08:00
ADMIN_GROUP_ID: 'admin' // see db migration code and groupdb._clear
2016-02-07 20:25:08 -08:00
};
var assert = require('assert'),
DatabaseError = require('./databaseerror.js'),
2016-02-07 20:34:05 -08:00
groupdb = require('./groupdb.js'),
2016-02-08 09:41:21 -08:00
util = require('util');
2016-02-07 20:25:08 -08:00
// http://dustinsenos.com/articles/customErrorsInNode
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
function GroupError(reason, errorOrMessage) {
assert.strictEqual(typeof reason, 'string');
assert(errorOrMessage instanceof Error || typeof errorOrMessage === 'string' || typeof errorOrMessage === 'undefined');
Error.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.reason = reason;
if (typeof errorOrMessage === 'undefined') {
this.message = reason;
} else if (typeof errorOrMessage === 'string') {
this.message = errorOrMessage;
} else {
this.message = 'Internal error';
this.nestedError = errorOrMessage;
}
}
util.inherits(GroupError, Error);
GroupError.INTERNAL_ERROR = 'Internal Error';
GroupError.ALREADY_EXISTS = 'Already Exists';
GroupError.NOT_FOUND = 'Not Found';
GroupError.BAD_FIELD = 'Field error';
2016-02-08 09:41:21 -08:00
GroupError.NOT_EMPTY = 'Not Empty';
2016-02-13 12:24:51 +01:00
GroupError.NOT_ALLOWED = 'Not Allowed';
2016-02-07 20:25:08 -08:00
function validateGroupname(name) {
assert.strictEqual(typeof name, 'string');
var RESERVED = [ 'admins', 'users' ]; // ldap code uses 'users' pseudo group
2016-02-07 20:25:08 -08:00
if (name.length <= 2) return new GroupError(GroupError.BAD_FIELD, 'name must be atleast 2 chars');
if (name.length >= 200) return new GroupError(GroupError.BAD_FIELD, 'name too long');
2016-02-07 20:25:08 -08:00
if (!/^[A-Za-z0-9_-]*$/.test(name)) return new GroupError(GroupError.BAD_FIELD, 'name can only have A-Za-z0-9_-');
2016-02-08 09:41:21 -08:00
if (RESERVED.indexOf(name) !== -1) return new GroupError(GroupError.BAD_FIELD, 'name is reserved');
2016-02-07 20:25:08 -08:00
return null;
}
function create(name, callback) {
assert.strictEqual(typeof name, 'string');
assert.strictEqual(typeof callback, 'function');
var error = validateGroupname(name);
if (error) return callback(error);
groupdb.add(name /* id */, name, function (error) {
2016-02-07 20:34:05 -08:00
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new GroupError(GroupError.ALREADY_EXISTS));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
2016-02-07 20:25:08 -08:00
2016-02-09 13:33:30 -08:00
callback(null, { id: name, name: name });
2016-02-07 20:25:08 -08:00
});
}
function remove(id, callback) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof callback, 'function');
2016-02-13 12:24:51 +01:00
// never allow admin group to be deleted
if (id === exports.ADMIN_GROUP_ID) return callback(new GroupError(GroupError.NOT_ALLOWED));
2016-02-07 20:25:08 -08:00
groupdb.del(id, function (error) {
2016-02-07 20:34:05 -08:00
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
2016-02-07 20:25:08 -08:00
callback(null);
});
}
function get(id, callback) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.get(id, function (error, result) {
2016-02-07 20:34:05 -08:00
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
2016-02-07 20:25:08 -08:00
return callback(null, result);
});
}
2016-02-09 15:26:34 -08:00
function getWithMembers(id, callback) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.getWithMembers(id, function (error, result) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
return callback(null, result);
});
}
2016-02-09 13:33:30 -08:00
function getAll(callback) {
assert.strictEqual(typeof callback, 'function');
groupdb.getAll(function (error, result) {
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
return callback(null, result);
});
}
function getAllWithMembers(callback) {
assert.strictEqual(typeof callback, 'function');
groupdb.getAllWithMembers(function (error, result) {
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
2016-02-09 13:33:30 -08:00
return callback(null, result);
});
}
2016-02-08 09:41:21 -08:00
function getMembers(groupId, callback) {
assert.strictEqual(typeof groupId, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.getMembers(groupId, function (error, result) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
return callback(null, result);
});
}
2016-02-08 20:38:50 -08:00
function getGroups(userId, callback) {
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.getGroups(userId, function (error, result) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
return callback(null, result);
});
}
2016-02-09 15:47:02 -08:00
function setGroups(userId, groupIds, callback) {
assert.strictEqual(typeof userId, 'string');
assert(Array.isArray(groupIds));
assert.strictEqual(typeof callback, 'function');
2016-02-11 10:52:31 +01:00
groupdb.setGroups(userId, groupIds, function (error) {
2016-02-09 15:47:02 -08:00
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
2016-02-11 10:52:31 +01:00
return callback(null);
2016-02-09 15:47:02 -08:00
});
}
2016-02-08 09:41:21 -08:00
function addMember(groupId, userId, callback) {
assert.strictEqual(typeof groupId, 'string');
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.addMember(groupId, userId, 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));
return callback(null);
});
}
function removeMember(groupId, userId, callback) {
assert.strictEqual(typeof groupId, 'string');
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.removeMember(groupId, userId, 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));
return callback(null);
});
}
2016-02-08 10:53:01 -08:00
function isMember(groupId, userId, callback) {
assert.strictEqual(typeof groupId, 'string');
assert.strictEqual(typeof userId, 'string');
assert.strictEqual(typeof callback, 'function');
groupdb.isMember(groupId, userId, function (error, result) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new GroupError(GroupError.NOT_FOUND));
if (error) return callback(new GroupError(GroupError.INTERNAL_ERROR, error));
return callback(null, result);
});
}