Before I go to far I am hoping someone can tell me if I am handling this situation correctly or if there is a far easier way I am just missing. We have a web page made using AngularJS and Web API. We are now dealing with authentication of users when they try to go to certain pages. We have a module called permissions we use for this currently shown below.
angular.module('permissions', []).factory('permissions', function (LoginApi, $q) {
//this is the variable which will hold the user, fetch it from the server - will return null if not authenticated
var storedUser;
function currentUser() {
var deferred = $q.defer();
if (!storedUser) {
storedUser = LoginApi.get(function () {
deferred.resolve(storedUser);
})
}
else {
deferred.resolve(storedUser);
}
return deferred.promise;
}
//define the permissions object that's exposed publicly
return {
setUser: function (user) {
storedUser = user;
},
isInRole: function (roleName) {
var promise = currentUser();
promise.then(function() {
if (!storedUser || !storedUser.roles) {
return false;
}
//if roleName is in currentUserRoles, then return true
if (storedUser.roles.indexOf(roleName) > -1) {
return true;
} else {
return false;
}
}, function(reason) {
return false;
});
},
isLoggedIn: function () {
var promise = currentUser();
promise.then(function() {
if (!storedUser) {
return false;
} else {
return true;
}
}, function(reason) {
return false;
});
},
firstName: function () {
var promise = currentUser();
promise.then(function () {
if (!storedUser) {
return '';
}
return storedUser.firstName;
}, function (reason) {
return '';
});
},
lastName: function () {
var promise = currentUser();
promise.then(function () {
if (!storedUser) {
return '';
}
return storedUser.lastName;
}, function (reason) {
return '';
});
},
email: function () {
var promise = currentUser();
promise.then(function () {
if (!storedUser) {
return '';
}
return storedUser.email;
}, function (reason) {
return '';
});
}
};
});
As you can see I am using a promise to make my calls wait for me to get the user if there is one that is logged in. I have this working but now my issue is that in any function on my web site that deals with permissions it looks like I will need to add promises and deferrals too because currently the calls are not waiting for the permissions functions to run. An example of a place this is being used is in my routeChange event on the rootScope shown below
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (next.access == "All")
{
//do nothing
}
else if (next.access == "User") {
if ($rootScope.permissions.isLoggedIn()) {
//do nothign they have permissions required
} else {
// not going to #login, we should redirect now
$location.path("/login");
}
}
else if (next.access == "Admin") {
if ($rootScope.permissions.isInRole('Admin_Base')) {
//do nothign they have valid permissions
} else {
// not going to #login, we should redirect now
$location.path("/403");
}
}
});
So basically even though inside of permissions my functions defer til the user gets returned. The functions that call these functions do not defer so it basically gets a false returned every time when checking permissions. I think I can get around this by adding promises to the calls to permissions but I am wondering if there is an easier way to handle this that I am missing.