예제 #1
0
        // 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);
        }
예제 #2
0
        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
            });
        }
    }
예제 #3
0
        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);
        }
예제 #4
0
        // 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);
        }
예제 #5
0
 private UserSummary map(ScampUser docDbUSer)
 {
     return(new UserSummary
     {
         Id = docDbUSer.Id,
         Name = docDbUSer.Name
     });
 }
예제 #6
0
        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
            });
        }
예제 #7
0
 /// <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;
     }
 }
예제 #8
0
        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
            });
        }
예제 #9
0
        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...
        }
예제 #10
0
        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
                });
            }
        }
예제 #11
0
        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
            });
        }
예제 #12
0
        // 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);
        }
예제 #13
0
        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;
            }
        }
예제 #14
0
        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
                });
            }
        }
예제 #15
0
        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));
            }
        }
예제 #16
0
        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
            });
        }
예제 #17
0
        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
            });
        }
    }
}
예제 #18
0
        public async Task <bool> IsSysAdmin()
        {
            ScampUser user = await GetOrCreateCurrentUser();

            return(user.IsSystemAdmin);
        }
예제 #19
0
 public UserRepository(DocDb docdb)
 {
     this.docdb      = docdb;
     this.cachedUser = null;
 }
예제 #20
0
        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
            });
        }
예제 #21
0
        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
            });
        }