/// <summary>
        /// When overridden in a derived class, deletes all user-profile data for profiles in which the last activity date occurred before the specified date.
        /// </summary>
        /// <returns>The number of profiles deleted from the data source.</returns>
        /// <param name="authenticationOption">One of the <see cref="T:System.Web.Profile.ProfileAuthenticationOption" /> values, specifying 
        /// whether anonymous, authenticated, or both types of profiles are deleted.</param>
        /// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime" /> that identifies which user profiles are considered 
        /// inactive. If the <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate" />  value of a user profile occurs on or before 
        /// this date and time, the profile is considered inactive.</param>
        public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
        {
            int num = 0;

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
            {
                IQueryable<Profile> profiles = context.User.Where(MatchUserApplication())
                                                                     .Where(ApplyAuthenticationOption(authenticationOption))
                                                                     .Where(u => u.LastActivityDate <= userInactiveSinceDate.ToUniversalTime())
                                                                     .Select(u => u.Profile);

                foreach (Profile profile in profiles)
                {
                    context.DeleteObject(profile);
                    num++;
                }

                context.SaveChanges();
            }

            return num;
        }
        /// <summary>
        ///  Clears a lock so that the membership user can be validated.
        /// </summary>
        /// <returns>true if the membership user was successfully unlocked; otherwise, false.</returns>
        /// <param name="username">The membership user whose lock status you want to clear.</param>
        public override bool UnlockUser(string username)
        {
            try
            {
                using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
                {
                    User user;
                    try
                    {
                        user = GetUser(u => u.Username == username, context);
                        if (user == null)
                        {
                            return false;
                        }
                    }
                    catch (ProviderException)
                    {
                        return false;
                    }

                    user.LastLockedOutDate = DateTime.Now;
                    context.SaveChanges();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Resets a user's password to a new, automatically generated password.
        /// </summary>
        /// <returns>The new password for the specified user.</returns>
        /// <param name="username">The user to reset the password for.</param>
        /// <param name="answer">The password answer for the specified user.</param>
        public override string ResetPassword(string username, string answer)
        {
            if (!EnablePasswordReset)
            {
                throw new NotSupportedException("Password reset is not enabled.");
            }

            if (answer == null && RequiresQuestionAndAnswer)
            {
                UpdateFailureCount(username, "passwordAnswer");
                throw new ProviderException("Password answer required for password reset.");
            }

            string newPassword = Membership.GeneratePassword(NEWPASSWORDLENGTH, MinRequiredNonAlphanumericCharacters);

            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true);
            OnValidatingPassword(args);

            if (args.Cancel)
            {
                if (args.FailureInformation != null)
                {
                    throw args.FailureInformation;
                }

                throw new MembershipPasswordException("Reset password canceled due to password validation failure.");
            }

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
            {
                User user = GetUser(u => u.Username == username, context);

                if (Convert.ToBoolean(user.IsLockedOut))
                {
                    throw new MembershipPasswordException("The supplied user is locked out.");
                }

                if (RequiresQuestionAndAnswer && !CheckPassword(answer, user.PasswordAnswer))
                {
                    UpdateFailureCount(username, "passwordAnswer");
                    throw new MembershipPasswordException("Incorrect password answer.");
                }

                try
                {
                    user.Password = EncodePassword(newPassword);
                    user.LastPasswordChangedDate = DateTime.Now;

                    context.SaveChanges();
                    return newPassword;
                }
                catch
                {
                    throw new MembershipPasswordException("User not found, or user is locked out. Password not Reset.");
                }
            }
        }
        /// <summary>
        /// Gets information from the data source for a user. Provides an option to update the last-activity date/time stamp for the user.
        /// </summary>
        /// <returns>A <see cref="T:System.Web.Security.MembershipUser" /> object populated with the specified user's information from the data source.</returns>
        /// <param name="username">The name of the user to get information for.</param>
        /// <param name="userIsOnline">true to update the last-activity date/time stamp for the user; false to return user information without updating the last-activity date/time stamp for the user.</param>
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
            {
                MembershipUser membershipUser = null;
                User user;
                try
                {
                    user = GetUser(u => u.Username == username, context);
                }
                catch (ProviderException)
                {
                    user = null;
                }

                if (user != null)
                {
                    membershipUser = GetMembershipUserFromPersistedEntity(user);

                    if (userIsOnline)
                    {
                        user.LastActivityDate = DateTime.Now;
                        context.SaveChanges();
                    }
                }

                return membershipUser;
            }
        }
        /// <summary>
        /// Removes a user from the membership data source. 
        /// </summary>
        /// <returns>true if the user was successfully deleted; otherwise, false.</returns>
        /// <param name="username">The name of the user to delete.</param>
        /// <param name="deleteAllRelatedData">true to delete data related to the user from the database; false to leave data related to the user in the database.</param>
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            try
            {
                using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
                {
                    User user;
                    try
                    {
                        user = GetUser(u => u.Username == username, context);
                        if (user == null)
                        {
                            return false;
                        }
                    }
                    catch (ProviderException)
                    {
                        return false;
                    }

                    context.DeleteObject(user);
                    context.SaveChanges();

                    if (deleteAllRelatedData)
                    {
                        // TODO: delete user related data
                    }

                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Adds a new membership user to the data source.
        /// </summary>
        /// <returns>A <see cref="T:System.Web.Security.MembershipUser" /> object populated with the information for the newly created user.</returns>
        /// <param name="username">The user name for the new user.</param>
        /// <param name="password">The password for the new user.</param>
        /// <param name="email">The e-mail address for the new user.</param>
        /// <param name="passwordQuestion">The password question for the new user.</param>
        /// <param name="passwordAnswer">The password answer for the new user</param>
        /// <param name="isApproved">Whether or not the new user is approved to be validated.</param>
        /// <param name="providerUserKey">The unique identifier from the membership data source for the user.</param>
        /// <param name="status">A <see cref="T:System.Web.Security.MembershipCreateStatus" /> enumeration value indicating whether the user was created successfully.</param>
        public override MembershipUser CreateUser(
                                                  string username,
                                                  string password,
                                                  string email,
                                                  string passwordQuestion,
                                                  string passwordAnswer,
                                                  bool isApproved,
                                                  object providerUserKey,
                                                  out MembershipCreateStatus status)
        {
            // Validate username/password
            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, password, true);
            OnValidatingPassword(args);

            if (args.Cancel)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }

            if (RequiresUniqueEmail && GetUserNameByEmail(email) != string.Empty)
            {
                status = MembershipCreateStatus.DuplicateEmail;
                return null;
            }

            // Check whether user with passed username already exists
            MembershipUser user;
            try
            {
                user = GetUser(username, false);
            }
            catch (ProviderException)
            {
                user = null;
            }

            if (user == null)
            {
                DateTime creationDate = DateTime.Now;

                if (providerUserKey == null)
                {
                    providerUserKey = Guid.NewGuid();
                }
                else
                {
                    if (!(providerUserKey is Guid))
                    {
                        status = MembershipCreateStatus.InvalidProviderUserKey;
                        return null;
                    }
                }

                using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
                {
                    User newUser = new User
                    {
                        Id = (Guid)providerUserKey,
                        Username = username,
                        Email = email,
                        IsApproved = isApproved,
                        CreationDate = creationDate,
                        IsAnonymous = false,
                        Application = ProviderUtils.EnsureApplication(ApplicationName, context),
                        Password = EncodePassword(password),
                        PasswordQuestion = passwordQuestion,
                        PasswordAnswer = passwordAnswer,
                        LastLoginDate = creationDate,
                        LastPasswordChangedDate = creationDate,
                        LastActivityDate = creationDate,
                        IsOnline = false,
                        IsLockedOut = false,
                        LastLockedOutDate = creationDate,
                        FailedPasswordAttemptCount = 0,
                        FailedPasswordAttemptWindowStart = creationDate,
                        FailedPasswordAnswerAttemptCount = 0,
                        FailedPasswordAnswerAttemptWindowStart = creationDate
                    };

                    try
                    {
                        context.AddToUser(newUser);
                        context.SaveChanges();
                        status = MembershipCreateStatus.Success;
                    }
                    catch
                    {
                        status = MembershipCreateStatus.UserRejected;
                    }
                }

                return GetUser(username, false);
            }

            status = MembershipCreateStatus.DuplicateUserName;

            return null;
        }
        /// <summary>
        /// Processes a request to update the password question and answer for a membership user.
        /// </summary>
        /// <returns>true if the password question and answer are updated successfully; otherwise, false.</returns>
        /// <param name="username">The user to change the password question and answer for.</param>
        /// <param name="password">The password for the specified user.</param>
        /// <param name="newPasswordQuestion">The new password question for the specified user.</param>
        /// <param name="newPasswordAnswer">The new password answer for the specified user.</param>
        public override bool ChangePasswordQuestionAndAnswer(string username, string password,
                                                             string newPasswordQuestion, string newPasswordAnswer)
        {
            // Check if user is authenticated
            if (!ValidateUser(username, password))
            {
                return false;
            }

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
            {
                User user = GetUser(u => u.Username == username, context);
                user.PasswordAnswer = EncodePassword(newPasswordAnswer);
                user.PasswordQuestion = newPasswordQuestion;

                try
                {
                    context.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// Adds the specified user names to the specified roles for the configured applicationName.
        /// </summary>
        /// <param name="userNames">A string array of user names to be added to the specified roles.</param>
        /// <param name="roleNames">A string array of the role names to add the specified user names to.</param>
        public override void AddUsersToRoles(string[] userNames, string[] roleNames)
        {
            using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
            {
                IQueryable<Role> roles = context.Role.Where(MatchRoleApplication()).Where(ProviderUtils.BuildContainsExpression<Role, string>(r => r.Name, roleNames));
                if (roles.Count() != roleNames.Length)
                {
                    throw new ProviderException("Role not found.");
                }

                IQueryable<User> users = context.User.Where(MatchUserApplication()).Where(ProviderUtils.BuildContainsExpression<User, string>(u => u.Username, userNames));
                if (users.Count() != userNames.Length)
                {
                    throw new ProviderException("User not found.");
                }

                try
                {
                    foreach (User user in users)
                    {
                        foreach (Role role in roles)
                        {
                            // Check whether user is already in role
                            if (IsUserInRole(user.Username, role.Name))
                            {
                                throw new ProviderException(string.Format("User is already in role '{0}'.", role.Name));
                            }

                            user.Role.Add(role);
                        }
                    }

                    context.SaveChanges(false);
                }
                catch (Exception ex)
                {
                    if (WriteExceptionsToEventLog)
                    {
                        WriteToEventLog(ex, "AddUsersToRoles");
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    context.Connection.Close();
                }
            }
        }
        /// <summary>
        /// A helper method that performs the checks and updates associated with password failure tracking.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <param name="failureType">Type of the failure.</param>
        private void UpdateFailureCount(string username, string failureType)
        {
            using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
            {
                User user = GetUser(u => u.Username == username, context);

                DateTime windowStart = new DateTime();
                int failureCount = 0;

                if (failureType == "password")
                {
                    failureCount = Convert.ToInt32(user.FailedPasswordAttemptCount);
                    windowStart = Convert.ToDateTime(user.FailedPasswordAttemptWindowStart);
                }

                if (failureType == "passwordAnswer")
                {
                    failureCount = Convert.ToInt32(user.FailedPasswordAnswerAttemptCount);
                    windowStart = Convert.ToDateTime(user.FailedPasswordAnswerAttemptWindowStart);
                }

                DateTime windowEnd = windowStart.AddMinutes(PasswordAttemptWindow);

                if (failureCount == 0 || DateTime.Now > windowEnd)
                {
                    // First password failure or outside of PasswordAttemptWindow.
                    // Start a new password failure count from 1 and a new window starting now.
                    if (failureType == "password")
                    {
                        user.FailedPasswordAttemptCount = 1;
                        user.FailedPasswordAttemptWindowStart = DateTime.Now;
                    }

                    if (failureType == "passwordAnswer")
                    {
                        user.FailedPasswordAnswerAttemptCount = 1;
                        user.FailedPasswordAnswerAttemptWindowStart = DateTime.Now;
                    }

                    try
                    {
                        context.SaveChanges();
                    }
                    catch
                    {
                        throw new ProviderException("Unable to update failure count and window start.");
                    }
                }
                else
                {
                    if (failureCount++ >= MaxInvalidPasswordAttempts)
                    {
                        // Max password attempts have exceeded the failure threshold. Lock out the user.
                        user.IsLockedOut = true;
                        user.LastLockedOutDate = DateTime.Now;

                        try
                        {
                            context.SaveChanges();
                        }
                        catch
                        {
                            throw new ProviderException("Unable to lock out user.");
                        }
                    }
                    else
                    {
                        // Max password attempts have not exceeded the failure threshold. Update
                        // the failure counts. Leave the window the same.
                        if (failureType == "password")
                        {
                            user.FailedPasswordAttemptCount = failureCount;
                        }

                        if (failureType == "passwordAnswer")
                        {
                            user.FailedPasswordAnswerAttemptCount = failureCount;
                        }

                        try
                        {
                            context.SaveChanges();
                        }
                        catch
                        {
                            throw new ProviderException("Unable to update failure count.");
                        }
                    }
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Removes a role from the data source for the configured applicationName.
        /// </summary>
        /// <param name="roleName">The name of the role to delete.</param>
        /// <param name="throwOnPopulatedRole">If true, throw an exception if <paramref name="roleName"/> has one or more members and do not delete <paramref name="roleName"/>.</param>
        /// <returns>
        /// true if the role was successfully deleted; otherwise, false.
        /// </returns>
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            // Validate role
            if (!RoleExists(roleName))
            {
                throw new ProviderException("Role does not exist.");
            }

            if (throwOnPopulatedRole && GetUsersInRole(roleName).Length > 0)
            {
                throw new ProviderException("Cannot delete a populated role.");
            }

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
            {
                Role role = GetRole(r => r.Name == roleName, context);
                if (role == null)
                {
                    return false;
                }

                try
                {
                    context.DeleteObject(role);
                    context.SaveChanges();
                }
                catch (Exception ex)
                {
                    if (WriteExceptionsToEventLog)
                    {
                        WriteToEventLog(ex, "DeleteRole");
                        return false;
                    }

                    throw;
                }

                return true;
            }
        }
Exemple #11
0
        /// <summary>
        /// Removes the specified user names from the specified roles for the configured applicationName.
        /// </summary>
        /// <param name="userNames">A string array of user names to be removed from the specified roles.</param>
        /// <param name="roleNames">A string array of role names to remove the specified user names from.</param>
        public override void RemoveUsersFromRoles(string[] userNames, string[] roleNames)
        {
            using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
            {
                IQueryable<Role> roles = context.Role.Where(MatchRoleApplication()).Where(ProviderUtils.BuildContainsExpression<Role, string>(r => r.Name, roleNames));
                if (roles.Count() != roleNames.Length)
                {
                    throw new ProviderException("Role not found.");
                }

                IQueryable<User> users = context.User.Include("Role").Where(MatchUserApplication()).Where(ProviderUtils.BuildContainsExpression<User, string>(u => u.Username, userNames));
                if (users.Count() != userNames.Length)
                {
                    throw new ProviderException("User not found.");
                }

                try
                {
                    foreach (User user in users)
                    {
                        foreach (Role role in roles)
                        {
                            /*if (!user.Role.IsLoaded)
                            {
                                user.Role.Load();
                            }*/

                            if (user.Role.Contains(role))
                            {
                                user.Role.Remove(role);
                            }
                        }
                    }

                    context.SaveChanges();
                }
                catch (Exception ex)
                {
                    if (WriteExceptionsToEventLog)
                    {
                        WriteToEventLog(ex, "RemoveUsersFromRoles");
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
Exemple #12
0
        /// <summary>
        /// Adds a new role to the data source for the configured applicationName.
        /// </summary>
        /// <param name="roleName">The name of the role to create.</param>
        public override void CreateRole(string roleName)
        {
            // Validate role name
            if (roleName.Contains(","))
            {
                throw new ArgumentException("Role names cannot contain commas.");
            }

            if (RoleExists(roleName))
            {
                throw new ProviderException("Role name already exists.");
            }

            try
            {
                using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
                {
                    Application application = ProviderUtils.EnsureApplication(ApplicationName, context);

                    // Create new role
                    Role newRole = new Role
                    {
                        Id = Guid.NewGuid(),
                        Name = roleName,
                        Application = application
                    };
                    context.AddToRole(newRole);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                if (WriteExceptionsToEventLog)
                {
                    WriteToEventLog(ex, "CreateRole");
                }
                else
                {
                    throw;
                }
            }
        }
        /// <summary>
        /// When overridden in a derived class, deletes profile properties and information for profiles that match the supplied list of user names.
        /// </summary>
        /// <returns>The number of profiles deleted from the data source.</returns>
        /// <param name="usernames">A string array of user names for profiles to be deleted.</param>
        public override int DeleteProfiles(string[] usernames)
        {
            int num = 0;

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
            {
                IQueryable<User> users = context.User.Include("Profile").Where(u => usernames.Contains(u.Username) && u.Profile != null);

                foreach (User user in users)
                {
                    context.DeleteObject(user.Profile);
                    num++;
                }

                context.SaveChanges();
            }

            return num;
        }
        /// <summary>
        /// Gets the property values from database.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="propertiesValues">The property values.</param>
        private void ExtractPropertyValuesFromDatabase(string userName, SettingsPropertyValueCollection propertiesValues)
        {
            string[] propertyNames = null;
            string propertiesValuesSerialized = null;
            byte[] propertiesValuesBinary = null;

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(connectionString))
            {
                User user = context.User.Include("Profile").Where(MatchUserApplication()).Where(u => u.Username == userName && u.Profile != null).FirstOrDefault();
                if (user != null)
                {
                    propertyNames = user.Profile.PropertyNames.Split(new[] { ':' });
                    propertiesValuesSerialized = user.Profile.PropertyValuesString;
                    propertiesValuesBinary = user.Profile.PropertyValuesBinary;

                    // Update user
                    user.LastActivityDate = DateTime.Now;
                    context.SaveChanges();
                }
            }

            ParseDataFromDatabase(propertyNames, propertiesValuesSerialized, propertiesValuesBinary, propertiesValues);
        }
 /// <summary>
 /// Updates information about a user in the data source.
 /// </summary>
 /// <param name="membershipUser">A <see cref="T:System.Web.Security.MembershipUser" /> object that represents the user to update and the updated information for the user.</param>
 public override void UpdateUser(MembershipUser membershipUser)
 {
     using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
     {
         User user = GetUser(u => u.Username == membershipUser.UserName, context);
         user.Email = membershipUser.Email;
         user.Comment = membershipUser.Comment;
         user.IsApproved = membershipUser.IsApproved;
         context.SaveChanges();
     }
 }
        /// <summary>
        /// Processes a request to update the password for a membership user.
        /// </summary>
        /// <returns>true if the password was updated successfully; otherwise, false.</returns>
        /// <param name="username">The user to update the password for.</param>
        /// <param name="oldPassword">The current password for the specified user.</param>
        /// <param name="newPassword">The new password for the specified user.</param>
        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            // Check if user is authenticated
            if (!ValidateUser(username, oldPassword))
            {
                return false;
            }

            // Notify that password is going to change
            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true);
            OnValidatingPassword(args);

            if (args.Cancel)
            {
                if (args.FailureInformation != null)
                {
                    throw args.FailureInformation;
                }

                throw new MembershipPasswordException("Change password canceled due to new password validation failure.");
            }

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
            {
                User user = GetUser(u => u.Username == username, context);
                user.Password = EncodePassword(newPassword);
                user.LastPasswordChangedDate = DateTime.Now;

                try
                {
                    context.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// Verifies that the specified user name and password exist in the data source.
        /// </summary>
        /// <returns>true if the specified username and password are valid; otherwise, false.</returns>
        /// <param name="username">The name of the user to validate.</param>
        /// <param name="password">The password for the specified user.</param>
        public override bool ValidateUser(string username, string password)
        {
            bool isValid = false;

            using (EFProviders.MemberShip context = new EFProviders.MemberShip(ConnectionString))
            {
                User user;
                try
                {
                    user = GetUser(u => u.Username == username, context);
                    if (user == null)
                    {
                        return false;
                    }
                }
                catch (ProviderException)
                {
                    return false;
                }

                if (CheckPassword(password, user.Password))
                {
                    if (user.IsApproved && !user.IsLockedOut)
                    {
                        isValid = true;

                        user.LastActivityDate = DateTime.Now;
                        user.LastLoginDate = DateTime.Now;
                        context.SaveChanges();
                    }
                }
                else
                {
                    UpdateFailureCount(username, "password");
                }

                return isValid;
            }
        }
        /// <summary>
        /// Sets the values of the specified group of property settings.
        /// </summary>
        /// <param name="context">A <see cref="T:System.Configuration.SettingsContext" /> describing the current application usage.</param>
        /// <param name="properties">A <see cref="T:System.Configuration.SettingsPropertyValueCollection" /> representing the group 
        /// of property settings to set.</param>
        public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection properties)
        {
            string username = (string)context["UserName"];

            if (string.IsNullOrEmpty(username) || properties.Count < 1)
            {
                return;
            }

            bool userIsAuthenticated = (bool)context["IsAuthenticated"];
            string propertiesNames = string.Empty;
            string propertiesValuesSerialized = string.Empty;
            byte[] propertiesValuesBinary = null;

            PrepareDataForSaving(ref propertiesNames, ref propertiesValuesSerialized, ref propertiesValuesBinary, properties, userIsAuthenticated);

            if (propertiesNames.Length != 0)
            {
                using (EFProviders.MemberShip dataContext = new EFProviders.MemberShip(connectionString))
                {
                    // Attempt to load user with associated profile
                    User user = dataContext.User.Include("Profile").Where(MatchUserApplication()).Where(u => u.Username == username).FirstOrDefault();

                    if (user == null)
                    {
                        throw new ArgumentException("user");
                    }

                    if (user.Profile == null)
                    {
                        // Create new profile
                        user.Profile = new Profile();
                    }

                    // Set profile values
                    user.Profile.PropertyNames = propertiesNames;
                    user.Profile.PropertyValuesString = propertiesValuesSerialized;
                    user.Profile.PropertyValuesBinary = propertiesValuesBinary;
                    user.Profile.LastUpdatedDate = DateTime.Now;
                    dataContext.SaveChanges();
                }
            }
        }