/SystemWebMembershipProxyProvider.cs
C# | 420 lines | 264 code | 68 blank | 88 comment | 65 complexity | 438807322937247dd7f17335489a9438 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Resources;
- using System.Text;
- using System.Web;
- using System.Web.Profile;
- using System.Web.Security;
- using System.Web.UI;
- using ScrewTurn.Wiki.PluginFramework;
-
- namespace Db4objects.ScrewTurnWiki.SystemMembership {
- public class SystemWebMembershipProxyProvider : IUsersStorageProviderV30 {
- static readonly ComponentInformation info;
- static readonly string helpHtml;
-
- static SystemWebMembershipProxyProvider() {
- var thisType = typeof(SystemWebMembershipProxyProvider);
- info = new ComponentInformation("System.Web.Membership Proxying User Provider",
- "Versant",
- thisType.Assembly.GetName().Version.ToString(),
- "http://www.versant.com",
- null);
-
- //var resources = new ResourceManager(thisType);
- //helpHtml = resources.GetString("HtmlHelp.htm");
- //thisType, "HtmlHelp.htm"
- using (var reader = new StreamReader(thisType.Assembly.GetManifestResourceStream("Db4objects.ScrewTurnWiki.SystemMembership.HelpHtml.htm"))) {
- helpHtml = reader.ReadToEnd();
- }
- }
-
- #region IProviderV30 Members
- /// <summary>
- /// Initializes the Storage Provider
- /// </summary>
- /// <param name="host"></param>
- /// <param name="config">configuration data, if any</param>
- public void Init(IHostV30 host, string config) {
- if (host == null) throw new ArgumentNullException("host");
- if (config == null) throw new ArgumentNullException("config");
-
- var membershipProvider = Membership.Provider;
- if (membershipProvider.RequiresQuestionAndAnswer)
- throw new InvalidConfigurationException(this.Information.Name + " does not support the RequiresQuestionAndAnswer option on the current Membership Provider.");
-
- // For UserInfo
- VerifyProfileField("DisplayName");
- // For User Profile
- VerifyProfileField("Culture");
- VerifyProfileField("Timezone");
- // For Email Notifications
- VerifyProfileField("PageChanges");
- VerifyProfileField("DiscussionMessages");
- VerifyProfileField("NamespacePageChanges");
- VerifyProfileField("NamespaceDiscussionMessages");
- }
-
- private void VerifyProfileField(string profileFieldName) {
- var profileProperties = ProfileBase.Properties;
- var profileProperty = profileProperties[profileFieldName];
- if (profileProperty == null)
- throw new InvalidConfigurationException(this.Information.Name + " requires a '" + profileFieldName + "' profile field defined in the current Profile Provider.");
- if (profileProperty.PropertyType != typeof(string))
- throw new InvalidConfigurationException(this.Information.Name + " requires that the '" + profileFieldName + "' profile field is configured with type=\"String\".");
- if (profileProperty.IsReadOnly)
- throw new InvalidConfigurationException(this.Information.Name + " requires that the '" + profileFieldName + "' profile field is configured with readOnly=\"true\".");
- //if (!(bool)profileProperty.Attributes["AllowAnonymous"])
- // throw new InvalidConfigurationException(this.Information.Name + " requires that the '" + profileFieldName + "' profile field is configured with allowAnonymous=\"true\".");
- }
-
- /// <summary>
- /// Gets the Information about the Provider.
- /// </summary>
- public ComponentInformation Information {
- get { return info; }
- }
-
- //cleanup/disconnect
- //not guaranteed to ever be called.
- public void Shutdown() {}
-
- /// <summary>
- /// Gets a brief summary of the configuration string format.
- /// null if no configuration is needed
- /// </summary>
- public string ConfigHelpHtml {
- get {
- return helpHtml;
- }
- }
- #endregion
-
- public bool UserAccountsReadOnly {
- get { return false; }
- }
-
- public bool UserGroupsReadOnly {
- get { return false; }
- }
-
- public bool UsersDataReadOnly {
- get { return false; }
- }
-
- /// <summary>
- /// Gets a value indicating whether group membership is read-only.
- /// </summary>
- /// <remarks>
- /// If UserAccountsReadOnly is false, then this property must also be false.
- /// If this property is true, the provider should return membership data compatible with default user groups.
- /// </remarks>
- public bool GroupMembershipReadOnly {
- get { return false; }
- }
-
- #region Users
- /// <summary>
- /// Adds a new user to the system.
- /// </summary>
- /// <param name="displayName">name to display for the user, can be null</param>
- /// <param name="active">is the account active</param>
- /// <param name="created">account creation datetime</param>
- /// <returns></returns>
- public UserInfo AddUser(string username, string displayName, string password, string email, bool active, DateTime created) {
- if(String.IsNullOrEmpty(username))
- throw new ArgumentNullException("username");
- if (String.IsNullOrEmpty(password))
- throw new ArgumentNullException("password");
- if(String.IsNullOrEmpty(email))
- throw new ArgumentNullException("email");
-
- MembershipCreateStatus createStatus;
- var membershipUser = Membership.CreateUser(username, password, email, null, null, active, out createStatus);
-
- switch(createStatus){
- case MembershipCreateStatus.DuplicateEmail:
- case MembershipCreateStatus.DuplicateProviderUserKey:
- case MembershipCreateStatus.DuplicateUserName:
- case MembershipCreateStatus.UserRejected:
- return null;
- }
-
- var profile = ProfileBase.Create(membershipUser.UserName);
- profile["DisplayName"] = displayName;
- profile.Save();
-
- return ToUserInfo(membershipUser);
- }
-
- /// <summary>
- /// get a user account
- /// </summary>
- /// <param name="username"></param>
- /// <returns>null if no matching user was found</returns>
- public UserInfo GetUser(string username) {
- if (String.IsNullOrEmpty(username)) throw new ArgumentNullException("username");
-
- var membershipUser = Membership.GetUser(username);
- return ToUserInfo(membershipUser);
- }
-
- /// <summary>
- /// get a user account
- /// </summary>
- /// <param name="email"></param>
- /// <returns>null if no matching user was found</returns>
- public UserInfo GetUserByEmail(string email) {
- if (String.IsNullOrEmpty(email)) throw new ArgumentNullException("email");
-
- var users = Membership.FindUsersByEmail(email).OfType<MembershipUser>();
- return ToUserInfo(users.SingleOrDefault());
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <returns>All users, sorted by username</returns>
- public UserInfo[] GetUsers() {
- return new UserInfo[] { };
- //HACK: Don't return all users
- //var users = Membership.GetAllUsers().OfType<MembershipUser>().OrderBy(u=>u.UserName);
- //return (from u in users select ToUserInfo(u)).ToArray();
- }
-
- /// <summary>
- /// Gets all the users that have the specified element in their data.
- /// </summary>
- /// <param name="key">key of the data</param>
- /// <returns>the users and the data</returns>
- public IDictionary<UserInfo, string> GetUsersWithData(string key) {
- if (String.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
- //HACK: don't return any users.
- return new Dictionary<UserInfo, string>();
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="user">user to modify</param>
- /// <param name="newDisplayName">new display name (can be null)</param>
- /// <param name="newPassword">new password (null or empty to keep current password)</param>
- /// <param name="newEmail"></param>
- /// <param name="newActive"></param>
- /// <returns>The Modified UserInfo instance</returns>
- public UserInfo ModifyUser(UserInfo user, string newDisplayName, string newPassword, string newEmail, bool newActive) {
- if (user == null) throw new ArgumentNullException("user");
- var membershipUser = Membership.GetUser(user.Username, false);
- if (membershipUser == null)
- throw new ArgumentException("Could not locate user '" + user.Username + "' in Membership Provider.", "user");
-
- membershipUser.ChangePassword(membershipUser.GetPassword(), newPassword);
- membershipUser.Email = newEmail;
- membershipUser.IsApproved = newActive;
- Membership.UpdateUser(membershipUser);
-
- var profile = GetProfile(membershipUser);
- profile["DisplayName"] = newDisplayName;
- profile.Save();
-
- return ToUserInfo(membershipUser);
- }
-
- /// <returns>true if the user was removed successfuly</returns>
- public bool RemoveUser(UserInfo user) {
- if (user == null) throw new ArgumentNullException("user");
-
- return Membership.DeleteUser(user.Username);
- }
-
- #endregion
-
- #region Login/out
- /// <summary>
- /// Notifies the provider that a user has logged in through the authentication cookie.
- /// </summary>
- /// <param name="user"></param>
- public void NotifyCookieLogin(UserInfo user) {
- if (user == null) throw new ArgumentNullException("user");
- Membership.GetUser(true);
- }
-
- public void NotifyLogout(UserInfo user) {
- if (user == null) throw new ArgumentNullException("user");
- if(HttpContext.Current == null) return;
- switch (HttpContext.Current.User.Identity.AuthenticationType) {
- case "Forms":
- FormsAuthentication.SignOut();
- break;
- }
- }
-
- public bool TestAccount(UserInfo user, string password) {
- if (user == null) throw new ArgumentNullException("user");
- return Membership.ValidateUser(user.Username, password);
- }
-
- public UserInfo TryAutoLogin(System.Web.HttpContext context) {
- if (context == null) throw new ArgumentNullException("context");
-
- if (HttpContext.Current != null &&
- HttpContext.Current.User.Identity.IsAuthenticated)
- return ToUserInfo(Membership.GetUser(true));
- return null;
- }
-
- public UserInfo TryManualLogin(string username, string password) {
- if (String.IsNullOrEmpty(username)) throw new ArgumentNullException("username");
- //if (String.IsNullOrEmpty(password)) throw new ArgumentNullException("password");
-
- if (Membership.ValidateUser(username, password))
- return GetUser(username);
- return null;
- }
- #endregion
-
- #region UserGroups/Roles
- /// <summary>
- /// Adds a user group (role)
- /// </summary>
- /// <param name="description">ignored by the System Role Providers</param>
- public UserGroup AddUserGroup(string name, string description) {
- if (String.IsNullOrEmpty(name))
- throw new ArgumentNullException("name");
- //if (description == null)
- // throw new ArgumentNullException("description");
-
- Roles.CreateRole(name);
- return new MembershipUserGroup(name, String.Empty, this, name);
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <returns>All user groups (Roles), sorted by name</returns>
- public UserGroup[] GetUserGroups() {
- var roles = Roles.GetAllRoles();
- Array.Sort<string>(roles);
-
- return (from roleName in roles
- orderby roleName
- select new MembershipUserGroup(roleName, String.Empty, this, roleName)
- {Users=GetUsersForGroup(roleName) }
- ).ToArray();
- }
-
- private string[] GetUsersForGroup(string roleName) {
- if (String.IsNullOrEmpty(roleName)) throw new ArgumentNullException("roleName");
- return new string[] { };
- //HACK: Don't return all users
- //return Roles.GetUsersInRole(roleName);
- }
-
- public UserGroup ModifyUserGroup(UserGroup group, string description) {
- if (group == null) throw new ArgumentNullException("group");
- //if (description == null) throw new ArgumentNullException("description");
-
- // System Role Provider does not support role descriptions
- return group;
- }
-
- public bool RemoveUserGroup(UserGroup group) {
- if (group == null) throw new ArgumentNullException("group");
-
- return Roles.DeleteRole(group.Name);
- }
-
- public UserInfo SetUserMembership(UserInfo user, string[] groups) {
- if (user == null) throw new ArgumentNullException("user");
-
- var currentRoles = Roles.GetRolesForUser(user.Username);
- Roles.RemoveUserFromRoles(user.Username,
- (from r in currentRoles
- where !groups.Contains(r)
- select r).ToArray());
-
- Roles.AddUserToRoles(user.Username, groups);
-
- var ret = GetUser(user.Username);
- ret.Groups = Roles.GetRolesForUser(user.Username);
-
- return ret;
- }
- #endregion
-
- #region User Data
- public IDictionary<string, string> RetrieveAllUserData(UserInfo user) {
- if (user == null) throw new ArgumentNullException("user");
-
- var ret = new Dictionary<string, string>();
- var profile = GetProfile(user.Username);
-
- foreach(var p in ProfileBase.Properties.OfType<SettingsProperty>()) {
- if (p.PropertyType == typeof(string))
- ret.Add(p.Name, (string)profile[p.Name]);
- else if (profile[p.Name] != null)
- ret.Add(p.Name, profile[p.Name].ToString());
- else
- ret.Add(p.Name, null);
-
- return ret;
- }
-
- return ret;
- }
-
- public string RetrieveUserData(UserInfo user, string key) {
- if (user == null) throw new ArgumentNullException("user");
- if (String.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
-
- key = key.ToLowerInvariant();
- var profile = GetProfile(user.Username);
- return profile[key] as string;
- }
-
- public bool StoreUserData(UserInfo user, string key, string value) {
- if (user == null) throw new ArgumentNullException("user");
- if (String.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
-
- try {
- var profile = GetProfile(user.Username);
- profile[key] = value;
- profile.Save();
- }
- catch {
- return false;
- }
- return true;
- }
- #endregion
-
- #region Internal Utilities
- private MembershipUserInfo ToUserInfo(MembershipUser membershipUser){
- if (membershipUser == null) return null;
-
- var profile = GetProfile(membershipUser);
- if (profile["DisplayName"] == null)
- profile["DisplayName"] = membershipUser.UserName;
- profile.Save();
-
- return new MembershipUserInfo(membershipUser.UserName, (string)profile["DisplayName"], membershipUser.Email, membershipUser.IsApproved, membershipUser.CreationDate, this, membershipUser.ProviderUserKey) {
- Groups = Roles.GetRolesForUser(membershipUser.UserName)};
- }
-
- private static ProfileBase GetProfile(string username) {
- if (String.IsNullOrEmpty(username)) throw new ArgumentNullException("username");
-
- return ProfileBase.Create(username);
- }
-
- private static ProfileBase GetProfile(MembershipUser user) {
- if (user == null) throw new ArgumentNullException("user");
- return GetProfile(user.UserName);
- }
- #endregion
- }
- }