// this method will see if the requesting user has permissions to take the action on the // specified resource private async Task <bool> CanManageResource(ScampResource resource, ResourceAction action) { ScampUser currentUser = await _securityHelper.GetOrCreateCurrentUser(); // System admin can do everything EXCEPT create a resource // to create a resource, you must be a group admin if (action != ResourceAction.Create && currentUser.IsSystemAdmin) { return(true); //Sysadmin can do everything } // Resource owner can also do anything to their resource except create var owner = resource.Owners.Find(user => user.Id == currentUser.Id); // if current user is in list of resource owners, allow action if (action != ResourceAction.Create && owner != null) { return(true); } // Resource's Group Managers can do anything to the resources in groups // they manage var rscGroup = currentUser.GroupMembership.Find(grp => grp.Id == resource.ResourceGroup.Id); // if current user is a manager of the group that owns the resource, allow action if (rscGroup != null && rscGroup.isManager) { return(true); } // if no positive results, default to false and deny action return(false); }
public async Task <IActionResult> Delete(string userId) { // only system admins can access this functionality if (!await _securityHelper.IsSysAdmin()) { return(new HttpStatusCodeResult(403)); // Forbidden } // get subscription ScampUser tmpUser = await _userRepository.GetUserById(userId); if (tmpUser == null) // if not found { return new ObjectResult("specified group manager does not exist") { StatusCode = 400 } } ; //TODO: kick off process to clean up all resources in the managers groups // https://github.com/SimpleCloudManagerProject/SCAMP/issues/197 // mark subscription as deleted tmpUser.budget = null; await _userRepository.UpdateUser(tmpUser); // return success return(new ObjectResult(null) { StatusCode = 204 }); } }
public async Task <User> Get() { // fetch current user ScampUser currentUser = await _securityHelper.GetCurrentUser(); if (currentUser == null) { currentUser = await _securityHelper.GetOrCreateCurrentUser(); // Check if this was the first user created to the system int userCount = await _userRepository.GetUserCount(); if (userCount == 1) { // Make the first user of the system a system admin so that // it has the permissions to setup the system currentUser.IsSystemAdmin = true; await _userRepository.UpdateUser(currentUser); } } // Create user object to be returned var user = new User() { Id = currentUser.Id, Name = currentUser.Name, Email = currentUser.Email, isSystemAdmin = await _securityHelper.IsSysAdmin(), isGroupAdmin = await _securityHelper.IsGroupAdmin(), isGroupManager = await _securityHelper.IsGroupManager() }; return(user); }
// retrieves the current user and creates it if it is not yet found public async Task <ScampUser> GetOrCreateCurrentUser() { ScampUser currentUser = await GetCurrentUser(); if (currentUser == null) // insert if user doesn't exist { var userId = Context.User.Claims.FirstOrDefault(c => c.Type.Contains("objectidentifier")).Value; // build user object currentUser = new ScampUser() { Id = userId, Name = string.Format("{0} {1}", Context.User.FindFirst(ClaimTypes.GivenName).Value, Context.User.FindFirst(ClaimTypes.Surname).Value).Trim(), IsSystemAdmin = false, // get email address Email = Context.User.Claims.FirstOrDefault(c => c.Type.Contains("email") || c.Type.Contains("upn")).Value }; // insert into database await _userRepository.CreateUser(currentUser); // fetch from database so that the returned object will have // proper SelfLink property currentUser = await _userRepository.GetUserById(userId); } return(currentUser); }
private UserSummary map(ScampUser docDbUSer) { return(new UserSummary { Id = docDbUSer.Id, Name = docDbUSer.Name }); }
public async Task <IActionResult> grantGroupManager([FromBody] GroupAdminSummary groupManagerSummary) { // ensure requestor has system admin permissions if (!await _securityHelper.IsSysAdmin()) { return new ObjectResult("Access Denied, requestor is not a system administrator") { StatusCode = 403 } } ; ScampUser tmpUser = await _userRepository.GetUserById(groupManagerSummary.Id); bool doingAdd = tmpUser == null; // if we're doing add operations if (doingAdd) { // build new document tmpUser = new ScampUser() { Id = groupManagerSummary.Id, Name = groupManagerSummary.Name }; } // do validation // https://github.com/SimpleCloudManagerProject/SCAMP/issues/196 // set budget info if (tmpUser.budget == null) { tmpUser.budget = new ScampUserBudget(); } tmpUser.budget.unitsBudgeted = groupManagerSummary.unitsBudgeted; tmpUser.budget.EndDate = groupManagerSummary.endDate.Date.AddMinutes(1); // save changes if (doingAdd) // create user { await _userRepository.CreateUser(tmpUser); } else // else must be update { await _userRepository.UpdateUser(tmpUser); } return(new ObjectResult(null) { StatusCode = 204 }); }
/// <summary> /// Sets (adds) a user view object into the cache /// </summary> /// <param name="user">the user view object to be inserted</param> /// <returns></returns> public async Task SetUser(ScampUser userDoc) { try { await _cache.StringSetAsync(userDoc.Id, Serialize(userDoc)); } catch (Exception ex) { //TODO: log issue string tmp = ex.Message; } }
public async Task <IActionResult> GetResourcesforUser(string userId) { List <ScampResourceSummary> resourceList = new List <ScampResourceSummary>(); ScampUser currentUser = await _securityHelper.GetOrCreateCurrentUser(); // request must be systemAdmin, or the requesting user if (!currentUser.IsSystemAdmin && currentUser.Id != userId) { return new ObjectResult("User is not authorized to perform this action against specific resource(s)") { StatusCode = 401 } } ; // execute query ScampUser user = await _userRepository.GetUserById(userId); if (user == null) { return new ObjectResult("requested resource not available") { StatusCode = 204 } } ; foreach (ScampUserGroupMbrship groupMbrship in user.GroupMembership) { foreach (ScampUserGroupResources resource in groupMbrship.Resources) { // get resource state from volatile store CurrentResourceState currentState = await _volatileStorageController.GetResourceState(resource.Id); ScampResourceSummary tmpSummary = new ScampResourceSummary() { Id = resource.Id, Name = resource.Name, Type = resource.type, State = currentState.State, totUnitsUsed = currentState.UnitsUsed }; resourceList.Add(tmpSummary); } } return(new ObjectResult(resourceList) { StatusCode = 200 }); }
public async Task UpdateUser(ScampUser user) { if (!(await docdb.IsInitialized)) { return; } var savedUser = await docdb.Client.ReplaceDocumentAsync(user.SelfLink, user); // Purge the cache cachedUser = null; //TODO: exception handling, etc... }
public async Task <IActionResult> Get(string userId, string view) { //TODO: authorization check // get requested user document ScampUser userDoc = await _userRepository.GetUserById(userId); if (userDoc == null) { return(HttpNotFound()); } if (view == "summary") { UserBudgetSummary tmpBudgetSummary = new UserBudgetSummary(); foreach (var group in userDoc.GroupMembership) { if (group.isManager) { // get this group's current budget var groupBudget = await _volatileStorageController.GetGroupBudgetState(group.Id); tmpBudgetSummary.totGroups++; tmpBudgetSummary.unitsBudgeted += groupBudget.UnitsBudgetted; tmpBudgetSummary.totUnitsUsed += groupBudget.UnitsUsed; tmpBudgetSummary.totUnitsAllocated += groupBudget.UnitsAllocated; } } ; // return view return(new ObjectResult(tmpBudgetSummary) { StatusCode = 200 }); } else { return(new ObjectResult(string.Format("view '{0}' not supported", view)) { StatusCode = 400 }); } }
public async Task <IActionResult> Get() { ScampUser currentUser = await _securityHelper.GetOrCreateCurrentUser(); List <GroupSummary> groupSummaries = new List <GroupSummary>(); foreach (ScampUserGroupMbrship group in currentUser.GroupMembership) { if (await _securityHelper.CurrentUserCanManageGroup(group.Id)) { groupSummaries.Add(MapToGroupSummary(group)); } } return(new ObjectResult(groupSummaries) { StatusCode = 200 }); }
// Returns the ScampUser based on the given userId or null // if the user wasn't found from the database public async Task <ScampUser> GetUserById(string userId) { if (!(await docdb.IsInitialized)) { return(null); } // Unless the user with given id is found from the cache, fetch it if (cachedUser == null || cachedUser.Id != userId) { // get specified user by ID var query = from u in docdb.Client.CreateDocumentQuery <ScampUser>(docdb.Collection.SelfLink) where u.Id == userId select u; cachedUser = await query.AsDocumentQuery().FirstOrDefaultAsync(); } return(cachedUser); }
public async Task CreateUser(ScampUser newUser) { try { if (!(await docdb.IsInitialized)) { return; } var created = await docdb.Client.CreateDocumentAsync(docdb.Collection.SelfLink, newUser); // Purge the cache cachedUser = null; } catch (Exception ex) { throw; } }
public async Task <IActionResult> Get(string userId, string view) { //TODO: authorization check // get requested user document ScampUser userDoc = await _userRepository.GetUserById(userId); if (userDoc == null) { return(HttpNotFound()); } // get user usage across all resources List <UserBudgetState> usrBudgets = await _volatileStorageController.GetUserBudgetStates(userId); if (view == "summary") { UserUsageSummary tmpUserSummary = new UserUsageSummary() { totGroups = userDoc.GroupMembership.Count() }; // summarize resource usage foreach (var rscBudget in usrBudgets) { tmpUserSummary.unitsBudgeted += rscBudget.UnitsBudgetted; tmpUserSummary.totUnitsUsed += rscBudget.UnitsUsed; } return(new ObjectResult(tmpUserSummary) { StatusCode = 200 }); } else { return(new ObjectResult(string.Format("view '{0}' not supported", view)) { StatusCode = 400 }); } }
public async Task <IActionResult> Put(string groupId, [FromBody] Group value) { ScampUser currentUser = await _securityHelper.GetOrCreateCurrentUser(); ScampResourceGroup group = await _groupRepository.GetGroup(groupId); // Only the group budget owner can edit the group information if (group.Budget.OwnerId == currentUser.Id) { await _groupRepository.UpdateGroup(groupId, new ScampResourceGroup { Members = value.Users.ConvertAll((a => new ScampUserGroupMbrship() { Id = a.Id, Name = a.Name, isManager = a.isManager })), Id = value.Id, Name = value.Name, Description = value.Description, Budget = new ScampGroupBudget() { OwnerId = group.Budget.OwnerId, OwnerName = group.Budget.OwnerName, unitsBudgeted = value.Budget.unitsBudgeted, DefaultUserAllocation = value.Budget.defaultUserBudget, EndDate = value.Budget.expiryDate } }); return(new ObjectResult(value) { StatusCode = 200 }); } else { return(new HttpStatusCodeResult(403)); } }
public async Task <IActionResult> grantAdmin([FromBody] UserSummary usrSummary) { // ensure requestor has system admin permissions if (!await _securityHelper.IsSysAdmin()) { return new ObjectResult("Access Denied, requestor is not a system administrator") { StatusCode = 403 } } ; ScampUser tmpUser = await _userRepository.GetUserById(usrSummary.Id); // if user wasn't found, add them to the scamp DB if (tmpUser == null) { // build new document tmpUser = new ScampUser() { Id = usrSummary.Id, Name = usrSummary.Name, IsSystemAdmin = true }; // create user await _userRepository.CreateUser(tmpUser); } else { tmpUser.IsSystemAdmin = true; await _userRepository.UpdateUser(tmpUser); // save updated setting } return(new ObjectResult(null) { StatusCode = 204 }); }
public async Task <IActionResult> revokeAdmin(string userId) { // check for last remaining admin List <ScampUser> adminList = await _settingsRepository.GetSystemAdministrators(); if (adminList.Count <= 1) { return new ObjectResult("This would remove the last system admin. There must always be at least 1.") { StatusCode = 403 } } ; ScampUser tmpUser = await _userRepository.GetUserById(userId); // if user wasn't found, add them to the scamp DB if (tmpUser == null) { return new ObjectResult("Specified user does not exist") { StatusCode = 400 } } ; // revoke admin rights tmpUser.IsSystemAdmin = false; await _userRepository.UpdateUser(tmpUser); // save updated setting return(new ObjectResult(null) { StatusCode = 204 }); } } }
public async Task <bool> IsSysAdmin() { ScampUser user = await GetOrCreateCurrentUser(); return(user.IsSystemAdmin); }
public UserRepository(DocDb docdb) { this.docdb = docdb; this.cachedUser = null; }
public async Task <IActionResult> AddUserToGroup(string groupId, [FromBody] UserSummary newUser) { if (!await _securityHelper.CurrentUserCanManageGroup(groupId)) { return(new HttpStatusCodeResult(403)); // Forbidden } string userId = newUser.Id; // get group details var rscGroup = await _groupRepository.GetGroup(groupId); if (rscGroup == null) { return(new ObjectResult("designated group does not exist") { StatusCode = 400 }); } // make sure user isn't already in group IEnumerable <ScampUserGroupMbrship> userList = from ur in rscGroup.Members where ur.Id == userId select ur; if (userList.Count() > 0) // user is already in the list { return new ObjectResult("designated user is already a member of specified group") { StatusCode = 400 } } ; // create the user if they don't exist //TODO: https://github.com/SimpleCloudManagerProject/SCAMP/issues/247 if (!(await _userRepository.UserExists(userId))) { // build user object var tmpUser = new ScampUser(newUser); // insert into database await _userRepository.CreateUser(tmpUser); } //TODO: Issue #152 // check to make sure enough remains in the group allocation to allow add of user // create volatile storage budget entry for user var newBudget = new UserBudgetState(userId, groupId) { //TODO: Take into account the budget potentially sent in POST body UnitsBudgetted = rscGroup.Budget.DefaultUserAllocation, UnitsUsed = 0 }; await _volatileStorageController.AddUserBudgetState(newBudget); newUser.unitsBudgeted = newBudget.UnitsBudgetted; // create document updates await _groupRepository.AddUserToGroup(groupId, userId, false); //TODO: Issue #152 // update group budget allocation to reflect addition of new user // return list return(new ObjectResult(newUser) { StatusCode = 200 }); }
public async Task <IActionResult> Get(string userId, string view) { // get requested user document ScampUser userDoc = await _userRepository.GetUserById(userId); if (userDoc == null) { return(HttpNotFound()); } //TODO: authorization check // build return view if (view == "admin") // do admin view { List <ScampAdminGroupReference> rtnView = new List <ScampAdminGroupReference>(); // build return view foreach (ScampUserGroupMbrship group in userDoc.GroupMembership) { if (!(await _securityHelper.CurrentUserCanManageGroup(group.Id))) { continue; } // get group budget var groupBudget = await _volatileStorageController.GetGroupBudgetState(group.Id); // build return list item ScampAdminGroupReference tmpGroupRef = new ScampAdminGroupReference() { Id = group.Id, Name = group.Name, // be sure to handle user without a budget values totUnitsUsed = (groupBudget == null ? 0 : groupBudget.UnitsUsed), totUnitsAllocated = (groupBudget == null ? 0 : groupBudget.UnitsAllocated), totUnitsBudgeted = (groupBudget == null ? 0 : groupBudget.UnitsBudgetted) }; // add item to list rtnView.Add(tmpGroupRef); } // return results return(new ObjectResult(rtnView) { StatusCode = 200 }); } else if (view == "user") // do user view { List <ScampUserGroupReference> rtnView = new List <ScampUserGroupReference>(); // get user group budgets var groupBudgets = await _volatileStorageController.GetUserBudgetStates(userId); foreach (ScampUserGroupMbrship group in userDoc.GroupMembership) { // get group var groupBudget = groupBudgets.First(g => g.groupId == group.Id); // build return object ScampUserGroupReference tmpGroupRef = new ScampUserGroupReference() { Id = group.Id, Name = group.Name, // be sure to handle user without a budget values totUnitsUsedByUser = (groupBudget == null ? 0 : groupBudget.UnitsUsed), totUnitsRemainingForUser = (groupBudget == null ? 0 : (groupBudget.UnitsBudgetted - groupBudget.UnitsUsed)) }; rtnView.Add(tmpGroupRef); } // return document return(new ObjectResult(rtnView) { StatusCode = 200 }); } else { //TODO: invalid argument "view" } return(new ObjectResult(null) { StatusCode = 200 }); }