using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.Serialization; namespace Umbraco.Core.Models { /// /// Represents a Member object /// [Serializable] [DataContract(IsReference = true)] public class Member : ContentBase, IMember { private readonly IMemberType _contentType; private string _contentTypeAlias; private string _username; private string _email; private string _password; private object _providerUserKey; private Type _userTypeKey; /// /// Constructor for creating a Member object /// /// Name of the content /// ContentType for the current Content object public Member(string name, IMemberType contentType) : base(name, -1, contentType, new PropertyCollection()) { _contentType = contentType; } internal Member(string name, string email, string username, string password, int parentId, IMemberType contentType) : base(name, parentId, contentType, new PropertyCollection()) { Mandate.ParameterNotNull(contentType, "contentType"); _contentType = contentType; _email = email; _username = username; _password = password; } public Member(string name, string email, string username, string password, IMemberType contentType) : this(name, email, username, password, -1, contentType) { Mandate.ParameterNotNull(contentType, "contentType"); _contentType = contentType; _email = email; _username = username; _password = password; } //public Member(string name, string email, string username, string password, IContentBase parent, IMemberType contentType) // : base(name, parent, contentType, new PropertyCollection()) //{ // Mandate.ParameterNotNull(contentType, "contentType"); // _contentType = contentType; // _email = email; // _username = username; // _password = password; //} private static readonly PropertyInfo DefaultContentTypeAliasSelector = ExpressionHelper.GetPropertyInfo(x => x.ContentTypeAlias); private static readonly PropertyInfo UsernameSelector = ExpressionHelper.GetPropertyInfo(x => x.Username); private static readonly PropertyInfo EmailSelector = ExpressionHelper.GetPropertyInfo(x => x.Email); private static readonly PropertyInfo PasswordSelector = ExpressionHelper.GetPropertyInfo(x => x.Password); private static readonly PropertyInfo ProviderUserKeySelector = ExpressionHelper.GetPropertyInfo(x => x.ProviderUserKey); private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo(x => x.ProviderUserKeyType); /// /// Gets or sets the Username /// [DataMember] public string Username { get { return _username; } set { SetPropertyValueAndDetectChanges(o => { _username = value; return _username; }, _username, UsernameSelector); } } /// /// Gets or sets the Email /// [DataMember] public string Email { get { return _email; } set { SetPropertyValueAndDetectChanges(o => { _email = value; return _email; }, _email, EmailSelector); } } /// /// Gets or sets the Password /// [DataMember] public string Password { get { return _password; } set { SetPropertyValueAndDetectChanges(o => { _password = value; return _password; }, _password, PasswordSelector); } } /// /// Gets or sets the Groups that Member is part of /// [DataMember] public IEnumerable Groups { get; set; } /// /// Gets or sets the Password Question /// /// /// Alias: umbracoPasswordRetrievalQuestionPropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public string PasswordQuestion { get { return Properties[Constants.Conventions.Member.PasswordQuestion].Value == null ? string.Empty : Properties[Constants.Conventions.Member.PasswordQuestion].Value.ToString(); } set { Properties[Constants.Conventions.Member.PasswordQuestion].Value = value; } } /// /// Gets or sets the Password Answer /// /// /// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public string PasswordAnswer { get { return Properties[Constants.Conventions.Member.PasswordAnswer].Value == null ? string.Empty : Properties[Constants.Conventions.Member.PasswordAnswer].Value.ToString(); } set { Properties[Constants.Conventions.Member.PasswordAnswer].Value = value; } } /// /// Gets or set the comments for the member /// /// /// Alias: umbracoCommentPropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public string Comments { get { return Properties[Constants.Conventions.Member.Comments].Value == null ? string.Empty : Properties[Constants.Conventions.Member.Comments].Value.ToString(); } set { Properties[Constants.Conventions.Member.Comments].Value = value; } } /// /// Gets or sets a boolean indicating whether the Member is approved /// /// /// Alias: umbracoApprovePropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public bool IsApproved { get { if (Properties[Constants.Conventions.Member.IsApproved].Value == null) return default(bool); if (Properties[Constants.Conventions.Member.IsApproved].Value is bool) return (bool)Properties[Constants.Conventions.Member.IsApproved].Value; return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsApproved].Value, typeof(bool)); } set { Properties[Constants.Conventions.Member.IsApproved].Value = value; } } /// /// Gets or sets a boolean indicating whether the Member is locked out /// /// /// Alias: umbracoLockPropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public bool IsLockedOut { get { if (Properties[Constants.Conventions.Member.IsLockedOut].Value == null) return default(bool); if (Properties[Constants.Conventions.Member.IsLockedOut].Value is bool) return (bool)Properties[Constants.Conventions.Member.IsLockedOut].Value; return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsLockedOut].Value, typeof(bool)); } set { Properties[Constants.Conventions.Member.IsLockedOut].Value = value; } } /// /// Gets or sets the date for last login /// /// /// Alias: umbracoLastLoginPropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public DateTime LastLoginDate { get { if (Properties[Constants.Conventions.Member.LastLoginDate].Value == null) return default(DateTime); if (Properties[Constants.Conventions.Member.LastLoginDate].Value is DateTime) return (DateTime)Properties[Constants.Conventions.Member.LastLoginDate].Value; return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLoginDate].Value, typeof(DateTime)); } set { Properties[Constants.Conventions.Member.LastLoginDate].Value = value; } } /// /// Gest or sets the date for last password change /// /// /// Alias: umbracoMemberLastPasswordChange /// Part of the standard properties collection. /// [IgnoreDataMember] public DateTime LastPasswordChangeDate { get { if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value == null) return default(DateTime); if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value is DateTime) return (DateTime)Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value; return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value, typeof(DateTime)); } set { Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value = value; } } /// /// Gets or sets the date for when Member was locked out /// /// /// Alias: umbracoMemberLastLockout /// Part of the standard properties collection. /// [IgnoreDataMember] public DateTime LastLockoutDate { get { if (Properties[Constants.Conventions.Member.LastLockoutDate].Value == null) return default(DateTime); if (Properties[Constants.Conventions.Member.LastLockoutDate].Value is DateTime) return (DateTime)Properties[Constants.Conventions.Member.LastLockoutDate].Value; return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLockoutDate].Value, typeof(DateTime)); } set { Properties[Constants.Conventions.Member.LastLockoutDate].Value = value; } } /// /// Gets or sets the number of failed password attempts. /// This is the number of times the password was entered incorrectly upon login. /// /// /// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias /// Part of the standard properties collection. /// [IgnoreDataMember] public int FailedPasswordAttempts { get { if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value == null) return default(int); if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value is int) return (int)Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value; return (int)Convert.ChangeType(Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value, typeof(int)); } set { Properties[Constants.Conventions.Member.LastLockoutDate].Value = value; } } /// /// String alias of the default ContentType /// [DataMember] public virtual string ContentTypeAlias { get { return _contentTypeAlias; } internal set { SetPropertyValueAndDetectChanges(o => { _contentTypeAlias = value; return _contentTypeAlias; }, _contentTypeAlias, DefaultContentTypeAliasSelector); } } /// /// User key from the Provider. /// /// /// When using standard umbraco provider this key will /// correspond to the guid UniqueId/Key. /// Otherwise it will the one available from the asp.net /// membership provider. /// [DataMember] public virtual object ProviderUserKey { get { return _providerUserKey; } set { SetPropertyValueAndDetectChanges(o => { _providerUserKey = value; return _providerUserKey; }, _providerUserKey, ProviderUserKeySelector); } } /// /// Gets or sets the type of the provider user key. /// /// /// The type of the provider user key. /// [IgnoreDataMember] internal Type ProviderUserKeyType { get { return _userTypeKey; } private set { SetPropertyValueAndDetectChanges(o => { _userTypeKey = value; return _userTypeKey; }, _userTypeKey, UserTypeKeySelector); } } /// /// Sets the type of the provider user key. /// /// The type. internal void SetProviderUserKeyType(Type type) { ProviderUserKeyType = type; } /// /// Method to call when Entity is being saved /// /// Created date is set and a Unique key is assigned internal override void AddingEntity() { base.AddingEntity(); if (Key == Guid.Empty) Key = Guid.NewGuid(); } /// /// Gets the ContentType used by this content object /// [IgnoreDataMember] public IMemberType ContentType { get { return _contentType; } } public override void ChangeTrashedState(bool isTrashed, int parentId = -20) { throw new NotSupportedException("Members can't be trashed as no Recycle Bin exists, so use of this method is invalid"); } /* Internal experiment - only used for mapping queries. * Adding these to have first level properties instead of the Properties collection. */ internal string LongStringPropertyValue { get; set; } internal string ShortStringPropertyValue { get; set; } internal int IntegerropertyValue { get; set; } internal bool BoolPropertyValue { get; set; } internal DateTime DateTimePropertyValue { get; set; } internal string PropertyTypeAlias { get; set; } } }