/// <summary>
        /// Change password
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public virtual DataResult ChangePassword(ChangePasswordRequest request)
        {
            Guard.IsNotNull(request, "Request");

            var result = new DataResult();
            if (String.IsNullOrWhiteSpace(request.UserName))
            {
                result.AddError(this.localizationService.GetResource("Security.Login.UserDoesNotExists"));
                return result;
            }
            if (String.IsNullOrWhiteSpace(request.NewPassword))
            {
                result.AddError("Password is not entered");
                return result;
            }

            var User = this.userService.GetByUsername(request.UserName);
            if (User == null)
            {
                result.AddError(this.localizationService.GetResource("Security.Login.UserDoesNotExists"));
                return result;
            }

            var requestIsValid = false;
            if (request.ValidateRequest)
            {
                //password
                string oldPwd = request.OldPassword;

                bool oldPasswordIsValid = encryptionService.GetSHAHash(oldPwd,true).IsCaseInsensitiveEqual(User.Password);

                if (!oldPasswordIsValid)
                    result.AddError("Old password doesn't match");

                if (oldPasswordIsValid)
                    requestIsValid = true;
            }
            else
                requestIsValid = true;

            //at this point request is valid
            if (requestIsValid)
            {
                User.Password = encryptionService.GetSHAHash(request.NewPassword, true);
                User.LastPasswordChangeDate = DateTime.UtcNow; // set the date time when the password has been changed.

                this.userService.Update(User);
            }

            return result;
        }
        /// <summary>
        /// Update registration
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public virtual DataResult<User> UpdateRegistration(UserRegistrationRequest request)
        {
            Guard.IsNotNull(request, "Request");

            var result = new DataResult<User>();

            if (!CommonHelper.IsValidEmail(request.Username))
            {
                result.AddError(this.localizationService.GetResource("Common.WrongEmail"));
                return result;
            }

            var user = userService.GetByUsername(request.Username);

            // add or remove administrator role
            // set the enterprise administrator role
            var administratorRole = this.userService.GetUserRoleBySystemName(SystemUserRoleNames.Administrators);
            if (administratorRole == null)
                throw new SiteException("'" + SystemUserRoleNames.Administrators + "' role could not be loaded");

            // if administrator
            if (request.IsAdministrator)
            {
                user.UserRoles.Add(administratorRole);
            }
            else
            {
                if (user.IsInUserRole(SystemUserRoleNames.Administrators))
                    user.UserRoles.Remove(administratorRole);
            }

            // add audit history
            user.AuditHistory.Add
            (
                userActivityService.InsertActivity(SystemActivityLogTypeNames.Update,
                    user.ToString(), StateKeyManager.USER_ACTIVITY_COMMENT, request.Username)
             );

            // insert the user
            this.userService.Update(user);

            // upadate attributes
            attributeService.SaveAttribute(user, SystemUserAttributeNames.FirstName, encryptionService.AESEncrypt(request.FirstName, user));
            attributeService.SaveAttribute(user, SystemUserAttributeNames.LastName, encryptionService.AESEncrypt(request.LastName, user));

            if (!string.IsNullOrEmpty(request.Mobile))
                attributeService.SaveAttribute(user, SystemUserAttributeNames.Mobile, encryptionService.AESEncrypt(request.Mobile, user));

            result.Data = user;
            return result;
        }
        /// <summary>
        /// Validate user
        /// </summary>
        /// <param name="userName">UserName</param>
        /// <param name="hashPassword">Hash Password</param>
        /// <returns>Result</returns>
        public virtual DataResult<User> ValidateUser(string userName, string userPassword)
        {
            var result = new DataResult<User>();

            User user = this.userService.GetByUsername(userName);

            // need to set appropriate messages
            if (user == null)
            {
                result.AddError(localizationService.GetResource("Security.Login.UserDoesNotExists"));
                return result;
            }

            // check whether the user isapproved or not
            if (user.CurrentPublishingStatus != PublishingStatus.Active)
            {
                result.AddError(localizationService.GetResource("Security.Login.UserNotActive"));
                return result;
            }

            // only registered can login
            if (!user.IsRegistered())
                return result;

            // validate the password
            var isValid = encryptionService.GetSHAHash(userPassword, true).IsCaseInsensitiveEqual(user.Password); //client is sending hashPassword

            if (!isValid)
            {
                user.FailedPasswordAttemptCount++;
                this.userService.Update(user);
                result.AddError(localizationService.GetResource("Security.Login.WrongCredentials"));
                return result;
            }

            // valid credentials and user
            result.Data = user;

            return result;
        }
        /// <summary>
        /// Register User
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public virtual DataResult<User> RegisterUser(UserRegistrationRequest request)
        {
            Guard.IsNotNull(request, "Request");

            var result = new DataResult<User>();

            if (!CommonHelper.IsValidEmail(request.Username))
            {
                result.AddError(this.localizationService.GetResource("Common.WrongEmail"));
                return result;
            }

            if (String.IsNullOrWhiteSpace(request.Password))
            {
                result.AddError(this.localizationService.GetResource("Users.Fields.Password"));
                return result;
            }

            //validate unique user
            if (!this.userService.IsUnique(request.Username))
            {
                result.AddError(this.localizationService.GetResource("Users.Fields.Username.NotUnique"));
                return result;
            }

            var user = new User()
            {
                CreatedOn = DateTime.UtcNow,
                Username = request.Username,
                Password = request.Password, // we have already encrypted the password on client side
                CurrentPublishingStatus = request.CurrentPublishingStatus, // whether its an active user
            };

            //add to 'Registered' role
            var registeredRole = this.userService.GetUserRoleBySystemName(SystemUserRoleNames.Users);
            if ( registeredRole == null )
                throw new SiteException("'" + SystemUserRoleNames.Users + "' role could not be loaded");
            user.UserRoles.Add(registeredRole);

            // if administrator
            if (request.IsAdministrator)
            {
                // set the enterprise administrator role
                var administratorRole = this.userService.GetUserRoleBySystemName(SystemUserRoleNames.Administrators);
                if (administratorRole == null)
                    throw new SiteException("'" + SystemUserRoleNames.Administrators + "' role could not be loaded");
                user.UserRoles.Add(administratorRole);
            }

            // add audit history
            user.AuditHistory.Add
             (
                userActivityService.InsertActivity(SystemActivityLogTypeNames.Add,
                    user.ToString(), StateKeyManager.USER_ACTIVITY_COMMENT, request.Username)
             );

            // insert the user
            this.userService.Insert(user);

            // upadate attributes
            attributeService.SaveAttribute(user, SystemUserAttributeNames.FirstName, encryptionService.AESEncrypt(request.FirstName, user));
            attributeService.SaveAttribute(user, SystemUserAttributeNames.LastName, encryptionService.AESEncrypt(request.LastName, user));

            if ( !string.IsNullOrEmpty(request.Mobile))
                attributeService.SaveAttribute(user, SystemUserAttributeNames.Mobile, encryptionService.AESEncrypt( request.Mobile,user));

            // create activation token
            attributeService.SaveAttribute(user, SystemUserAttributeNames.AccountActivationToken, Guid.NewGuid().ToString());

            // set the data result
            result.Data = user;
            return result;
        }