151 lines
5.0 KiB
JavaScript
151 lines
5.0 KiB
JavaScript
/*
|
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
* not use this file except in compliance with the License. You may obtain
|
|
* a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
/**
|
|
* This service maintains our permission state while the client is running.
|
|
* Rather than be based on a per-request basis whose responses can quickly
|
|
* become stale, it broadcasts events which views/directives can use to
|
|
* update their permissions.
|
|
*
|
|
* At the moment this is a fairly naive implementation, which assumes that
|
|
* permissions are defined as key/value pairs, and are globally scoped.
|
|
* For example, this is possible:
|
|
*
|
|
* isSuperuser: true
|
|
*
|
|
* But this is not.
|
|
*
|
|
* Project ID 4, canEdit: false
|
|
*
|
|
* We'll need to update this once we know what our permission structure
|
|
* looks like.
|
|
*/
|
|
angular.module('sb.auth').factory('PermissionManager',
|
|
function ($log, $q, $rootScope, Session, SessionState, CurrentUser,
|
|
Notification, Priority) {
|
|
'use strict';
|
|
|
|
// Our permission resolution cache.
|
|
var permCache = {};
|
|
var NOTIFY_PERMISSIONS = 'notify_permissions';
|
|
|
|
/**
|
|
* Resolve a permission.
|
|
*/
|
|
function resolvePermission(permName) {
|
|
var deferred = $q.defer();
|
|
|
|
if (permCache.hasOwnProperty(permName)) {
|
|
deferred.resolve(permCache[permName]);
|
|
} else {
|
|
CurrentUser.resolve().then(
|
|
function (user) {
|
|
permCache[permName] = user[permName];
|
|
deferred.resolve(permCache[permName]);
|
|
},
|
|
function (error) {
|
|
deferred.reject(error);
|
|
}
|
|
);
|
|
}
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Clear the permission cache and notify the system that it needs
|
|
* to re-resolve the permissions.
|
|
*/
|
|
function clearPermissionCache() {
|
|
$log.debug('Resetting permission cache.');
|
|
permCache = {};
|
|
$rootScope.$broadcast(NOTIFY_PERMISSIONS);
|
|
}
|
|
|
|
/**
|
|
* Wrapper function which resolves the permission we're looking
|
|
* for and then invokes the passed handler.
|
|
*/
|
|
function permissionListenHandler(permName, handler) {
|
|
return function () {
|
|
resolvePermission(permName).then(
|
|
function (value) {
|
|
handler(value);
|
|
},
|
|
function () {
|
|
handler(null);
|
|
}
|
|
);
|
|
};
|
|
}
|
|
|
|
return {
|
|
/**
|
|
* Initialize the permission manager on the passed scope.
|
|
*/
|
|
initialize: function () {
|
|
$log.debug('Initializing permissions');
|
|
|
|
|
|
// Always record the logged in state on the root scope.
|
|
var removeNotifier = Notification.intercept(function (message) {
|
|
switch (message.type) {
|
|
case SessionState.LOGGED_IN:
|
|
case SessionState.LOGGED_OUT:
|
|
clearPermissionCache();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}, Priority.LAST);
|
|
|
|
$rootScope.$on('$destroy', removeNotifier);
|
|
|
|
// Run update if the session state has already resolved.
|
|
// Otherwise wait for the above listeners.
|
|
if (Session.getSessionState() !== SessionState.PENDING) {
|
|
clearPermissionCache();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Convenience method which allows a
|
|
* @param scope The view scope that wants to listen to permission
|
|
* changes.
|
|
* @param permName The name of the permission.
|
|
* @param handler The response handler
|
|
*/
|
|
listen: function (scope, permName, handler) {
|
|
var messageHandler = permissionListenHandler(permName, handler);
|
|
|
|
scope.$on('$destroy',
|
|
$rootScope.$on(NOTIFY_PERMISSIONS, messageHandler)
|
|
);
|
|
|
|
// Trigger the handler once.
|
|
messageHandler();
|
|
},
|
|
|
|
/**
|
|
* Resolve a specific permission. Loads from a resolution cache
|
|
* if this permission is currently unknown.
|
|
*/
|
|
resolve: function (permName) {
|
|
return resolvePermission(permName);
|
|
}
|
|
};
|
|
});
|