diffusion
Version:
Diffusion JavaScript client
304 lines (252 loc) • 10.4 kB
JavaScript
var Services = require('services/services');
var CHANGE_PRINCIPAL = require('services/services').CHANGE_PRINCIPAL;
var GET_SECURITY_CONFIGURATION = require('services/services').GET_SECURITY_CONFIGURATION;
var UPDATE_SECURITY_CONFIGURATION = require('services/services').UPDATE_SECURITY_CONFIGURATION;
var GET_SYSTEM_AUTHENTICATION = require('services/services').GET_SYSTEM_AUTHENTICATION;
var UPDATE_SYSTEM_AUTHENTICATION = require('services/services').UPDATE_SYSTEM_AUTHENTICATION;
var Emitter = require('events/emitter');
var Result = require('events/result');
var registerHandler = require('control/registration').registerHandler;
var ControlGroup = require('control/control-group');
var CommandService = require('client/command-service');
var AuthenticationResponse = require('services/security/authentication-response');
var SecurityCommandScript = require('services/authentication/security-command-script');
var SecurityScriptBuilder = require('features/security/security-script-builder');
var AuthenticationScriptBuilder = require('features/security/system-authentication-script-builder');
var _implements = require('util/interface')._implements;
var api = require('../../features/security');
var requireNonNull = require('util/require-non-null');
var log = require('util/logger').create('Session.Security');
var GlobalPermission = {
AUTHENTICATE: 0,
VIEW_SESSION: 1,
MODIFY_SESSION: 2,
REGISTER_HANDLER: 3,
VIEW_SERVER: 4,
CONTROL_SERVER: 5,
VIEW_SECURITY: 6,
MODIFY_SECURITY: 7
};
var TopicPermission = {
READ_TOPIC: 0,
UPDATE_TOPIC: 1,
MODIFY_TOPIC: 2,
SEND_TO_MESSAGE_HANDLER: 3,
SEND_TO_SESSION: 4,
SELECT_TOPIC: 5,
QUERY_OBSOLETE_TIME_SERIES_EVENTS: 6,
EDIT_TIME_SERIES_EVENTS: 7,
EDIT_OWN_TIME_SERIES_EVENTS: 8,
ACQUIRE_LOCK: 9
};
var SecurityConfiguration = _implements(api.SecurityConfiguration, {
__constructor: function Configuration(anonymous, named, roles) {
this.anonymous = anonymous;
this.named = named;
this.roles = roles;
},
toString: function () {
return "SecurityConfiguration [anonymous=" + this.anonymous + ", named=" + this.named +
", roles=" + this.roles + "]";
}
});
var SystemAuthentication = _implements(api.SystemAuthenticationConfiguration, {
__constructor: function Configuration(principals, action, roles) {
this.principals = principals || [];
this.anonymous = {
action: action,
roles: roles || []
};
},
toString: function () {
return "SystemAuthenticationConfiguration [principals=" +
this.principals + ", anonymous=" + this.anonymous + "]";
}
});
SystemAuthentication.CONNECTION_ACTION = {
ALLOW: {id: 0, value: 'allow'},
DENY: {id: 1, value: 'deny'},
ABSTAIN: {id: 2, value: 'abstain'},
fromString: function (val) {
return this[val.toUpperCase()];
}
};
var SystemPrincipal = _implements(api.SystemPrincipal, {
__constructor: function SystemPrincipal(name, roles) {
this.name = requireNonNull(name);
this.roles = roles || [];
},
toString: function () {
return "SystemPrincipal [" + this.name + ", " + this.roles + "]";
}
});
function remappingValueWithKey(permission) {
var p = {};
Object.keys(permission).forEach(function(key) {
p[key] = key;
});
return p;
}
var Security = _implements(api, function SecurityImpl(internal) {
var serviceLocator = internal.getServiceLocator();
var changePrincipal = serviceLocator.obtain(CHANGE_PRINCIPAL);
var getConfiguration = serviceLocator.obtain(GET_SECURITY_CONFIGURATION);
var getSystemAuthentication = serviceLocator.obtain(GET_SYSTEM_AUTHENTICATION);
var updateSystemAuthentication = serviceLocator.obtain(UPDATE_SYSTEM_AUTHENTICATION);
var updateSecurityConfiguration = serviceLocator.obtain(UPDATE_SECURITY_CONFIGURATION);
internal.getServiceRegistry().add(Services.AUTHENTICATION, CommandService.create(function(internal, req, callback) {
internal.getConversationSet().respond(req.cid, { req : req, callback : callback });
}));
this.GlobalPermission = remappingValueWithKey(GlobalPermission);
this.TopicPermission = remappingValueWithKey(TopicPermission);
this.getPrincipal = function () {
return internal.getPrincipal();
};
this.changePrincipal = function (principal, credentials) {
var emitter = new Emitter();
var result = new Result(emitter);
if (internal.checkConnected(emitter)) {
log.debug('Changing principal', principal);
changePrincipal.send({
principal: principal,
credentials: credentials
}, function (err, response) {
if (err) {
emitter.error(err);
} else {
if (response) {
internal.setPrincipal(principal);
emitter.emit('complete');
} else {
emitter.error(new Error('Unable to change principal due to authentication failure'));
}
}
});
}
return result;
};
this.getSecurityConfiguration = function () {
var emitter = new Emitter();
var result = new Result(emitter);
if (internal.checkConnected(emitter)) {
log.debug('Getting security configuration');
getConfiguration.send(null, function (err, response) {
if (err) {
emitter.error(err);
} else {
emitter.emit('complete', response);
}
});
}
return result;
};
this.getSystemAuthenticationConfiguration = function () {
var emitter = new Emitter();
var result = new Result(emitter);
if (internal.checkConnected(emitter)) {
log.debug('Getting system authentication');
getSystemAuthentication.send(null, function (err, response) {
if (err) {
emitter.error(err);
} else {
emitter.emit('complete', response);
}
});
}
return result;
};
this.setAuthenticationHandler = function(name, details, handler) {
var emitter = new Emitter();
var result = new Result(emitter);
if (internal.checkConnected(emitter)) {
log.debug('Setting Authentication Handler for "' + name + '"');
var adapter = {
active : function(close) {
log.debug('Authentication Handler active for "' + name + '"');
handler.onActive(close);
},
respond : function(msg) {
var req = msg.req;
var callback = msg.callback;
handler.onAuthenticate(req.principal, req.credentials, req.details, {
allow : function (res) {
if (res) {
callback.respond(AuthenticationResponse.allow(res));
} else {
callback.respond(AuthenticationResponse.ALLOW);
}
},
abstain : function () {
callback.respond(AuthenticationResponse.ABSTAIN);
},
deny : function () {
callback.respond(AuthenticationResponse.DENY);
}
});
},
close : function(err) {
if (err) {
log.debug('Authentication Handler closed with error for "' + name + '"');
handler.onError(err);
} else {
log.debug('Authentication Handler closed for "' + name + '"');
handler.onClose();
}
}
};
var params = {
definition : Services.AUTHENTICATION,
group : ControlGroup.DEFAULT,
details : details,
name : name
};
return registerHandler(internal, params, adapter,
Services.AUTHENTICATION_CONTROL_REGISTRATION,
Services.AUTHENTICATION_CONTROL_DEREGISTRATION);
}
return result;
};
var updateStoreCallback = function (err, result, emitter) {
if (err) {
emitter.error(err);
} else if (result.errors.length > 0) {
emitter.error(result.errors);
} else {
emitter.emit('complete');
}
};
var updateStore = function (updater, script) {
var emitter = new Emitter();
var result = new Result(emitter);
if (script === "") {
emitter.emit('complete');
} else if (!script || typeof script !== 'string') {
emitter.error(new Error('Invalid argument for script:' + script));
} else if (internal.checkConnected(emitter)) {
updater.send(new SecurityCommandScript(script), function (err, result) {
updateStoreCallback(err, result, emitter);
});
}
return result;
};
this.updateSecurityStore = function (script) {
log.debug('Updating security store');
return updateStore(updateSecurityConfiguration, script);
};
this.updateAuthenticationStore = function (script) {
log.debug('Updating authentication store');
return updateStore(updateSystemAuthentication, script);
};
this.securityScriptBuilder = function (script) {
return new SecurityScriptBuilder(script);
};
this.authenticationScriptBuilder = function (script) {
return new AuthenticationScriptBuilder(script);
};
});
module.exports.GlobalPermission = GlobalPermission;
module.exports.TopicPermission = TopicPermission;
module.exports.Security = Security;
module.exports.SystemPrincipal = SystemPrincipal;
module.exports.Configuration = SecurityConfiguration;
module.exports.SystemAuthentication = SystemAuthentication;