UNPKG

diffusion

Version:

Diffusion JavaScript client

304 lines (252 loc) 10.4 kB
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;