/**
* The UserSync module
* @module usersync
* @copyright CHECKROOM NV 2017
*/
define([
'jquery',
'base',
'common'
], /** @lends UserSync */ function ($, Base, common) {
var DEFAULTS = {
kind: "ldap",
name: "",
host: "ldap://yourdomain.com",
port: 389,
timeOut: 10,
login: "",
password: "",
newUsers: "create",
existingUsers: "update",
missingUsers: "ignore",
autoSync: false,
role: "selfservice",
query: "(cn=*)",
base: "ou=team,dc=yourdomain,dc=com",
loginField: "uid",
nameField: "cn",
emailField: "mail",
restrictLocations: [],
timezone: "Etc/GMT",
hostCert: 'ldap_tls_demand'
};
// Allow overriding the ctor during inheritance
// http://stackoverflow.com/questions/4152931/javascript-inheritance-call-super-constructor-or-use-prototype-chain
var tmp = function() {};
tmp.prototype = Base.prototype;
/**
* @name UserSync
* @class UserSync
* @constructor
* @extends Base
* @property {string} kind - The kind
* @property {string} name - The name
* @property {string} host - The url of the host
* @property {int} port - The port number
* @property {int} timeOut - The timeOut in seconds
* @property {string} login - The login for the host
* @property {string} password - The password for the host
* @property {string} newUsers - What to with new Users (ignore, create)
* @property {string} existingUsers - What to with existing Users (ignore, update)
* @property {string} missingUsers - What to with missing Users (ignore, archive, deactivate)
* @property {boolean} autoSync - Do a nightly sync automatically?
* @property {string} role - Sync users under which role? (selfservice, user, admin)
* @property {string} query - The query
* @property {string} base - The base
* @property {string} loginField - The loginField
* @property {string} nameField - The nameField
* @property {string} emailField - The emailField
*/
var UserSync = function(opt) {
var spec = $.extend({
_fields: ['*']
}, opt);
Base.call(this, spec);
this.helper = spec.helper;
this.kind = spec.kind || DEFAULTS.kind;
this.name = spec.name || DEFAULTS.name;
this.host = spec.host || DEFAULTS.host;
this.port = spec.port || DEFAULTS.port;
this.timeOut = spec.timeOut || DEFAULTS.timeOut;
this.login = spec.login || DEFAULTS.login;
this.password = spec.password || DEFAULTS.password;
this.newUsers = spec.newUsers || DEFAULTS.newUsers;
this.existingUsers = spec.existingUsers || DEFAULTS.existingUsers;
this.missingUsers = spec.missingUsers || DEFAULTS.missingUsers;
this.autoSync = (spec.autoSync!=null) ? spec.autoSync : DEFAULTS.autoSync;
this.role = spec.role || DEFAULTS.role;
this.query = spec.query || DEFAULTS.query;
this.base = spec.base || DEFAULTS.base;
this.loginField = spec.loginField || DEFAULTS.loginField;
this.nameField = spec.nameField || DEFAULTS.nameField;
this.emailField = spec.emailField || DEFAULTS.emailField;
this.restrictLocations = spec.restrictLocations?spec.restrictLocations.slice():DEFAULTS.restrictLocations.slice();
this.timezone = spec.timezone || DEFAULTS.timezone;
this.hostCert = spec.hostCert || DEFAULTS.hostCert;
};
UserSync.prototype = new tmp();
UserSync.prototype.constructor = UserSync;
//
// Document overrides
//
UserSync.prototype.isValidName = function() {
this.name = $.trim(this.name);
return (this.name.length>=3);
};
UserSync.prototype.isValidRole = function() {
switch(this.role) {
case "user":
case "admin":
case "selfservice":
return true;
default:
return false;
}
};
/**
* Checks if the usersync is valid
* @method
* @name UserSync#isValid
* @returns {boolean}
*/
UserSync.prototype.isValid = function() {
return (
this.isValidName() &&
this.isValidRole());
};
/**
* Checks if the user is empty
* @method
* @name UserSync#isEmpty
* @returns {boolean}
*/
UserSync.prototype.isEmpty = function() {
return (
(Base.prototype.isEmpty.call(this)) &&
(this.kind==DEFAULTS.kind) &&
(this.name==DEFAULTS.name) &&
(this.host==DEFAULTS.host) &&
(this.port==DEFAULTS.port) &&
(this.timeOut==DEFAULTS.timeOut) &&
(this.login==DEFAULTS.login) &&
(this.password==DEFAULTS.password) &&
(this.newUsers==DEFAULTS.newUsers) &&
(this.existsingUsers==DEFAULTS.existingUsers) &&
(this.missingUsers==DEFAULTS.missingUsers) &&
(this.autoSync==DEFAULTS.autoSync) &&
(this.role==DEFAULTS.role) &&
(this.query==DEFAULTS.query) &&
(this.base==DEFAULTS.base) &&
(this.loginField==DEFAULTS.loginField) &&
(this.nameField==DEFAULTS.nameField) &&
(this.emailField==DEFAULTS.emailField) &&
(this.timezone==DEFAULTS.timezone) &&
(this.hostCert==DEFAULTS.hostCert) &&
(this.restrictLocations && this.restrictLocations.length == 0));
};
/**
* Checks if the user is dirty and needs saving
* @method
* @name UserSync#isDirty
* @returns {boolean}
*/
UserSync.prototype.isDirty = function() {
return this._isDirtyInfo() || this._isDirtyRestrictLocations();
};
UserSync.prototype._isDirtyInfo = function(){
var isDirty = Base.prototype.isDirty.call(this);
if( (!isDirty) &&
(this.raw)) {
var kind = this.raw.kind || DEFAULTS.kind;
var name = this.raw.name || DEFAULTS.name;
var host = this.raw.host || DEFAULTS.host;
var port = this.raw.port || DEFAULTS.port;
var timeOut = this.raw.timeOut || DEFAULTS.timeOut;
var login = this.raw.login || DEFAULTS.login;
var password = this.raw.password || DEFAULTS.password;
var newUsers = this.raw.newUsers || DEFAULTS.newUsers;
var existingUsers = this.raw.existingUsers || DEFAULTS.existingUsers;
var missingUsers = this.raw.missingUsers || DEFAULTS.missingUsers;
var autoSync = (this.raw.autoSync!=null) ? this.raw.autoSync : DEFAULTS.autoSync;
var role = this.raw.role || DEFAULTS.role;
var query = this.raw.query || DEFAULTS.query;
var base = this.raw.base || DEFAULTS.base;
var loginField = this.raw.loginField || DEFAULTS.loginField;
var nameField = this.raw.nameField || DEFAULTS.nameField;
var emailField = this.raw.emailField || DEFAULTS.emailField;
var timezone = this.raw.timezone || DEFAULTS.timezone;
var hostCert = this.raw.hostCert || DEFAULTS.hostCert;
return (
(this.kind!=kind) ||
(this.name!=name) ||
(this.host!=host) ||
(this.port!=port) ||
(this.timeOut!=timeOut) ||
(this.login!=login) ||
(this.password!=password) ||
(this.newUsers!=newUsers) ||
(this.existingUsers!=existingUsers) ||
(this.missingUsers!=missingUsers) ||
(this.autoSync!=autoSync) ||
(this.role!=role) ||
(this.query!=query) ||
(this.base!=base) ||
(this.loginField!=loginField) ||
(this.nameField!=nameField) ||
(this.emailField!=emailField) ||
(this.timezone!=timezone) ||
(this.hostCert!=hostCert) ||
(this._isDirtyRestrictLocations())
);
}
return isDirty;
}
UserSync.prototype._isDirtyRestrictLocations = function(){
if((this.raw)) {
var that = this,
restrictLocations = this.raw.restrictLocations || DEFAULTS.restrictLocations;
// Check if other locations have been selected
return this.restrictLocations.filter(function(x){ return restrictLocations.indexOf(x) < 0; }).length > 0 ||
restrictLocations.filter(function(x){ return that.restrictLocations.indexOf(x) < 0; }).length > 0;
}
return false;
};
UserSync.prototype._getDefaults = function() {
return DEFAULTS;
};
//
// Business logic
//
/**
* Clones the template to a new one
* @name UserSync#clone
* @returns {promise}
*/
UserSync.prototype.clone = function() {
return this.ds.call(this.id, "clone");
};
/**
* Tests the specified connection
* @name UserSync#testConnection
* @returns {promise}
*/
UserSync.prototype.testConnection = function() {
return this.ds.call(this.id, "testConnection");
};
/**
* Tests the specified sync
* @name UserSync#syncUsers
* @param wetRun
* @returns {promise}
*/
UserSync.prototype.syncUsers = function(wetRun) {
return this.ds.call(this.id, "syncUsers", {wetRun: wetRun});
};
/**
* Writes the usersync to a json object
* @param options
* @returns {object}
* @private
*/
UserSync.prototype._toJson = function(options) {
var data = Base.prototype._toJson.call(this, options);
data.kind = this.kind || DEFAULTS.kind;
data.name = this.name || DEFAULTS.name;
data.host = this.host || DEFAULTS.host;
data.port = this.port || DEFAULTS.port;
data.timeOut = this.timeOut || DEFAULTS.timeOut;
data.login = this.login || DEFAULTS.login;
data.password = this.password || DEFAULTS.password;
data.newUsers = this.newUsers || DEFAULTS.newUsers;
data.existingUsers = this.existingUsers || DEFAULTS.existingUsers;
data.missingUsers = this.missingUsers || DEFAULTS.missingUsers;
data.autoSync = (this.autoSync!=null) ? this.autoSync : DEFAULTS.autoSync;
data.role = this.role || DEFAULTS.role;
data.query = this.query || DEFAULTS.query;
data.base = this.base || DEFAULTS.base;
data.loginField = this.loginField || DEFAULTS.loginField;
data.nameField = this.nameField || DEFAULTS.nameField;
data.emailField = this.emailField || DEFAULTS.emailField;
data.timezone = this.timezone || DEFAULTS.timezone;
data.hostCert = this.hostCert || DEFAULTS.hostCert;
return data;
};
/**
* Reads the usersync from the json object
* @param data
* @param options
* @returns {promise}
* @private
*/
UserSync.prototype._fromJson = function(data, options) {
var that = this;
return Base.prototype._fromJson.call(this, data, options)
.then(function() {
// Read the group id from group or group._id
// depending on the fields
that.kind = data.kind || DEFAULTS.kind;
that.name = data.name || DEFAULTS.name;
that.host = data.host || DEFAULTS.host;
that.port = data.port || DEFAULTS.port;
that.timeOut = data.timeOut || DEFAULTS.timeOut;
that.login = data.login || DEFAULTS.login;
that.password = data.password || DEFAULTS.password;
that.newUsers = data.newUsers || DEFAULTS.newUsers;
that.existingUsers = data.existingUsers || DEFAULTS.existingUsers;
that.missingUsers = data.missingUsers || DEFAULTS.missingUsers;
that.autoSync = (data.autoSync!=null) ? data.autoSync : DEFAULTS.autoSync;
that.role = data.role || DEFAULTS.role;
that.query = data.query || DEFAULTS.query;
that.base = data.base || DEFAULTS.base;
that.loginField = data.loginField || DEFAULTS.loginField;
that.nameField = data.nameField || DEFAULTS.nameField;
that.emailField = data.emailField || DEFAULTS.emailField;
that.restrictLocations = data.restrictLocations?data.restrictLocations.slice():DEFAULTS.restrictLocations.slice();
that.timezone = data.timezone || DEFAULTS.timezone;
that.hostCert = data.hostCert || DEFAULTS.hostCert;
$.publish('usersync.fromJson', data);
return data;
});
};
/**
* Restrict user access to specific location(s)
* @param locations
* @param skipRead
* @returns {promise}
*/
UserSync.prototype.setRestrictLocations = function(locations, skipRead) {
if (!this.existsInDb()) {
return $.Deferred().reject("Usersync does not exist in database");
}
return this._doApiCall({method: 'setRestrictLocations', params: { restrictLocations: locations }, skipRead: skipRead});
};
/**
* Clear user location(s) access (makes all location accessible for the user)
* @param skipRead
* @returns {promise}
*/
UserSync.prototype.clearRestrictLocations = function(skipRead) {
if (!this.existsInDb()) {
return $.Deferred().reject("Usersync does not exist in database");
}
return this._doApiCall({method: 'clearRestrictLocations', skipRead: skipRead});
};
/**
* Updates the usersync
* @param skipRead
* @returns {*}
*/
UserSync.prototype.update = function(skipRead) {
if (this.isEmpty()) {
return $.Deferred().reject(new Error("Cannot update to empty usersync"));
}
if (!this.existsInDb()) {
return $.Deferred().reject(new Error("Cannot update usersync without id"));
}
if (!this.isValid()) {
return $.Deferred().reject(new Error("Cannot update, invalid usersync"));
}
var that = this,
dfdRestrictLocations = $.Deferred(),
dfdInfo = $.Deferred(),
params = this._toJson();
if(this._isDirtyInfo()){
dfdInfo = this.ds.update(this.id, params, this._fields).then(function(resp){
that._fromJson(resp);
});
}else{
dfdInfo.resolve();
}
if(this._isDirtyRestrictLocations()){
if(this.restrictLocations.length != 0){
dfdRestrictLocations = this.setRestrictLocations(this.restrictLocations, true);
} else{
dfdRestrictLocations = this.clearRestrictLocations(true);
}
}else{
dfdRestrictLocations.resolve();
}
return $.when(dfdInfo, dfdRestrictLocations);
};
UserSync.prototype.create = function (skipRead) {
if (this.existsInDb()) {
return $.Deferred().reject(new Error('Cannot create document, already exists in database'));
}
if (this.isEmpty()) {
return $.Deferred().reject(new Error('Cannot create empty document'));
}
return this._create(skipRead);
};
return UserSync;
});