//--- Methods ---
 public virtual RoleBE Copy() {
     RoleBE role = new RoleBE();
     role.CreatorUserId = CreatorUserId;
     role.ID = ID;
     role.Name = Name;
     role.PermissionFlags = PermissionFlags;
     role.TimeStamp = TimeStamp;
     role.Type = Type;
     return role;
 }
Exemple #2
0
        //--- Methods ---
        public virtual RoleBE Copy()
        {
            RoleBE role = new RoleBE();

            role.CreatorUserId   = CreatorUserId;
            role.ID              = ID;
            role.Name            = Name;
            role.PermissionFlags = PermissionFlags;
            role.TimeStamp       = TimeStamp;
            role.Type            = Type;
            return(role);
        }
Exemple #3
0
        /// <summary>
        /// This applies permissions in a set/replace approach synonymous with PUT
        /// </summary>
        /// <param name="targetPage">Page to apply permissions to</param>
        /// <param name="restriction">Optional restriction mask to apply to page (and optionally to child pages)</param>
        /// <param name="proposedGrants">List of grants to apply to page and child pages</param>
        /// <param name="cascade">
        /// NONE: Dont apply permissions. 
        /// ABSOLUTE: proposedGrants are applied to root page and child pages. All grants not in the proposedGrants list are removed.
        /// DELTAS: proposedGrants is applied exactly to the root page. Child pages get the differences between the proposedGrants and the grants of the root page thus preserving the grants they had.
        /// </param>
        public static void ReplacePagePermissions(PageBE targetPage, RoleBE restriction, IList<GrantBE> proposedGrants, CascadeType cascade) {
            //Perform validation of grants.

            // Make sure users and groups described in grants exist.
            // this populates user/group object within the grant.
            VerifyValidUsersAndGroups(proposedGrants);

            // Ensure a duplicate grant isn't given for the same role multiple times to a user/grant
            HashGrantsByTypeGranteeIdRoleId(proposedGrants);

            IList<GrantBE> currentGrants, proposedAddedGrants, proposedRemovedGrants;
            ulong userEffectiveRights = (ulong)GetUserPermissions(DekiContext.Current.User);

            switch(cascade) {
            case CascadeType.NONE:

                //No cascading to children. delta(current security of page, proposed security) is applied
                currentGrants = DbUtils.CurrentSession.Grants_GetByPage((uint)targetPage.ID);
                CompareGrantSets(currentGrants, proposedGrants, out proposedAddedGrants, out proposedRemovedGrants);
                ApplyPermissionChange(targetPage, false, userEffectiveRights, null, proposedAddedGrants, proposedRemovedGrants, currentGrants, restriction, true);
                break;
            case CascadeType.ABSOLUTE:

                //Cascade proposed security set to children.
                ApplyPermissionChange(targetPage, true, userEffectiveRights, proposedGrants, null, null, null, restriction, true);
                break;
            case CascadeType.DELTA:

                //Cascade delta(current security of page, proposed security) to page and children
                currentGrants = DbUtils.CurrentSession.Grants_GetByPage((uint)targetPage.ID);
                CompareGrantSets(currentGrants, proposedGrants, out proposedAddedGrants, out proposedRemovedGrants);
                // Note (arnec): even if proposed add & remove are empty, we have to call this method, since restriction may need to be set and propagated.
                ApplyPermissionChange(targetPage, true, userEffectiveRights, null, proposedAddedGrants, proposedRemovedGrants, currentGrants, restriction, true);
                break;
            }
        }
        private static void ParseUserXml(XDoc userDoc, out uint? id, out string username, out string email, out string fullname, out ServiceBE authService, out RoleBE role, out bool? active, out string language, out string timezone) {

            username = userDoc["username"].AsText;
            email = userDoc["email"].AsText;
            fullname = userDoc["fullname"].AsText;
            language = userDoc["language"].AsText;
            timezone = userDoc["timezone"].AsText;
            string authserviceidstr = userDoc["service.authentication/@id"].AsText;
            string rolestr = userDoc["permissions.user/role"].AsText;
            string statusStr = userDoc["status"].AsText;
            authService = null;
            role = null;

            id = null;

            if(!userDoc["@id"].IsEmpty) {
                uint id_temp;
                if(!uint.TryParse(userDoc["@id"].Contents, out id_temp))
                    throw new DreamBadRequestException(DekiResources.USER_ID_ATTR_INVALID);
                id = id_temp;
            }

            if(!string.IsNullOrEmpty(authserviceidstr)) {
                uint serviceid;
                if(!uint.TryParse(authserviceidstr, out serviceid))
                    throw new DreamBadRequestException(DekiResources.SERVICE_AUTH_ID_ATTR_INVALID);

                authService = ServiceBL.GetServiceById(serviceid);
                if(authService == null)
                    throw new DreamBadRequestException(string.Format(DekiResources.SERVICE_DOES_NOT_EXIST, serviceid));
            }

            if(!string.IsNullOrEmpty(rolestr)) {
                role = PermissionsBL.GetRoleByName(rolestr);
                if(role == null)
                    throw new DreamBadRequestException(string.Format(DekiResources.ROLE_DOES_NOT_EXIST, rolestr));
            }

            if(!string.IsNullOrEmpty(statusStr)) {
                switch(statusStr.ToLowerInvariant()) {
                case "active":
                    active = true;
                    break;
                case "inactive":
                    active = false;
                    break;
                default:
                    throw new DreamBadRequestException(DekiResources.USER_STATUS_ATTR_INVALID);
                }
            } else {
                active = null;
            }

            if(!string.IsNullOrEmpty(timezone)) {
                if(!timeZoneRegex.Match(timezone).Success) {
                    throw new DreamBadRequestException(DekiResources.INVALID_TIMEZONE_VALUE);
                }
            }

            if(!string.IsNullOrEmpty(language)) {
                string[] validLanguages = DekiContext.Current.Instance.Languages.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                string tempLanguage = language;
                if(!Array.Exists<string>(validLanguages, delegate(string temp) { return StringUtil.EqualsInvariantIgnoreCase(temp, tempLanguage); })) {
                    throw new DreamBadRequestException(DekiResources.INVALID_LANGUAGE_VALUE);
                }
            }
        }
        private static UserBE ReadUserXml(XDoc userDoc, string username, string email, string fullname, ServiceBE authService, RoleBE role, string language, string timezone) {

            UserBE user = new UserBE();

            if(string.IsNullOrEmpty(username))
                throw new DreamBadRequestException(DekiResources.USERNAME_PARAM_INVALID);

            //TODO (MaxM) Consider validation of fullname, email, username

            //Retrieve default auth service for new user if authservice not given
            if(authService == null) {
                authService = ServiceBL.RetrieveLocalAuthService();
            }

            user.Name = username;

            //Default role will be applied if one is not given
            if(role != null)
                user.RoleId = role.ID;

            user.RealName = fullname ?? string.Empty;
            user.ServiceId = authService.Id;
            user.UserActive = true;
            user.Email = email ?? string.Empty;
            user.Language = language;
            user.Timezone = timezone;

            return user;
        }
        private static UserBE UpdateUserFromXml(UserBE userToUpdate, XDoc userDoc, string username, string email, string fullname, ServiceBE authservice, RoleBE role, bool? active, string externalusername, string externalpassword, string language, string timezone, out List<GroupBE> externalGroups) {
            externalGroups = null;
            if(userToUpdate.Name != username && !string.IsNullOrEmpty(username)) {
                if(UserBL.IsAnonymous(userToUpdate)) {
                    throw new DreamBadRequestException(DekiResources.ANONYMOUS_USER_EDIT);
                }
                userToUpdate = RenameUser(userToUpdate, username);
            }

            //Modify a user's authentication service
            if(authservice != null && authservice.Id != userToUpdate.ServiceId) {
                if(UserBL.IsAnonymous(userToUpdate)) {
                    throw new DreamBadRequestException(DekiResources.ANONYMOUS_USER_EDIT);
                }

                if(ServiceBL.IsLocalAuthService(authservice)) {

                    //external to local
                    userToUpdate.ExternalName = null;
                    userToUpdate.ServiceId = authservice.Id;

                } else {

                    //(local or external) to external
                    userToUpdate = ExternalServiceSA.BuildUserFromAuthService(authservice, userToUpdate, userToUpdate.Name, true, externalusername, externalpassword, out externalGroups);
                    if(userToUpdate == null) {
                        throw new DreamInternalErrorException(DekiResources.USER_AUTHSERVICE_CHANGE_FAIL);
                    }

                    //Does the external account already exist?
                    UserBE matchingExternalAccount = DbUtils.CurrentSession.Users_GetByExternalName(userToUpdate.ExternalName, userToUpdate.ServiceId);
                    if(matchingExternalAccount != null) {
                        throw new DreamAbortException(DreamMessage.Conflict(string.Format(DekiResources.USER_EXISTS_WITH_EXTERNAL_NAME, matchingExternalAccount.Name, matchingExternalAccount.ExternalName, matchingExternalAccount.ServiceId)));
                    }
                }
            }

            if(email != null) {
                if(UserBL.IsAnonymous(userToUpdate) && email != userToUpdate.Email) {
                    throw new DreamBadRequestException(DekiResources.ANONYMOUS_USER_EDIT);
                }

                userToUpdate.Email = email;
            }

            if(!string.IsNullOrEmpty(fullname))
                userToUpdate.RealName = fullname;

            if(active != null) {
                if(UserBL.IsAnonymous(userToUpdate) && userToUpdate.UserActive && !active.Value) {
                    throw new DreamBadRequestException(DekiResources.DEACTIVATE_ANONYMOUS_NOT_ALLOWED);
                }

                //throw exception if licensing does not allow activating a user
                if(!userToUpdate.UserActive && active.Value) {
                    LicenseBL.IsUserCreationAllowed(true);
                }
                userToUpdate.UserActive = active.Value;
            }

            if(role != null && role.ID != userToUpdate.RoleId) {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
                userToUpdate.RoleId = role.ID;
            }

            if(language != null) {
                userToUpdate.Language = language;
            }

            if(timezone != null) {
                userToUpdate.Timezone = timezone;
            }

            return userToUpdate;
        }
Exemple #7
0
        private static void ParseGroupXml(XDoc groupDoc, out uint? id, out string name, out ServiceBE authService, out RoleBE role, out UserBE[] userList) {

            name = groupDoc["groupname"].AsText ?? groupDoc["name"].AsText;
            string authserviceidstr = groupDoc["service.authentication/@id"].AsText;
            string rolestr = groupDoc["permissions.group/role"].AsText;
            authService = null;
            role = null;
            id = null;


            if(!groupDoc["@id"].IsEmpty) {
                uint id_temp;
                if(!uint.TryParse(groupDoc["@id"].Contents, out id_temp))
                    throw new GroupIdAttributeInvalidArgumentException();
                id = id_temp;
            }

            if(!string.IsNullOrEmpty(authserviceidstr)) {
                uint serviceid;
                if(!uint.TryParse(authserviceidstr, out serviceid))
                    throw new ServiceAuthIdAttrInvalidArgumentException();

                authService = ServiceBL.GetServiceById(serviceid);
                if(authService == null)
                    throw new ServiceDoesNotExistInvalidArgumentException(serviceid);
            }

            if(!string.IsNullOrEmpty(rolestr)) {
                role = PermissionsBL.GetRoleByName(rolestr);
                if(role == null)
                    throw new RoleDoesNotExistInvalidArgumentException(rolestr);
            } else {
                role = PermissionsBL.RetrieveDefaultRoleForNewAccounts();
            }
            if(!groupDoc["users"].IsEmpty) {
                userList = ReadUserListXml(groupDoc["users"]);
            } else
                userList = new UserBE[] { };
        }
Exemple #8
0
        public static XDoc GetRoleXml(RoleBE role, string relation) {
            XDoc roleXml = null;
            if(role == null)
                roleXml = GetPermissionXml(0, relation);
            else {
                roleXml = GetPermissionXml(role.PermissionFlags, relation);
                roleXml.Start(role.Type.ToString().ToLowerInvariant());
                roleXml.Attr("id", role.ID);
                roleXml.Attr("href", DekiContext.Current.ApiUri.At("site", "roles", role.ID.ToString()));
                roleXml.Value(role.Name);
                roleXml.End();

            }

            return roleXml;
        }
Exemple #9
0
        public static RoleBE PutRole(RoleBE role, DreamMessage request, DreamContext context) {
            if(role == null) {
                string roleName = context.GetParam("roleid");

                //role name is double encoded.
                roleName = XUri.Decode(roleName);
                if(!roleName.StartsWith("=") || roleName.Substring(1).Length == 0)
                    throw new PermissionsInvalidRoleNameInvalidArgumentException();
                roleName = roleName.Substring(1);
                role = new RoleBE();
                role.Name = roleName;
                role.Type = RoleType.ROLE;
            }

            List<Permissions> operations = PermissionListFromString(request.ToDocument()["operations"].AsText);
            role.PermissionFlags = MaskFromPermissionList(operations);
            role.CreatorUserId = DekiContext.Current.User.ID;
            role.TimeStamp = DateTime.UtcNow;

            uint roleId;
            if(null == GetRoleByName(role.Name)) {
                roleId = DbUtils.CurrentSession.RolesRestrictions_InsertRole(role);
                if(roleId == 0) {
                    role = null;
                } else {
                    role.ID = roleId;
                }
            } else {
                DbUtils.CurrentSession.RolesRestrictions_UpdateRole(role);
            }

            // Clear output caching due to role change
            if(DekiContext.Current.Instance.CacheAnonymousOutput) {
                DekiContext.Current.Deki.EmptyResponseCacheInternal();
            }
            return role;
        }
Exemple #10
0
        /// <summary>
        /// Main workflow of applying permissions to pages
        /// </summary>
        /// <param name="targetPage">Page to apply permissions to</param>
        /// <param name="cascade">Whether or not to apply permissions to child pages</param>
        /// <param name="userEffectiveRights">permission mask of user (user + group operations) independant of a page</param>
        /// <param name="proposedGrantSet">Used only for PUT cascade=absolute</param>
        /// <param name="proposedAddedGrants">Grants to add (if they dont already exist)</param>
        /// <param name="proposedRemovedGrants">Grants to remove (if they exist)</param>
        /// <param name="currentGrants">Optional current set of grants for targetPage. This is provided as an optimization to eliminate a db hit</param>
        /// <param name="proposedRestriction">Optional restriction to be applied for page (and child pages)</param>
        /// <param name="atStartPage">Always true when calling from outside this method. Used for recursion to not throw exceptions for errors on child pages</param>
        private static void ApplyPermissionChange(PageBE targetPage, bool cascade, ulong userEffectiveRights, IList<GrantBE> proposedGrantSet, IList<GrantBE> proposedAddedGrants, IList<GrantBE> proposedRemovedGrants, IList<GrantBE> currentGrants, RoleBE proposedRestriction, bool atStartPage) {

            // TODO (steveb): validate which parameters are null and which are not (i.e. proposedAddedGrants, proposedRemovedGrants, proposedGrantSet)

            if(!targetPage.Title.IsEditable) {
                throw new PermissionsNotAllowedForbiddenException(targetPage.Title.Path, targetPage.Title.Namespace);
            }

            UserBE currentUser = DekiContext.Current.User;
            bool arePermissionsOkForPage = true;

            // Make sure granter has access to what is being granted.
            // remove already existing grants from new grant list.
            if(currentGrants == null) {
                currentGrants = DbUtils.CurrentSession.Grants_GetByPage((uint)targetPage.ID);
            }

            //proposedGrantSet will be null for descendant pages as well as for setting permissions via POST in a relative fashion
            if(proposedGrantSet != null) {
                CompareGrantSets(currentGrants, proposedGrantSet, out proposedAddedGrants, out proposedRemovedGrants);
            }

            AddRequesterToAddedGrantList(currentGrants, proposedAddedGrants, targetPage);

            try {

                //Determine the grant perm mask for the current user by using either the proposedGrantSet for the initial page
                //Or by computing it for descendant pages that dont have a proposedGrantSet passed in
                ulong proposedPageGrantMaskForUser;
                if(proposedGrantSet != null) {
                    proposedPageGrantMaskForUser = SumGrantPermissions(proposedGrantSet, currentUser);
                } else {
                    List<GrantBE> proposedGrantSetForCurrentPage = ApplyGrantMerge(currentGrants, proposedAddedGrants, proposedRemovedGrants);
                    proposedPageGrantMaskForUser = SumGrantPermissions(proposedGrantSetForCurrentPage, currentUser);
                }

                //Ensure user has the combined permissions granted to the page
                ulong addedGrantMask = SumGrantPermissions(proposedAddedGrants, null);
                CheckUserAllowed(currentUser, targetPage, (Permissions)addedGrantMask);

                //Determine the restriction mask to use. 
                ulong restrictionFlag = ulong.MaxValue;
                RoleBE targetPageRestriction = GetRestrictionById(targetPage.RestrictionID);
                if(proposedRestriction == null && targetPageRestriction != null) {
                    restrictionFlag = targetPageRestriction.PermissionFlags;
                } else if(proposedRestriction != null) {
                    restrictionFlag = proposedRestriction.PermissionFlags;
                }

                //Ensure the granter is not locking himself out.
                //Calculate the rights the granter would have after the grants are saved
                ulong newEffectivePageRights = CalculateEffectivePageRights(new PermissionStruct(userEffectiveRights, restrictionFlag, proposedPageGrantMaskForUser));

                //If granter no longer has "CHANGEPERMISSIONS" access after grants, the user is locking self out.
                if(!IsActionAllowed(newEffectivePageRights, false, false, false, Permissions.CHANGEPERMISSIONS)) {
                    throw new PermissionsUserWouldBeLockedOutOfPageInvalidOperationException();
                }

            } catch(MindTouchException) { // Validation/permission related exceptions
                arePermissionsOkForPage = false;
                if(atStartPage) //Swallow validation exceptions on 
                    throw;
            } catch(DreamAbortException) { // Validation/permission related exceptions

                // TODO (arnec): remove this once all usage of Dream exceptions is purged from Deki logic
                arePermissionsOkForPage = false;
                if(atStartPage) //Swallow validation exceptions on 
                    throw;
            }

            if(arePermissionsOkForPage) {
                //All validation steps succeeded: Apply grants/restriction to page based on delta of current grants and proposed additions/removals

                List<GrantBE> grantsToRemove = IntersectGrantSets(currentGrants, proposedRemovedGrants);
                List<GrantBE> grantsToAdd = GetExtraGrantsInEndingSet(currentGrants, proposedAddedGrants);

                if(grantsToRemove.Count > 0) {

                    // Contstruct recent change description
                    var deleteGrantsDescription = new DekiResourceBuilder();
                    List<uint> userGrantIds = new List<uint>();
                    List<uint> groupGrantIds = new List<uint>();
                    foreach(GrantBE g in grantsToRemove) {
                        if(!deleteGrantsDescription.IsEmpty) {
                            deleteGrantsDescription.Append(", ");
                        }
                        if(g.Type == GrantType.USER) {
                            userGrantIds.Add(g.Id);
                            UserBE user = UserBL.GetUserById(g.UserId);
                            if(user != null) {
                                deleteGrantsDescription.Append(DekiResources.GRANT_REMOVED(user.Name, g.Role.Name.ToLowerInvariant()));
                            }
                        } else if(g.Type == GrantType.GROUP) {
                            groupGrantIds.Add(g.Id);
                            GroupBE group = GroupBL.GetGroupById(g.GroupId);
                            if(group != null) {
                                deleteGrantsDescription.Append(DekiResources.GRANT_REMOVED(group.Name, g.Role.Name.ToLowerInvariant()));
                            }
                        }
                    }
                    DbUtils.CurrentSession.Grants_Delete(userGrantIds, groupGrantIds);
                    RecentChangeBL.AddGrantsRemovedRecentChange(DateTime.UtcNow, targetPage, DekiContext.Current.User, deleteGrantsDescription);
                }

                if(grantsToAdd.Count > 0) {

                    // Contstruct recent change description
                    Dictionary<uint, PageBE> uniquePages = new Dictionary<uint, PageBE>();
                    var addGrantsDescription = new DekiResourceBuilder();
                    foreach(GrantBE grant in grantsToAdd) {
                        grant.CreatorUserId = DekiContext.Current.User.ID;
                        if(!addGrantsDescription.IsEmpty) {
                            addGrantsDescription.Append(", ");
                        }
                        if(grant.Type == GrantType.USER) {
                            UserBE user = UserBL.GetUserById(grant.UserId);
                            if(user != null) {
                                addGrantsDescription.Append(DekiResources.GRANT_ADDED(user.Name, grant.Role.Name));
                            }
                        } else if(grant.Type == GrantType.GROUP) {
                            GroupBE group = GroupBL.GetGroupById(grant.GroupId);
                            if(group != null) {
                                addGrantsDescription.Append(DekiResources.GRANT_ADDED(group.Name, grant.Role.Name));
                            }
                        }
                        uniquePages[grant.PageId] = PageBL.GetPageById(grant.PageId);
                    }
                    foreach(GrantBE grantToAdd in grantsToAdd) {
                        DbUtils.CurrentSession.Grants_Insert(grantToAdd);
                    }
                    foreach(PageBE p in uniquePages.Values) {
                        RecentChangeBL.AddGrantsAddedRecentChange(DateTime.UtcNow, p, DekiContext.Current.User, addGrantsDescription);
                    }
                }

                targetPage.Touched = DateTime.UtcNow;

                if(proposedRestriction != null && targetPage.RestrictionID != proposedRestriction.ID) {
                    targetPage.RestrictionID = proposedRestriction.ID;
                    DbUtils.CurrentSession.Pages_Update(targetPage);

                    // NOTE (maxm): Restriction change without grant changes will not perform cache invalidation on permissions. Force the invalidation (if any) here.
                    if(ArrayUtil.IsNullOrEmpty(grantsToAdd) && ArrayUtil.IsNullOrEmpty(grantsToRemove)) {
                        DbUtils.CurrentSession.Grants_Delete(new uint[] { }, new uint[] { });
                    }

                    RecentChangeBL.AddRestrictionUpdatedChange(targetPage.Touched, targetPage, currentUser, DekiResources.RESTRICTION_CHANGED(proposedRestriction.Name));
                } else {
                    PageBL.Touch(targetPage, DateTime.UtcNow);
                }
            }

            //Cascade into child pages only if current page permissions applied
            if(cascade) {
                if(proposedGrantSet != null) {
                    proposedAddedGrants = proposedRemovedGrants = null;
                }

                ICollection<PageBE> childPages = PageBL.GetChildren(targetPage, true);
                foreach(PageBE p in childPages) {
                    ResetGrants(proposedGrantSet, p);
                    ResetGrants(proposedAddedGrants, p);
                    ResetGrants(proposedRemovedGrants, p);

                    ApplyPermissionChange(p, true, userEffectiveRights, proposedGrantSet, proposedAddedGrants, proposedRemovedGrants, null, proposedRestriction, false);
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// This applies permissions in a add/remove approach synonymous as used by POST.
        /// </summary>
        /// <param name="targetPage">Page to apply permissions to</param>
        /// <param name="restriction">Optional restriction mask to apply to page (and optionally to child pages)</param>
        /// <param name="grantsAdded"></param>
        /// <param name="grantsRemoved"></param>
        /// <param name="cascade">Whether or not to apply permissions to child pages</param>
        /// <remarks>
        /// This preserves existing page permissions by only adding and removing proposed grants
        /// </remarks>
        public static void ApplyDeltaPagePermissions(PageBE targetPage, RoleBE restriction, List<GrantBE> grantsAdded, List<GrantBE> grantsRemoved, bool cascade) {

            // Make sure users and groups described in grants exist.
            // this populates user/group object within the grant.
            List<GrantBE> allGrants = new List<GrantBE>(grantsAdded);
            allGrants.AddRange(grantsRemoved);
            VerifyValidUsersAndGroups(allGrants);

            // Ensure a duplicate grant isn't given for the same role multiple times to a user/grant
            HashGrantsByTypeGranteeIdRoleId(grantsAdded);
            HashGrantsByTypeGranteeIdRoleId(grantsRemoved);

            ulong userEffectiveRights = (ulong)GetUserPermissions(DekiContext.Current.User);
            ApplyPermissionChange(targetPage, cascade, userEffectiveRights, null, grantsAdded, grantsRemoved, null, restriction, true);
        }
Exemple #12
0
        private static void ParseUserXml(XDoc userDoc, out uint? id, out string username, out string email, out string fullname, out ServiceBE authService, out RoleBE role, out bool? active, out string language, out string timezone) {

            username = userDoc["username"].AsText;
            email = userDoc["email"].AsText;
            fullname = userDoc["fullname"].AsText;
            language = userDoc["language"].AsText;
            timezone = userDoc["timezone"].AsText;
            string authserviceidstr = userDoc["service.authentication/@id"].AsText;
            string rolestr = userDoc["permissions.user/role"].AsText;
            string statusStr = userDoc["status"].AsText;
            authService = null;
            role = null;

            id = null;

            if(!userDoc["@id"].IsEmpty) {
                uint id_temp;
                if(!uint.TryParse(userDoc["@id"].Contents, out id_temp)) {
                    throw new UserIdAttrInvalidArgumentException();
                }
                id = id_temp;
            }

            if(!string.IsNullOrEmpty(authserviceidstr)) {
                uint serviceid;
                if(!uint.TryParse(authserviceidstr, out serviceid))
                    throw new ServiceAuthIdAttrInvalidArgumentException();

                authService = ServiceBL.GetServiceById(serviceid);
                if(authService == null)
                    throw new ServiceDoesNotExistInvalidArgumentException(serviceid);
            }

            if(!string.IsNullOrEmpty(rolestr)) {
                role = PermissionsBL.GetRoleByName(rolestr);
                if(role == null)
                    throw new RoleDoesNotExistInvalidArgumentException(rolestr);
            }

            if(!string.IsNullOrEmpty(statusStr)) {
                switch(statusStr.ToLowerInvariant()) {
                case "active":
                    active = true;
                    break;
                case "inactive":
                    active = false;
                    break;
                default:
                    throw new UserStatusAttrInvalidArgumentException();
                }
            } else {
                active = null;
            }

            if(!string.IsNullOrEmpty(timezone)) {
                if(!timeZoneRegex.Match(timezone).Success) {
                    throw new UserTimezoneInvalidArgumentException();
                }
            }

            if(!string.IsNullOrEmpty(language)) {
                string[] validLanguages = DekiContext.Current.Instance.Languages.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                string tempLanguage = language;
                if(!Array.Exists(validLanguages, delegate(string temp) { return temp.EqualsInvariantIgnoreCase(tempLanguage); })) {
                    throw new UserInvalidLanguageException();
                }
            }
        }
Exemple #13
0
        private static UserBE UpdateUserFromXml(UserBE userToUpdate, XDoc userDoc, string username, string email, string fullname, ServiceBE authservice, RoleBE role, bool? active, string externalusername, string externalpassword, string language, string timezone, out List<GroupBE> externalGroups) {
            externalGroups = null;
            if(userToUpdate.Name != username && !string.IsNullOrEmpty(username)) {
                if(UserBL.IsAnonymous(userToUpdate)) {
                    throw new UserAnonymousEditInvalidOperationException();
                }
                userToUpdate = RenameUser(userToUpdate, username, fullname ?? userToUpdate.RealName);
            }

            //Modify a user's authentication service
            if(authservice != null && authservice.Id != userToUpdate.ServiceId) {
                if(UserBL.IsAnonymous(userToUpdate)) {
                    throw new UserAnonymousEditInvalidOperationException();
                }

                if(ServiceBL.IsLocalAuthService(authservice)) {

                    //external to local
                    userToUpdate.ExternalName = null;
                    userToUpdate.ServiceId = authservice.Id;

                } else {

                    //(local or external) to external
                    userToUpdate = ExternalServiceSA.BuildUserFromAuthService(authservice, userToUpdate, userToUpdate.Name, true, externalusername, externalpassword, out externalGroups);
                    if(userToUpdate == null) {
                        throw new UserAuthChangeFatalException();
                    }

                    //Does the external account already exist?
                    UserBE matchingExternalAccount = DbUtils.CurrentSession.Users_GetByExternalName(userToUpdate.ExternalName, userToUpdate.ServiceId);
                    if(matchingExternalAccount != null) {
                        throw new ExternalUserExistsConflictException(matchingExternalAccount.Name, matchingExternalAccount.ExternalName, matchingExternalAccount.ServiceId);
                    }
                }
            }

            if(email != null) {
                if(UserBL.IsAnonymous(userToUpdate) && email != userToUpdate.Email) {
                    throw new UserAnonymousEditInvalidOperationException();
                }

                userToUpdate.Email = email;
            }

            if(!string.IsNullOrEmpty(fullname))
                userToUpdate.RealName = fullname;

            if(active != null) {
                
                // disabling user
                if(userToUpdate.UserActive && !active.Value) {

                    // cannot disable anonymous user
                    if(UserBL.IsAnonymous(userToUpdate)) {
                        throw new UserAnonymousDeactivationInvalidOperationException();
                    }

                    // cannot disable owner
                    if(DekiContext.Current.LicenseManager.GetSiteOwnerUserId().GetValueOrDefault(0) == userToUpdate.ID) {
                        throw new UserOwnerDeactivationConflict();
                    }
                }

                //throw exception if licensing does not allow activating a user
                if(!userToUpdate.UserActive && active.Value) {
                    DekiContext.Current.LicenseManager.IsUserCreationAllowed(true);
                }

                userToUpdate.UserActive = active.Value;
            }

            if(role != null && role.ID != userToUpdate.RoleId) {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
                userToUpdate.RoleId = role.ID;
            }

            if(language != null) {
                userToUpdate.Language = language;
            }

            if(timezone != null) {
                userToUpdate.Timezone = timezone;
            }

            return userToUpdate;
        }
        private static void ParseGroupXml(XDoc groupDoc, out uint? id, out string name, out ServiceBE authService, out RoleBE role, out UserBE[] userList) {

            name = groupDoc["groupname"].AsText ?? groupDoc["name"].AsText;
            string authserviceidstr = groupDoc["service.authentication/@id"].AsText;
            string rolestr = groupDoc["permissions.group/role"].AsText;
            authService = null;
            role = null;
            id = null;


            if (!groupDoc["@id"].IsEmpty) {
                uint id_temp;
                if (!uint.TryParse(groupDoc["@id"].Contents, out id_temp))
                    throw new DreamBadRequestException(DekiResources.GROUP_ID_ATTR_INVALID);
                id = id_temp;
            }

            if (!string.IsNullOrEmpty(authserviceidstr)) {
                uint serviceid;
                if (!uint.TryParse(authserviceidstr, out serviceid))
                    throw new DreamBadRequestException(DekiResources.SERVICE_AUTH_ID_ATTR_INVALID);

                authService = ServiceBL.GetServiceById(serviceid);
                if (authService == null)
                    throw new DreamBadRequestException(string.Format(DekiResources.SERVICE_DOES_NOT_EXIST, serviceid));
            }

            if (!string.IsNullOrEmpty(rolestr)) {
                role = PermissionsBL.GetRoleByName(rolestr);
                if (role == null)
                    throw new DreamBadRequestException(string.Format(DekiResources.ROLE_DOES_NOT_EXIST, rolestr));
            } else {
                role = PermissionsBL.RetrieveDefaultRoleForNewAccounts();
            }
            if (!groupDoc["users"].IsEmpty) {
                userList = ReadUserListXml(groupDoc["users"]);
            } else
                userList = new UserBE[] { };
        }
 public void RolesRestrictions_UpdateRole(RoleBE role) {
     Stopwatch sw = Stopwatch.StartNew();
     _next.RolesRestrictions_UpdateRole(role);
     LogQuery(CATEGORY_ROLES_RESTRICTIONS, "RolesRestrictions_UpdateRole", sw, "role", role);
 }
 public uint RolesRestrictions_InsertRole(RoleBE role) {
     Stopwatch sw = Stopwatch.StartNew();
     var ret = _next.RolesRestrictions_InsertRole(role);
     LogQuery(CATEGORY_ROLES_RESTRICTIONS, "RolesRestrictions_InsertRole", sw, "role", role);
     return ret;
 }