Auth Service
(function () {
var m = angular.module("g.common");
m.factory('Auth', function ($http, $location, $cookieStore, rootUrl) {
var authConfig = new Framework.Core.Utilities.DefaultAuthConfiguration();
var accessLevels = authConfig.accessLevels;
var userRoles = authConfig.roles;
var currentUser = $cookieStore.get('user') || { username: '', role: userRoles.filter((p) => p.title == 'public')[0] };
$cookieStore.remove('user');
var refreshuser = $http({
method: 'POST',
url: rootUrl + '/currentuser/',
cache: false
});
var refreshuserCallback = response => {
changeUser(response.data);
}
refreshuser.then(refreshuserCallback);
function changeUser(user) {
angular.extend(currentUser, user);
}
var authService =
{
authorize: (accessLevel, role) => {
if (role === undefined) {
role = currentUser.role;
}
return accessLevel.bitMask & role.bitMask;
},
isLoggedIn: (user) => {
if (user === undefined) {
user = currentUser;
}
return user.role.title === 'user' || user.role.title === 'admin';
},
authenticate: () => {
var user = currentUser;
var isloggedin = user.role.title === 'user' || user.role.title === 'admin';
return refreshuser
.then(refreshuserCallback)
.then((x) => {
if (!isloggedin)
window.location.replace(rootUrl + '/secure/login');
}).error(() => { console.error('Error refreshing user'); });
},
logout: () => {
changeUser({
username: '',
role: userRoles.filter((p) => p.title == 'public')[0]
});
return Q(window.location.replace(rootUrl + '/secure/logout'));
},
accessLevels: accessLevels,
userRoles: userRoles,
user: currentUser
};
return authService;
});
m.directive('accessLevel', ['Auth', function (Auth) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var prevDisp = element.css('display')
, userRole
, accessLevel;
$scope.user = Auth.user;
$scope.$watch('user', function (user) {
if (user.role)
userRole = user.role;
updateCSS();
}, true);
attrs.$observe('accessLevel', function (al) {
if (al) accessLevel = $scope.$eval(al);
updateCSS();
});
function updateCSS() {
if (userRole && accessLevel) {
if (!Auth.authorize(accessLevel, userRole))
element.css('display', 'none');
else
element.css('display', prevDisp);
}
}
}
};
}]);
m.directive('activeNav', ['$location', function ($location) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var anchor = element[0];
if (element[0].tagName.toUpperCase() != 'A')
anchor = element.find('a')[0];
var path = anchor.href;
scope.location = $location;
scope.$watch('location.absUrl()', function (newPath) {
path = normalizeUrl(path);
newPath = normalizeUrl(newPath);
if (path === newPath ||
(attrs.activeNav === 'nestedTop' && newPath.indexOf(path) === 0)) {
element.addClass('active');
} else {
element.removeClass('active');
}
});
}
};
}]);
} ());
Access Level Attribute Directive Usage Example
<span data-access-level='accessLevels.anon'>
<button class="btn btn-default navbar-btn" type="submit" ng-click="login()">Log in</button>
</span>
<span data-access-level='accessLevels.user'>
<!--<div class="editor-label navbar-btn" id="userInfo" data-access-level='accessLevels.user'>Welcome {{ user.username }}</div>-->
<button class="btn btn-default navbar-btn" type="submit" ng-click="logout()">Log out</button>
</span>
State Provider
var authConfig: Framework.Core.Configuration.AuthConfiguration = new Framework.Core.Utilities.DefaultAuthConfiguration();
var access: Framework.Core.Configuration.AccessLevels = authConfig.accessLevels;
$stateProvider
.state('g', {
abstract: true,
template: '<ui-view/>',
resolve: {
"configuration": ($state,
ConfigurationService: Framework.Core.Services.ConfigurationService,
ApplicationDataSourcesInitializer: ApplicationDataSourcesInitializer) => {
return ConfigurationService
.getConfiguration();
}
},
data: {
access: access['public']
}
})
State Change
application.run(['$rootScope', '$state', 'Auth', function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
if (!('data' in toState) || !('access' in toState.data)) {
$rootScope.error = "Access undefined for this state";
event.preventDefault();
}
else if (!Auth.authorize(toState.data.access)) {
$rootScope.error = "Access denied";
alert("Access denied");
event.preventDefault();
if (fromState.url === '^') {
if (Auth.isLoggedIn()) {
$state.go('gev-sec');
} else {
$rootScope.error = null;
$state.go('gev');
}
}
}
});
}]);
Default Configuration
var DefaultAuthConfiguration = (function () {
function DefaultAuthConfiguration() {
this._roleTitles = ['public', 'user', 'admin'];
this._roles = null;
this._accessLevels = {
'public': "*",
'anon': ['public'],
'user': ['user', 'admin'],
'admin': ['admin']
};
CreateAccessLevels(this);
}
Object.defineProperty(DefaultAuthConfiguration.prototype, "accessLevels", {
get: function () {
return this._accessLevels;
},
set: function (accessLevels) {
this._accessLevels = accessLevels;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DefaultAuthConfiguration.prototype, "roles", {
get: function () {
return this._roles;
},
set: function (roles) {
this._roles = roles;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DefaultAuthConfiguration.prototype, "roleTitles", {
get: function () {
return this._roleTitles;
},
set: function (roleTitles) {
this._roleTitles = roleTitles;
;
},
enumerable: true,
configurable: true
});
return DefaultAuthConfiguration;
})();
Utilities.DefaultAuthConfiguration = DefaultAuthConfiguration;
function CreateRoles(authConfiguration) {
var bitMask = "01";
var userRoles = new Array();
for (var i = 0; i < authConfiguration.roleTitles.length; i++) {
var intCode = parseInt(bitMask, 2);
userRoles.push({
bitMask: intCode,
title: authConfiguration.roleTitles[i]
});
bitMask = (intCode << 1).toString(2);
}
authConfiguration.roles = userRoles;
}
Utilities.CreateRoles = CreateRoles;
function CreateAccessLevels(authConfiguration) {
if (!authConfiguration.roles)
CreateRoles(authConfiguration);
var accessLevels = {};
Object.keys(authConfiguration.accessLevels).map(function (leve) {
var accessLevelDeclaration = authConfiguration.accessLevels[leve];
var userRoles = authConfiguration.roles;
if (typeof accessLevelDeclaration == 'string') {
if (accessLevelDeclaration == '*') {
console.log('level: ' + accessLevelDeclaration);
var resultBitMask = '';
for (var role in authConfiguration.roles) {
resultBitMask += "1";
}
accessLevels[leve] = {
bitMask: parseInt(resultBitMask, 2)
};
}
else
console.log("Access Control Error: Could not parse '" + leve + "' as access definition for level '" + leve + "'");
}
else {
var resultBitMask2 = 0;
for (var i = 0; i < accessLevelDeclaration.length; i++) {
var accessrole = accessLevelDeclaration[i];
var userRolearr = userRoles.filter(function (p) { return p.title == accessrole; });
if (userRolearr.length > 0)
resultBitMask2 = resultBitMask2 | userRolearr[0].bitMask;
else
console.log("Access Control Error: Could not find role '" + accessrole + "' in registered roles while building access for '" + leve + "'");
}
accessLevels[leve] = {
bitMask: resultBitMask2
};
}
});
authConfiguration.accessLevels = accessLevels;
}
Utilities.CreateAccessLevels = CreateAccessLevels;