コード例 #1
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static UserBE CreateNewUser(UserBE newUser) {
            if(newUser == null)
                return null;

            //throw exception if licensing does not allow creation of another user
            LicenseBL.IsUserCreationAllowed(true);

            if(newUser.RoleId == 0) {
                RoleBE defaultRole = PermissionsBL.RetrieveDefaultRoleForNewAccounts();
                if(defaultRole != null)
                    newUser.RoleId = defaultRole.ID;
            }

            ValidateUser(newUser);
            newUser.CreateTimestamp = DateTime.UtcNow;
            uint userId = DbUtils.CurrentSession.Users_Insert(newUser);
            if(userId == 0) {
                return null;
            }

            newUser.ID = userId;

            PageBE userHomepage = null;
            try {
                // User homepages are created upon user creation (an attempt to create user homepages may also be done upon login)
                userHomepage = PageBL.CreateUserHomePage(newUser);
            } catch { }

            RecentChangeBL.AddUserCreatedRecentChange(DateTime.UtcNow, userHomepage, DekiContext.Current.User ?? newUser, String.Format(DekiResources.USER_ADDED, newUser.Name));
            DekiContext.Current.Instance.EventSink.UserCreate(DreamContext.Current.StartTime, newUser);


            return newUser;
        }
コード例 #2
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static void UpdateUser(UserBE user) {

            // Note (maxm): The user 'touched' timestamp is updated:
            // * at authentication time
            // * any user object changes (including group membership)
            // It's exposed in the user xml as 'date.lastlogin'
            user.Touched = DateTime.UtcNow;

            ValidateUser(user);
            DbUtils.CurrentSession.Users_Update(user);

            DekiContext.Current.Instance.EventSink.UserUpdate(DreamContext.Current.StartTime, user);
        }
コード例 #3
0
ファイル: BanningBL.cs プロジェクト: heran/DekiWiki
        public static void PerformBanCheck(UserBE user, string[] clientIps, out ulong banMask, out List<string> banReasons) {
            banMask = ulong.MinValue;
            banReasons = new List<string>();
            ulong? cachedBanMask = GetBanMaskFromCache(user.ID, clientIps);
            if(cachedBanMask != null) {

                //TODO MaxM: Ban reasons isn't currently cached (or used)
                banMask = cachedBanMask.Value;
            } else {
                IList<BanBE> bans = DbUtils.CurrentSession.Bans_GetByRequest(user.ID, clientIps.ToList());
                foreach(BanBE ban in bans) {
                    if(!ban.Expires.HasValue || (ban.Expires.Value >= DateTime.UtcNow)) {
                        banMask |= ban.RevokeMask;
                        banReasons.Add(ban.Reason);
                    }
                }
                CacheBanMask(user.ID, clientIps, banMask);
            }
        }
コード例 #4
0
        //--- Methods ---
        public static void SetRating(PageBE page, UserBE user, float? score) {
            ThrowOnInvalidLicense();
            RatingBE currentRating = DbUtils.CurrentSession.Rating_GetUserResourceRating(user.ID, page.ID, ResourceBE.Type.PAGE);

            if(score == null) {
                if(currentRating == null) {

                    // no rating exists currently: noop
                    return;
                }

                // reset a user ratings for a page
                DbUtils.CurrentSession.Rating_ResetUserResourceRating(user.ID, page.ID, ResourceBE.Type.PAGE, DreamContext.Current.StartTime);
            } else {

                // set or update a page rating

                // Valid score is limited to 0 and 1.
                if(score != 0 && score != 1) {
                    throw new Exceptions.InvalidRatingScoreException();
                }

                if(currentRating != null && currentRating.Score == score) {

                    // an equal score already exists: noop
                    return;
                }

                RatingBE rating = new RatingBE();
                rating.ResourceId = page.ID;
                rating.ResourceType = ResourceBE.Type.PAGE;
                rating.ResourceRevision = page.Revision;
                rating.Timestamp = DreamContext.Current.StartTime;
                rating.TimestampReset = null;
                rating.UserId = user.ID;
                rating.Score = score.Value;

                // Set a new rating
                DbUtils.CurrentSession.Rating_Insert(rating);
            }
            // Trigger a notification
            DekiContext.Current.Instance.EventSink.PageRated(DreamContext.Current.StartTime, page, user);
        }
コード例 #5
0
ファイル: UserBE.cs プロジェクト: Minocula/MindTouch_Core
        //--- Methods ---
        public virtual UserBE Copy()
        {
            UserBE user = new UserBE();

            user._NewPassword    = _NewPassword;
            user._Password       = _Password;
            user._Touched        = _Touched;
            user.CreateTimestamp = CreateTimestamp;
            user.Email           = Email;
            user.ExternalName    = ExternalName;
            user.ID          = ID;
            user.Language    = Language;
            user.Name        = Name;
            user.RealName    = RealName;
            user.RoleId      = RoleId;
            user.ServiceId   = ServiceId;
            user.Timezone    = Timezone;
            user.UserActive  = UserActive;
            user.LicenseSeat = LicenseSeat;
            return(user);
        }
コード例 #6
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static UserBE PostUserFromXml(XDoc userDoc, UserBE userToProcess, string accountpassword, string externalusername, string externalpassword) {
            List<GroupBE> externalGroups = null;
            uint? id;
            bool? active;
            string username, fullname, email, language, timezone;
            ServiceBE authService;
            RoleBE role;

            //Parse the standard user XML doc
            ParseUserXml(userDoc, out id, out username, out email, out fullname, out authService, out role, out active, out language, out timezone);

            //new user
            if(userToProcess == null && (id == null || id == 0)) {
                userToProcess = ReadUserXml(userDoc, username, email, fullname, authService, role, language, timezone);

                //External accounts should be confirmed, username normalized, groups retrieved
                if(authService != null && !ServiceBL.IsLocalAuthService(authService)) {

                    if(!string.IsNullOrEmpty(accountpassword))
                        throw new DreamBadRequestException(DekiResources.CANNOT_SET_EXTERNAL_ACCOUNT_PASSWORD);

                    //Only admins can create external accounts for others. Anyone can create their own external account
                    if(externalusername != userToProcess.Name || externalusername == string.Empty)
                        PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

                    //username+password from request query params are used here
                    userToProcess = ExternalServiceSA.BuildUserFromAuthService(authService, userToProcess, username, true, externalusername, externalpassword, out externalGroups);

                    if(userToProcess == null) {
                        throw new DreamAbortException(DreamMessage.NotFound(string.Format(DekiResources.EXTERNAL_USER_NOT_FOUND, username)));
                    }

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

                    //User creation requires admin rights unless the config flag allows it
                    //Anonymous users are not allowed to set role
                    if(!DekiContext.Current.Instance.AllowAnonymousLocalAccountCreation || role != null) {
                        PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
                    }
                }

                //Sanity check for already existing user
                UserBE existingUser = DbUtils.CurrentSession.Users_GetByName(userToProcess.Name);
                if(existingUser != null) {
                    throw new DreamAbortException(DreamMessage.Conflict(string.Format(DekiResources.USER_EXISTS_WITH_ID, existingUser.Name, existingUser.ID)));
                }

                //if (UserDA.RetrieveUserRegistrations(userToProcess.Name)) {
                //    throw new DreamAbortException(DreamMessage.Conflict(string.Format("User '{0}' has been reserved", userToProcess.Name)));
                //}

                userToProcess = UserBL.CreateOrUpdateUser(userToProcess, accountpassword);
                if(null != externalGroups) {
                    UserBL.UpdateUsersGroups(userToProcess, externalGroups.ToArray());
                }
            }

            //update existing user
            else {

                if(userToProcess == null) {

                    //Modifying a user with POST
                    if(id == null || id == 0) {
                        throw new DreamAbortException(DreamMessage.BadRequest(DekiResources.USER_ID_ATTR_INVALID));
                    }

                    userToProcess = UserBL.GetUserById(id.Value);
                    if(userToProcess == null) {
                        throw new DreamAbortException(DreamMessage.NotFound(string.Format(DekiResources.USER_ID_NOT_FOUND, id)));
                    }
                }

                if(!string.IsNullOrEmpty(accountpassword))
                    throw new DreamBadRequestException(DekiResources.USE_PUT_TO_CHANGE_PASSWORDS);

                //Permission check if not modifying self
                if(userToProcess.ID != DekiContext.Current.User.ID)
                    PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

                userToProcess = UpdateUserFromXml(userToProcess, userDoc, username, email, fullname, authService, role, active, externalusername, externalpassword, language, timezone, out externalGroups);
                userToProcess = CreateOrUpdateUser(userToProcess);
                if(null != externalGroups) {
                    UserBL.UpdateUsersGroups(userToProcess, externalGroups.ToArray());
                }

                if(UserBL.IsAnonymous(userToProcess) && DekiContext.Current.Instance.CacheAnonymousOutput) {
                    DekiContext.Current.Deki.EmptyResponseCacheInternal();
                }
            }

            return userToProcess;
        }
コード例 #7
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        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;
        }
コード例 #8
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
 public static XUri GetUriUiHomePage(UserBE user) {
     return XUri.TryParse(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null)));
 }
コード例 #9
0
ファイル: AuthBL.cs プロジェクト: StackableRegiments/metl2011
        public static bool IsValidAuthenticationForLocalUser(UserBE user, string password, out bool altPassword) {
            bool isValid = false;
            altPassword = false;
            string encrypted = AuthBL.EncryptPassword(user, password);
            if(string.CompareOrdinal(encrypted, user.Password) == 0) {

                //On login if a user has a temp password but logs in with original password, clear out the temp password.
                if(!string.IsNullOrEmpty(user.NewPassword)) {
                    user.NewPassword = string.Empty;
                    DbUtils.CurrentSession.Users_Update(user);
                }

                isValid = true;
            } else if(!string.IsNullOrEmpty(user.NewPassword) && string.CompareOrdinal(encrypted, user.NewPassword) == 0) {
                isValid = true;
                altPassword = true;
            }

            return isValid;
        }
コード例 #10
0
ファイル: AuthBL.cs プロジェクト: StackableRegiments/metl2011
        private static string CreateAuthTokenForUser(UserBE user, DateTime timestamp) {
            string ret = string.Empty;
            string tokenContent = string.Format("{0}_{1}", user.ID.ToString(), timestamp.ToUniversalTime().Ticks);

            //Include the users current password as part of validation to invalidate token upon pw change.
            string contentToValidate = string.Format("{0}.{1}.{2}", tokenContent, user.Password ?? string.Empty, DekiContext.Current.Instance.AuthTokenSalt);
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();

            string hash = new Guid(md5.ComputeHash(Encoding.Default.GetBytes(contentToValidate))).ToString("N");
            ret = tokenContent + "_" + hash;
            return ret;
        }
コード例 #11
0
ファイル: AuthBL.cs プロジェクト: StackableRegiments/metl2011
 public static string EncryptPassword(UserBE user, string pwd) {
     string md5Pwd = GetMD5(pwd);
     return GetMD5(user.ID + "-" + md5Pwd);
 }
コード例 #12
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static UserBE CreateOrUpdateUser(UserBE user, string newPassword) {

            if(user.ID > 0) {
                UpdateUser(user);
            } else {
                //TODO consider logic here to confirm that the user does not yet exist.

                user = CreateNewUser(user);
            }

            if(!string.IsNullOrEmpty(newPassword) && ServiceBL.IsLocalAuthService(user.ServiceId)) {
                user = UserBL.SetPassword(user, newPassword, false);
                DekiContext.Current.Instance.EventSink.UserChangePassword(DreamContext.Current.StartTime, user);
            }

            return user;
        }
コード例 #13
0
ファイル: GroupBL.cs プロジェクト: heran/DekiWiki
        private static void ValidateGroupMemberList(ServiceBE groupService, UserBE[] potentialMembers) {

            //Groups belonging to built-in auth service are allowed to contain users from remote services
            if(!ServiceBL.IsLocalAuthService(groupService)) {
                foreach(UserBE u in potentialMembers) {
                    if(u.ServiceId != groupService.Id)
                        throw new GroupMembersRequireSameAuthInvalidOperationException();
                }
            }
        }
コード例 #14
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static XDoc GetUserXml(UserBE user, string relation, bool showPrivateInfo) {
            XDoc userXml = new XDoc(string.IsNullOrEmpty(relation) ? "user" : "user." + relation);
            userXml.Attr("id", user.ID);
            userXml.Attr("href", DekiContext.Current.ApiUri.At("users", user.ID.ToString()));
            userXml.Elem("nick", user.Name);
            userXml.Elem("username", user.Name);
            userXml.Elem("fullname", user.RealName ?? String.Empty);

            // check if we can add the email address
            if(showPrivateInfo) {
                userXml.Elem("email", user.Email);
            } else {
                userXml.Start("email").Attr("hidden", true).End();
            }

            // add gravatar
            if(!IsAnonymous(user) && !string.IsNullOrEmpty(user.Email)) {
                DekiContext context = DekiContext.CurrentOrNull;
                XUri gravatar = new XUri("http://www.gravatar.com/avatar");
                string hash = string.Empty;
                if(context != null) {
                    DekiInstance deki = context.Instance;
                    string secure = context.Instance.GravatarSalt ?? string.Empty;
                    if(!secure.EqualsInvariantIgnoreCase("hidden")) {
                        hash = StringUtil.ComputeHashString(secure + (user.Email ?? string.Empty).Trim().ToLowerInvariant(), System.Text.Encoding.UTF8);
                    }

                    // add size, if any
                    string size = deki.GravatarSize;
                    if(size != null) {
                        gravatar = gravatar.With("s", size);
                    }

                    // add rating, if any
                    string rating = deki.GravatarRating;
                    if(rating != null) {
                        gravatar = gravatar.With("r", rating);
                    }

                    // add default icon, if any
                    string def = deki.GravatarDefault;
                    if(def != null) {
                        gravatar = gravatar.With("d", def);
                    }
                }
                if(!string.IsNullOrEmpty(hash)) {
                    userXml.Elem("hash.email", hash);
                    userXml.Elem("uri.gravatar", gravatar.At(hash + ".png"));
                } else {
                    userXml.Elem("hash.email", string.Empty);
                    userXml.Elem("uri.gravatar", gravatar.At("no-email.png"));
                }
            }
            return userXml;
        }
コード例 #15
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        /// <summary>
        /// Updates the given user in the db with current timestamp
        /// </summary>
        /// <param name="user"></param>
        public static UserBE UpdateUserTimestamp(UserBE user) {
            if(user == null)
                return null;

            //Update user's last logged time column to now if it's more than a minute old.
            if(user.Touched <= DateTime.UtcNow.AddMinutes(-1) && user.UserActive) {

                // Note (maxm): This does not call UserBL.UserUpdate to avoid frequent reindexing.
                user.Touched = DateTime.UtcNow;
                DbUtils.CurrentSession.Users_Update(user);
            }
            return user;
        }
コード例 #16
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
 public static void ValidateUser(UserBE user) {
     if(string.IsNullOrEmpty(user.Name) || user.Name.EndsWith(".", true, CultureInfo.InvariantCulture) || !Title.FromUIUsername(user.Name).IsValid)
         throw new DreamBadRequestException(string.Format(DekiResources.USER_VALIDATION_FAILED, user.Name));
 }
コード例 #17
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static void UpdateUsersGroups(UserBE user, GroupBE[] groups) {
            if(user == null || groups == null)
                return;

            IList<GroupBE> groupsWithIds = DbUtils.CurrentSession.Groups_GetByNames(groups.Select(e => e.Name).ToList());
            DbUtils.CurrentSession.GroupMembers_UpdateGroupsForUser(user.ID, groupsWithIds.Select(e => e.Id).ToList());
            UpdateUser(user);
        }
コード例 #18
0
ファイル: GroupBL.cs プロジェクト: heran/DekiWiki
        private static UserBE[] ReadUserListXml(XDoc usersList) {
            UserBE[] ret = null;
            List<uint> userIds = new List<uint>();
            foreach(XDoc userXml in usersList["user/@id"]) {
                uint? id = userXml.AsUInt;
                if(id == null)
                    throw new UserIdAttrInvalidArgumentException();

                userIds.Add(id.Value);
            }

            if(userIds.Count > 0) {
                Dictionary<uint, UserBE> userHash = DbUtils.CurrentSession.Users_GetByIds(userIds).AsHash(e => e.ID);

                foreach(uint id in userIds) {
                    if(!userHash.ContainsKey(id))
                        throw new GroupCouldNotFindUserInvalidArgumentException(id);
                }

                ret = new List<UserBE>(userHash.Values).ToArray();
            } else {
                ret = new UserBE[] { };
            }

            return ret;
        }
コード例 #19
0
ファイル: GroupBL.cs プロジェクト: heran/DekiWiki
        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[] { };
        }
コード例 #20
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static XDoc GetUserXmlVerbose(UserBE user, string relationAttr, bool showPrivateInfo) {
            XDoc userXml = GetUserXml(user, relationAttr, showPrivateInfo);

            userXml.Elem("date.created", user.CreateTimestamp);

            PageBE homePage = GetHomePage(user);
            if(homePage != null && homePage.ID != 0)
                userXml.Add(PageBL.GetPageXml(homePage, "home"));

            userXml.Start("status").Value(user.UserActive ? "active" : "inactive").End();
            userXml.Start("date.lastlogin").Value(user.Touched).End();
            userXml.Start("language").Value(user.Language).End();
            userXml.Start("timezone").Value(user.Timezone).End();

            ServiceBE authService = ServiceBL.GetServiceById(user.ServiceId);
            if(authService != null)
                userXml.Add(ServiceBL.GetServiceXml(authService, "authentication"));

            //Permissions for the user from user role
            userXml.Add(PermissionsBL.GetRoleXml(PermissionsBL.GetRoleById(user.RoleId), "user"));

            ulong effectivePermissions = PermissionsBL.CalculateEffectiveUserRights(user);

            //Effective permissions for the user from the role + group roles.
            userXml.Add(PermissionsBL.GetPermissionXml(effectivePermissions, "effective"));

            userXml.Start("groups");
            IList<GroupBE> groups = DbUtils.CurrentSession.Groups_GetByUser(user.ID);
            if(null != groups) {
                foreach(GroupBE g in groups) {
                    userXml.Add(GroupBL.GetGroupXmlVerbose(g, null));
                }
            }
            userXml.End();

            //Retrieve properties for current user while providing an href for other users.            
            if(DekiContext.Current.User.ID == user.ID) {

                IList<PropertyBE> props = PropertyBL.Instance.GetResources(user.ID, ResourceBE.Type.USER);
                userXml = PropertyBL.Instance.GetPropertyXml(props, GetUri(user), null, null, userXml);
            } else {
                userXml.Start("properties").Attr("href", GetUri(user).At("properties")).End();
            }

            // TODO Max: get <subscriptions> (watchlist) not implemented
            return userXml;
        }
コード例 #21
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        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;
        }
コード例 #22
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
 public static UserBE CreateOrUpdateUser(UserBE user) {
     return CreateOrUpdateUser(user, null);
 }
コード例 #23
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        public static UserBE SetPassword(UserBE user, string password, bool altPassword) {
            string pwhash = Logic.AuthBL.EncryptPassword(user, password);

            if(altPassword) {

                //Set the alternate password only while keeping the main password untouched.
                user.NewPassword = pwhash;
            } else {

                //Set the main password and clear the alternate password.
                user.Password = pwhash;
                user.NewPassword = string.Empty;
            }

            user.Touched = DateTime.UtcNow;
            DbUtils.CurrentSession.Users_Update(user);
            return user;
        }
コード例 #24
0
 public static IList<CommentBE> RetrieveCommentsForUser(UserBE user) {
     IList<CommentBE> comments = DbUtils.CurrentSession.Comments_GetByUser(user.ID);
     comments = ApplyPermissionFilter(comments);
     return comments;
 }
コード例 #25
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
        private static UserBE RenameUser(UserBE user, string newUserName) {

            //Renaming requires admin rights.
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

            if(!ServiceBL.IsLocalAuthService(user.ServiceId)) {

                //TODO MaxM: allow renaming of external users
                throw new DreamAbortException(DreamMessage.NotImplemented(DekiResources.EXTERNAL_USER_RENAME_NOT_ALLOWED));
            }

            //Check for already existing user with same name
            UserBE existingUser = DbUtils.CurrentSession.Users_GetByName(newUserName);
            if(existingUser != null) {
                throw new DreamAbortException(DreamMessage.Conflict(string.Format(DekiResources.USER_EXISTS_WITH_ID, existingUser.Name, existingUser.ID)));
            }

            PageBE existingTargetUserHomePage = PageBL.GetPageByTitle(Title.FromUIUsername(newUserName));
            if(existingTargetUserHomePage != null && existingTargetUserHomePage.ID != 0) {
                throw new DreamAbortException(DreamMessage.Conflict(DekiResources.USER_RENAME_HOMEPAGE_CONFLICT));
            }

            //Try to move the homepage.
            PageBE userHomePage = GetHomePage(user);
            if(userHomePage != null && userHomePage.ID != 0) {
                PageBL.MovePage(userHomePage, Title.FromUIUsername(newUserName));
            }

            //Rename the user
            user.Name = newUserName;
            UserBL.UpdateUser(user);
            return user;
        }
コード例 #26
0
ファイル: AuthBL.cs プロジェクト: StackableRegiments/metl2011
 public static string CreateAuthTokenForUser(UserBE user) {
     return CreateAuthTokenForUser(user, DateTime.Now);
 }
コード例 #27
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
 public static PageBE GetHomePage(UserBE user) {
     return PageBL.GetPageByTitle(Title.FromUIUsername(user.Name));
 }
コード例 #28
0
ファイル: AuthBL.cs プロジェクト: StackableRegiments/metl2011
 public static bool IsValidAuthenticationForLocalUser(UserBE user, string password) {
     bool altPassword;
     return IsValidAuthenticationForLocalUser(user, password, out altPassword);
 }
コード例 #29
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
 public static bool IsAnonymous(UserBE user) {
     return user.Name == DekiWikiService.ANON_USERNAME;
 }
コード例 #30
0
        public static UserBE BuildUserFromAuthService(ServiceBE serviceInfo, UserBE knownUser, string usernameToBuild, bool bypassAuthentication, string authusername, string password, out List<GroupBE> externalGroups) {
            externalGroups = null;
            if (serviceInfo == null || string.IsNullOrEmpty(usernameToBuild))
                return null;

            //Dont perform external lookup for disabled users
            if (knownUser != null && !knownUser.UserActive)
                return knownUser;

            string errMsg = string.Format(DekiResources.UNABLE_TO_AUTH_WITH_SERVICE, serviceInfo.Type.ToString(), serviceInfo.SID, serviceInfo.Uri);

            if(knownUser != null && !string.IsNullOrEmpty(knownUser.ExternalName)) {
                usernameToBuild = knownUser.ExternalName;
            }

            UserBE ret = null;
            DreamMessage response = null;
            if (serviceInfo.Uri == null)
                throw new DreamAbortException(DreamMessage.InternalError(string.Format(DekiResources.SERVICE_NOT_STARTED, serviceInfo.Type.ToString(), serviceInfo.SID)));
            try {
                Plug dekiExternalAuthPlug;

                //bypassAuthentication is used when you only need user details but not to necessarily authenticate
                if (bypassAuthentication) {

                    //An external auth service's GET: user/{username} does not necessarily require authentication to lookup users but it may. It's up to the service
                    //to decide if anon requests are allowed.
                    dekiExternalAuthPlug = Plug.New(serviceInfo.Uri).At(USER_INFO).At(XUri.Encode(usernameToBuild));
                } else {

                    //Credentials are always needed for GET: authenticate. The user details of the auth'd user is returned with same format as GET: user/{username}
                    dekiExternalAuthPlug = Plug.New(serviceInfo.Uri).At(AUTHENTICATE_PATH);
                }

                //Always include credentials with the request if they're supplied
                if (!string.IsNullOrEmpty(authusername)) {
                    dekiExternalAuthPlug = dekiExternalAuthPlug.WithCredentials(authusername, password ?? string.Empty);
                }

                response = dekiExternalAuthPlug.GetAsync().Wait();
            }
            catch (Exception x) {
                throw new DreamResponseException(DreamMessage.InternalError(x), errMsg);
            }

            if (response.IsSuccessful) {
                XDoc userXml = response.ToDocument();

                if (userXml == null || userXml.IsEmpty) {
                    throw new DreamInternalErrorException(string.Format("Empty or not well-formed XML returned from remote auth service: " + userXml.ToPrettyString()));
                }

                string nameFromAuthProvider = userXml["@name"].Contents;
                if (!StringUtil.EqualsInvariantIgnoreCase(nameFromAuthProvider, usernameToBuild)) {
                    throw new DreamInternalErrorException(string.Format(DekiResources.UNEXPECTED_EXTERNAL_USERNAME, userXml["@name"].AsText, usernameToBuild));
                }

                if (knownUser != null)
                    ret = knownUser;
                else
                    ret = new UserBE();

                ret.Email = string.IsNullOrEmpty(userXml["email"].AsText) ? (ret.Email ?? string.Empty) : userXml["email"].AsText;
                
                //Build the realname (exposed as 'fullname' in user xml) by saving it as '{firstname} {lastname}'
                string externalFirstName = userXml["firstname"].AsText ?? string.Empty;
                string externalLastName = userXml["lastname"].AsText ?? string.Empty;
                string separator = externalLastName.Length > 0 && externalFirstName.Length > 0 ? ", " : string.Empty;
                
                // NOTE (maxm): Fullname sync is disabled for now. Refer to bug 7855
#if !DISABLE_REAL_NAME_SYNCHRONIZATION
                ret.RealName = string.Format("{0}{1}{2}", externalLastName, separator, externalFirstName);
#endif

                ret.ServiceId = serviceInfo.Id;
                ret.Touched = DateTime.UtcNow;

                ret.ExternalName = string.IsNullOrEmpty(ret.ExternalName) ? nameFromAuthProvider : ret.ExternalName;
                ret.Name = string.IsNullOrEmpty(ret.Name) ? nameFromAuthProvider : ret.Name;

                //For new users, the name must be normalized and unique
                if (ret.ID == 0) {

                    string nameFromExternalName = string.Empty;

                    //Allow using a displayname from an external provider only for new accounts
                    if (!userXml["@displayname"].IsEmpty) {
                        nameFromExternalName = userXml["@displayname"].AsText;   
                    }
                    else {
                        nameFromExternalName = ret.ExternalName;
                    }

                    ret.Name = UserBL.NormalizeExternalNameToWikiUsername(nameFromExternalName);    
                }

                //Build group objects out of the user's group membership list
                externalGroups = new List<GroupBE>();
                IList<GroupBE> userGroups = DbUtils.CurrentSession.Groups_GetByUser(ret.ID);

                //Preserve local groups for existing users
                if (ret.ID != 0 && userGroups != null) {
                    foreach (GroupBE g in userGroups) {
                        if (ServiceBL.IsLocalAuthService(g.ServiceId)) {
                            externalGroups.Add(g);
                        }
                    }
                }

                foreach (XDoc group in userXml["groups/group"]) {
                    GroupBE g = new GroupBE();
                    g.Name = group["@name"].AsText;
                    g.ServiceId = serviceInfo.Id;
                    if (!string.IsNullOrEmpty(g.Name))
                        externalGroups.Add(g);
                }
            }
            else {
                switch (response.Status) {
                    case DreamStatus.Unauthorized:
                        if (bypassAuthentication) {
                            DekiContext.Current.Instance.Log.Warn(string.Format("Attempted to lookup user info on auth provider '{0}' but failed since it required credentials", serviceInfo.Id));
                        }

                        throw new DreamAbortException(DreamMessage.AccessDenied(DekiWikiService.AUTHREALM, string.Format(DekiResources.AUTHENTICATION_FAILED_FOR, serviceInfo.Description)));
                    case DreamStatus.InternalError:

                    case DreamStatus.Forbidden:
                    default:
                        throw new DreamAbortException(response, errMsg);
                }
            }
            
            return ret;
        }
コード例 #31
0
ファイル: UserBL.cs プロジェクト: StackableRegiments/metl2011
 public static XUri GetUri(UserBE user) {
     return DekiContext.Current.ApiUri.At("users", user.ID.ToString());
 }