⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 userprovidermanager.cs

📁 解压即可使用
💻 CS
字号:
//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Security.Cryptography;
using CommunityServer;
using CommunityServer.Components;
using System.Web;
using System.Web.Mail;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using CommunityServer.Configuration;
using Microsoft.ScalableHosting.Configuration;
using Microsoft.ScalableHosting.Security;
using Microsoft.ScalableHosting.Profile;

namespace CommunityServer.Data
{
    /// <summary>
    /// Summary description for UserManager.
    /// </summary>
    public class UserProviderManager
    {
        private User _currentUser = null;
        private CreateUserStatus _status = CreateUserStatus.UnknownFailure;

        public UserProviderManager(User user)
        {
            _currentUser = user;	
        }

        public User CurrentUser
        {
            get{return _currentUser;}
        }

        public CreateUserStatus Status
        {
            get{return _status;}
        }

        public void Create()
        {
            //will throw an exception if either fail
            this.ValidateNewUserExists();
            MembershipUser mu = this.CreateMembershipUser();

            //Lets update our user's details
            CurrentUser.RefreshMembershipUser(mu);
            ProfileBase pb = ProfileBase.Create(CurrentUser.Username,true);
            CurrentUser.RefreshUserProfile(new Profile(pb));
        }

        public void Update()
        {

            try 
            {
                Membership.UpdateUser(CurrentUser.Member);
            }
            catch (Exception ex) 
            {
                // Check to see if the MemberRole component threw a duplicate email exception.
                //  If so replace the incorrect message it threw with a more useful CS exception
                // NOTE: There is a bug in MemberRole whereas the duplicate email exception message is "The password-answer supplied is invalid"
                //       This due to a typo in the Microsoft.ScalableHosting.Security.SqlMembershipProvider.GetExceptionText method, which 
                //       returns a the wrong message for a status of 7.
                if (ex.Source.ToLower() == "memberrole" && ex.Message.ToLower() == "the password-answer supplied is invalid.")
                    throw new CSException(CreateUserStatus.DuplicateEmailAddress, "Duplicate Email Address", ex);

                throw;
            }


            _status = CreateUserStatus.Updated;
        }

        public void Delete()
        {
            Membership.DeleteUser(CurrentUser.Username,true);
            _status = CreateUserStatus.Deleted;
        }

        #region ValidateNewUserExists
        /// <summary>
        /// Validates the User does not alrady exist
        /// </summary>
        protected virtual void ValidateNewUserExists()
        {
            if(Membership.GetUser(CurrentUser.Username) != null)
            {
                throw new CSException(CreateUserStatus.DuplicateUsername);
            }
        }
        #endregion

        #region CreateMembershipUser
        /// <summary>
        /// Creates a new Membership user based on the this.CurrentUser value
        /// </summary>
        /// <returns></returns>
        protected virtual MembershipUser CreateMembershipUser()
        {
            string username = CurrentUser.Username;
            string password = CurrentUser.Password;
            string email = CurrentUser.Email;
            string question = CurrentUser.PasswordQuestion;
			string answer = CurrentUser.PasswordAnswer;
            UserAccountStatus status = CurrentUser.AccountStatus;

            MembershipUser member = null;

            //how much data do have / which method call should we use?
            if(email != null && question != null && answer != null && email.Trim().Length > 0 && question.Trim().Length > 0 && answer.Trim().Length > 0)
            {
                MembershipCreateStatus msc = MembershipCreateStatus.Success;

                member = Membership.CreateUser(username,password,email,question,answer,true,out msc);

                if(msc != MembershipCreateStatus.Success)
                    throw new MembershipCreateUserException(msc);

                SetMemberStatus(msc);
            }
            else if(email != null && email.Trim().Length > 0)
            {
                //only have username/password/email

                    member = Membership.CreateUser(username,password,email);
                    if(member == null)
                    {
                        _status = CreateUserStatus.UnknownFailure;
                    }
                    else
                    {
                        _status = CreateUserStatus.Created;
                    }	 
            }

                //only username/password
            else
            {
                    member = Membership.CreateUser(username,password);
                    if(member == null)
                    {
                        _status = CreateUserStatus.UnknownFailure;
                    }
                    else
                    {
                        _status = CreateUserStatus.Created;
                    }

            }	

            if(_status != CreateUserStatus.Created)
            {
                throw new CSException(_status);
            }
            return member;
        }

        private void SetMemberStatus(MembershipCreateStatus msc)
        {
            switch(msc)
            {
                case MembershipCreateStatus.Success:
                    _status = CreateUserStatus.Created;
                    break;
                case MembershipCreateStatus.DuplicateEmail:
                    _status = CreateUserStatus.DuplicateEmailAddress;
                    break;
                case MembershipCreateStatus.DuplicateUserName:
                    _status = CreateUserStatus.DuplicateUsername;
                    break;
                case MembershipCreateStatus.InvalidPassword:
					_status = CreateUserStatus.InvalidPassword;
					break;
                case MembershipCreateStatus.InvalidQuestion:
                    _status = CreateUserStatus.InvalidQuestionAnswer;
                    break;

                default:
                    _status = CreateUserStatus.UnknownFailure;
                    break;
            }
        }

        #endregion

        internal static void EncodePassword(string rawPassword, out string encodededPassword, out string salt, out int format)
        {
            byte[] sa = new byte[0x10];
            new RNGCryptoServiceProvider().GetBytes(sa);
            salt = Convert.ToBase64String(sa);

            

            //Currpent Provider Instance
            Microsoft.ScalableHosting.Security.MembershipProvider p = Microsoft.ScalableHosting.Security.Membership.Provider;
            format = (int)p.PasswordFormat;

            //We need the Root Membership Provider to invoke it's internally scoped EncodePassword method
            Type baseProviderType = typeof(Microsoft.ScalableHosting.Security.MembershipProvider);
            
            //EncodePassword is an internally scoped method. So we will try to invoke it via reflection
            MethodInfo mi = baseProviderType.GetMethod("EncodePassword", BindingFlags.Public|BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.FlattenHierarchy);

            if(mi != null)
            {
                encodededPassword =  mi.Invoke(p, new object[] {rawPassword,p.PasswordFormat, salt}) as string;
            }
            else
            {
                //Will be null under partial trust. Since Forums 2.0 never ran under partial trust, this should not be an issue
                encodededPassword = null;
            }

            
        }

        internal static bool ValidatePreviousPassword(string hashed, string cleanString, string salt, int format)
        {
            Byte[] clearBytes;
            Byte[] hashedBytes;

            cleanString = cleanString.ToLower().Trim();

            if(!Globals.IsNullorEmpty(salt))
            {
                Encoding encoding = Encoding.GetEncoding( "unicode" );

                //clearBytes = encoding.GetBytes( salt.ToLower().Trim() + cleanString.ToLower().Trim() );
                // fix to not force to lowercase, stronger encryption.
                //
                clearBytes = encoding.GetBytes( salt.ToLower().Trim() + cleanString);

            }
            else
            {
                clearBytes = new UnicodeEncoding().GetBytes(cleanString);
            }

                switch (format) 
                {
                    case 0:
                        return hashed == cleanString;
                    case 2:
                        hashedBytes = ((HashAlgorithm) CryptoConfig.CreateFromName("SHA1")).ComputeHash(clearBytes);
                        return hashed == BitConverter.ToString(hashedBytes);
                    case 1:
                    case 3:
                    default:
                        hashedBytes = ((HashAlgorithm) CryptoConfig.CreateFromName("MD5")).ComputeHash(clearBytes);
                        return hashed ==  BitConverter.ToString(hashedBytes);

                }

            }

    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -