public UserAuth CreateUserAuth(UserAuth newUser, string password)
		{
			ValidateNewUser(newUser, password);

			AssertNoExistingUser(newUser);

			var saltedHash = new SaltedHash();
			string salt;
			string hash;
			saltedHash.GetHashAndSaltString(password, out hash, out salt);
			var digestHelper = new DigestAuthFunctions();
			newUser.DigestHA1Hash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
			newUser.PasswordHash = hash;
			newUser.Salt = salt;
			newUser.CreatedDate = DateTime.UtcNow;
			newUser.ModifiedDate = newUser.CreatedDate;

			using (_session)
			{
				_session.Store(newUser);
				_session.SaveChanges();
			}

			return newUser;
		}
        public virtual UserAuth CreateUserAuth(UserAuth newUser, string password)
        {
            ValidateNewUser(newUser, password);

            using (var redis = factory.GetClient())
            {
                AssertNoExistingUser(redis, newUser);

                var saltedHash = new SaltedHash();
                string salt;
                string hash;
                saltedHash.GetHashAndSaltString(password, out hash, out salt);

                newUser.Id = redis.As<UserAuth>().GetNextSequence();
                newUser.PasswordHash = hash;
                newUser.Salt = salt;
                var digestHelper = new DigestAuthFunctions();
                newUser.DigestHA1Hash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
                newUser.CreatedDate = DateTime.UtcNow;
                newUser.ModifiedDate = newUser.CreatedDate;

                var userId = newUser.Id.ToString(CultureInfo.InvariantCulture);
                if (!newUser.UserName.IsNullOrEmpty())
                    redis.SetEntryInHash(IndexUserNameToUserId, newUser.UserName, userId);
                if (!newUser.Email.IsNullOrEmpty())
                    redis.SetEntryInHash(IndexEmailToUserId, newUser.Email, userId);

                redis.Store(newUser);

                return newUser;
            }
        }
        public UserAuth CreateUserAuth(UserAuth newUser, string password)
        {
            newUser.ThrowIfNull("newUser");
            password.ThrowIfNullOrEmpty("password");

            if (newUser.UserName.IsNullOrEmpty() && newUser.Email.IsNullOrEmpty())
                throw new ArgumentNullException("UserName or Email is required");

            if (!newUser.UserName.IsNullOrEmpty())
            {
                if (!ValidUserNameRegEx.IsMatch(newUser.UserName))
                    throw new ArgumentException("UserName contains invalid characters", "UserName");
            }

            return dbFactory.Exec(dbCmd => {
                var effectiveUserName = newUser.UserName ?? newUser.Email;
                var existingUser = GetUserAuthByUserName(dbCmd, effectiveUserName);
                if (existingUser != null)
                    throw new ArgumentException("User {0} already exists".Fmt(effectiveUserName));

                var saltedHash = new SaltedHash();
                string salt;
                string hash;
                saltedHash.GetHashAndSaltString(password, out hash, out salt);

                newUser.PasswordHash = hash;
                newUser.Salt = salt;

                dbCmd.Insert(newUser);

                newUser = dbCmd.GetById<UserAuth>(dbCmd.GetLastInsertId());
                return newUser;
            });
        }
        private UserAuth FindByPasswordCredential(string login, string password)
        {
            UserAuth userAuth = null;
            using (new UnitOfWork())
            {
                var manager = this.container.Resolve<IUserManager>();
                var user = manager.FindByPasswordCredential(login, password);
                if (user != null)
                {
                    userAuth = new UserAuth
                        {
                            RefIdStr = user.Id.ToString(CultureInfo.InvariantCulture), 
                            UserName = login, 
                            Email = user.Email, 
                            DisplayName = user.Name, 
                            Roles = new List<string>(), 
                            Permissions = new List<string>(), 
                        };
                    if (user.Role != null)
                    {
                        userAuth.Roles.Add(user.Role.Name);
                        userAuth.Permissions.AddRange(from p in user.Role.Permissions select p.Name.ToString());
                    }
                }
            }

            return userAuth;
        }
        private static Person ToPerson(UserAuth auth)
        {
            if (auth == null)
            {
                return null;
            }

            var name = auth.FullName;
            if (string.IsNullOrEmpty(name))
            {
                if (!string.IsNullOrEmpty(auth.FirstName) || !string.IsNullOrEmpty(auth.LastName))
                {
                    name = auth.FirstName + " " + auth.LastName;
                }
                else
                {
                    name = auth.UserName;
                }
            }

            return new Person
            {
                Id = auth.Id,
                Name = name,

                CustomerId = auth.RefId,
                IsEmployee = auth.Roles.Contains(Global.Constants.EmployeeRoleName)
            };
        }
		public UserAuth UpdateUserAuth(UserAuth existingUser, UserAuth newUser, string password)
		{
			ValidateNewUser(newUser, password);

			AssertNoExistingUser(newUser, existingUser);

			var hash = existingUser.PasswordHash;
			var salt = existingUser.Salt;
			if (password != null)
			{
				var saltedHash = new SaltedHash();
				saltedHash.GetHashAndSaltString(password, out hash, out salt);
			}
			// If either one changes the digest hash has to be recalculated
			var digestHash = existingUser.DigestHA1Hash;
			if (password != null || existingUser.UserName != newUser.UserName)
			{
				var digestHelper = new DigestAuthFunctions();
				digestHash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
			}
			newUser.Id = existingUser.Id;
			newUser.PasswordHash = hash;
			newUser.Salt = salt;
			newUser.DigestHA1Hash = digestHash;
			newUser.CreatedDate = existingUser.CreatedDate;
			newUser.ModifiedDate = DateTime.UtcNow;

			using (var session = _documentStore.OpenSession())
			{
				session.Store(newUser);
				session.SaveChanges();
			}

			return newUser;
		}
 public bool TryAuthenticate(
     Dictionary<string, string> digestHeaders, 
     string privateKey, 
     int nonceTimeOut, 
     string sequence, 
     out UserAuth userAuth)
 {
     throw new NotSupportedException();
 }
        private void LoadUserAuth(IAuthSession session, UserAuth userAuth)
        {
            if (userAuth == null) return;

            session.PopulateWith(userAuth);
            session.UserAuthId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
            session.ProviderOAuthAccess = GetUserOAuthProviders(session.UserAuthId)
                .ConvertAll(x => (IOAuthTokens)x);
        }
		private void ValidateNewUserWithoutPassword(UserAuth newUser)
		{
			newUser.ThrowIfNull("newUser");

			if (newUser.UserName.IsNullOrEmpty() && newUser.Email.IsNullOrEmpty())
				throw new ArgumentNullException("UserName or Email is required");

			if (!newUser.UserName.IsNullOrEmpty())
			{
				if (!ValidUserNameRegEx.IsMatch(newUser.UserName))
					throw new ArgumentException("UserName contains invalid characters", "UserName");
			}
		}
		private void AssertNoExistingUser(UserAuth newUser, UserAuth exceptForExistingUser = null)
		{
			if (newUser.UserName != null)
			{
				var existingUser = GetUserAuthByUserName(newUser.UserName);
				if (existingUser != null
					&& (exceptForExistingUser == null || existingUser.Id != exceptForExistingUser.Id))
					throw new ArgumentException("User {0} already exists".Fmt(newUser.UserName));
			}
			if (newUser.Email != null)
			{
				var existingUser = GetUserAuthByUserName(newUser.Email);
				if (existingUser != null
					&& (exceptForExistingUser == null || existingUser.Id != exceptForExistingUser.Id))
					throw new ArgumentException("Email {0} already exists".Fmt(newUser.Email));
			}
		}
        public ActionResult Register(RegisterModel model)
        {
            string hash;
            string salt;
            new SaltedHash().GetHashAndSaltString(model.Password, out hash, out salt);

            var user = new UserAuth
                {
                    DisplayName = model.UserName,
                    Email = model.Email,
                    UserName = model.UserName,
                    PasswordHash = hash,
                    Salt = salt
                };

            var response = UserAuthRepo.CreateUserAuth(user, model.Password);
            var authResponse = AuthService.Authenticate(new Auth {UserName = model.UserName, Password = model.Password, RememberMe = true});

            return RedirectToAction("Index", "Home");
        }
        public bool TryAuthenticate(string userName, string password, out UserAuth userAuth)
        {
            // todo: implement
            userAuth = new UserAuth
                {
                    Id = 1,
                    UserName = userName,
                    Email = "email",
                    PrimaryEmail = "email",
                    DisplayName = "full name",
                    PasswordHash = "adsd",
                    Salt = "salt",
                    Permissions = new List<string>(),
                    Roles = new List<string>(),
                    CreatedDate = DateTime.Now,
                    ModifiedDate = DateTime.Now
                };

            return true;
        }
        public string CreateOrMergeAuthSession(IOAuthSession oAuthSession, IOAuthTokens tokens)
        {
            using (var redis = factory.GetClient())
            {
                UserOAuthProvider oauthProvider = null;

                var oAuthProviderId = GetAuthProviderByUserId(redis, tokens.Provider, tokens.UserId);
                if (!oAuthProviderId.IsNullOrEmpty())
                    oauthProvider = redis.As<UserOAuthProvider>().GetById(oAuthProviderId);

                var userAuth = GetUserAuth(redis, oAuthSession, tokens);

                if (userAuth == null)
                {
                    userAuth = new UserAuth {
                        Id = redis.As<UserAuth>().GetNextSequence(),
                    };
                }

                if (oauthProvider == null)
                {
                    oauthProvider = new UserOAuthProvider {
                        Id = redis.As<UserOAuthProvider>().GetNextSequence(),
                        UserAuthId = userAuth.Id,
                        Provider = tokens.Provider,
                        UserId = tokens.UserId,
                    };
                    var idx = IndexProviderUserIdHash(tokens.Provider);
                    redis.SetEntryInHash(idx, tokens.UserId, oauthProvider.Id.ToString());
                }

                oauthProvider.PopulateMissing(tokens);
                userAuth.PopulateMissing(oauthProvider);

                redis.Store(userAuth);
                redis.Store(oauthProvider);
                redis.AddItemToSet(IndexUserAuthAndProviderIdsSet(userAuth.Id), oauthProvider.Id.ToString());

                return userAuth.Id.ToString();
            }
        }
		public UserAuth CreateUserAuth(UserAuth newUser, string password)
		{
			ValidateNewUser(newUser, password);

			AssertNoExistingUser(mongoDatabase, newUser);

			var saltedHash = new SaltedHash();
			string salt;
			string hash;
			saltedHash.GetHashAndSaltString(password, out hash, out salt);
            var digestHelper = new DigestAuthFunctions();
            newUser.DigestHA1Hash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
			newUser.PasswordHash = hash;
			newUser.Salt = salt;
			newUser.CreatedDate = DateTime.UtcNow;
			newUser.ModifiedDate = newUser.CreatedDate;

			var collection = mongoDatabase.GetCollection<UserAuth>("UserAuth");
			collection.Insert(newUser);
			// todo - update id here
			return newUser;
		}
        public UserAuth CreateUserAuth(UserAuth newUser, string password)
        {
            ValidateNewUser(newUser, password);

            return dbFactory.Run(db => {
                AssertNoExistingUser(db, newUser);

                string salt;
                string hash;
                passwordHasher.GetHashAndSaltString(password, out hash, out salt);
                var digestHelper = new DigestAuthFunctions();
                newUser.DigestHa1Hash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
                newUser.PasswordHash = hash;
                newUser.Salt = salt;
                newUser.CreatedDate = DateTime.UtcNow;
                newUser.ModifiedDate = newUser.CreatedDate;

                db.Insert(newUser);

                newUser = db.GetById<UserAuth>(db.GetLastInsertId());
                return newUser;
            });
        }
        public UserAuth UpdateUserAuth(UserAuth existingUser, UserAuth newUser, string password)
        {
            ValidateNewUser(newUser, password);

            using (var redis = factory.GetClient())
            {
                AssertNoExistingUser(redis, newUser, existingUser);

                if (existingUser.UserName != newUser.UserName && existingUser.UserName != null)
                {
                    redis.RemoveEntryFromHash(IndexUserNameToUserId, existingUser.UserName);
                }
                if (existingUser.Email != newUser.Email && existingUser.Email != null)
                {
                    redis.RemoveEntryFromHash(IndexEmailToUserId, existingUser.Email);
                }

                var hash = existingUser.PasswordHash;
                var salt = existingUser.Salt;
                if (password != null)
                {
                    var saltedHash = new SaltedHash();
                    saltedHash.GetHashAndSaltString(password, out hash, out salt);
                }
                // If either one changes the digest hash has to be recalculated
                var digestHash = existingUser.DigestHA1Hash;
                if (password != null || existingUser.UserName != newUser.UserName)
                {
                    var digestHelper = new DigestAuthFunctions();
                    digestHash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
                }

                newUser.Id = existingUser.Id;
                newUser.PasswordHash = hash;
                newUser.Salt = salt;
                newUser.CreatedDate = existingUser.CreatedDate;
                newUser.ModifiedDate = DateTime.UtcNow;

                var userId = newUser.Id.ToString(CultureInfo.InvariantCulture);
                if (!newUser.UserName.IsNullOrEmpty())
                    redis.SetEntryInHash(IndexUserNameToUserId, newUser.UserName, userId);
                if (!newUser.Email.IsNullOrEmpty())
                    redis.SetEntryInHash(IndexEmailToUserId, newUser.Email, userId);

                redis.Store(newUser);

                return newUser;
            }
        }
		public void SaveUserAuth(UserAuth userAuth)
		{
			userAuth.ModifiedDate = DateTime.UtcNow;
			if (userAuth.CreatedDate == default(DateTime))
				userAuth.CreatedDate = userAuth.ModifiedDate;

			var collection = mongoDatabase.GetCollection<UserAuth>("UserAuth");
			collection.Insert(userAuth);
		}
        public bool TryAuthenticate(Dictionary<string,string> digestHeaders, string PrivateKey, int NonceTimeOut, string sequence, out UserAuth userAuth)
        {
            //userId = null;
            userAuth = GetUserAuthByUserName(digestHeaders["username"]);
            if (userAuth == null) return false;

            var digestHelper = new DigestAuthFunctions();
            if (digestHelper.ValidateResponse(digestHeaders,PrivateKey,NonceTimeOut,userAuth.DigestHA1Hash,sequence))
            {
                //userId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
                return true;
            }
            userAuth = null;
            return false;
        }
		public void SaveUserAuth(UserAuth userAuth)
		{
            using (_session)
			{
				userAuth.ModifiedDate = DateTime.UtcNow;
				if (userAuth.CreatedDate == default(DateTime))
					userAuth.CreatedDate = userAuth.ModifiedDate;

                _session.Store(userAuth);
                _session.SaveChanges();
			}
		}
		public void SaveUserAuth(UserAuth userAuth)
		{
			using (var session = _documentStore.OpenSession())
			{
				userAuth.ModifiedDate = DateTime.UtcNow;
				if (userAuth.CreatedDate == default(DateTime))
					userAuth.CreatedDate = userAuth.ModifiedDate;

				session.Store(userAuth);
				session.SaveChanges();
			}
		}
		private void LoadUserAuth(IAuthSession session, UserAuth userAuth)
		{
			if (userAuth == null) return;

			var idSesije = session.Id;  //first record session Id (original session Id)
			session.PopulateWith(userAuth); //here, original sessionId is overwritten with facebook user Id
			session.Id = idSesije;  //we return Id of original session here

			session.UserAuthId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
			session.ProviderOAuthAccess = GetUserOAuthProviders(session.UserAuthId)
				.ConvertAll(x => (IOAuthTokens)x);

		}
        public UserAuth UpdateUserAuth(UserAuth existingUser, UserAuth newUser, string password)
        {
            ValidateNewUser(newUser, password);

            return dbFactory.Exec(dbCmd => {
                AssertNoExistingUser(dbCmd, newUser, existingUser);

                var hash = existingUser.PasswordHash;
                var salt = existingUser.Salt;
                if (password != null)
                {
                    var saltedHash = new SaltedHash();
                    saltedHash.GetHashAndSaltString(password, out hash, out salt);
                }

                newUser.Id = existingUser.Id;
                newUser.PasswordHash = hash;
                newUser.Salt = salt;
                newUser.CreatedDate = existingUser.CreatedDate;
                newUser.ModifiedDate = DateTime.UtcNow;

                dbCmd.Save(newUser);

                return newUser;
            });
        }
		private void ValidateNewUser(UserAuth newUser, string password)
		{
			password.ThrowIfNullOrEmpty("password");

			ValidateNewUserWithoutPassword(newUser);
		}
        public void SaveUserAuth(UserAuth userAuth)
        {
            userAuth.ModifiedDate = DateTime.UtcNow;
            if (userAuth.CreatedDate == default(DateTime))
                userAuth.CreatedDate = userAuth.ModifiedDate;

            dbFactory.Exec(dbCmd => dbCmd.Save(userAuth));
        }
        public virtual bool TryAuthenticate(string userName, string password, out UserAuth userAuth)
        {
            //userId = null;
            userAuth = GetUserAuthByUserName(userName);
            if (userAuth == null) return false;

            var saltedHash = new SaltedHash();
            if (saltedHash.VerifyHashString(password, userAuth.PasswordHash, userAuth.Salt))
            {
                return true;
            }

            userAuth = null;
            return false;
        }
        public bool TryAuthenticate(Dictionary <string, string> digestHeaders, string PrivateKey, int NonceTimeOut, string sequence, out UserAuth userAuth)
        {
            //userId = null;
            userAuth = GetUserAuthByUserName(digestHeaders["username"]);
            if (userAuth == null)
            {
                return(false);
            }

            var digestHelper = new DigestAuthFunctions();

            if (digestHelper.ValidateResponse(digestHeaders, PrivateKey, NonceTimeOut, userAuth.DigestHA1Hash, sequence))
            {
                //userId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
                return(true);
            }
            userAuth = null;
            return(false);
        }
        public UserAuth CreateUserAuth(UserAuth newUser, string password)
        {
            ValidateNewUser(newUser, password);

            return dbFactory.Exec(dbCmd => {
                AssertNoExistingUser(dbCmd, newUser);

                var saltedHash = new SaltedHash();
                string salt;
                string hash;
                saltedHash.GetHashAndSaltString(password, out hash, out salt);

                newUser.PasswordHash = hash;
                newUser.Salt = salt;
                newUser.CreatedDate = DateTime.UtcNow;
                newUser.ModifiedDate = newUser.CreatedDate;

                dbCmd.Insert(newUser);

                newUser = dbCmd.GetById<UserAuth>(dbCmd.GetLastInsertId());
                return newUser;
            });
        }
        public void SaveUserAuth(UserAuth userAuth)
        {
            userAuth.ModifiedDate = DateTime.UtcNow;
            if (userAuth.CreatedDate == default(DateTime))
                userAuth.CreatedDate = userAuth.ModifiedDate;

            using (var redis = factory.GetClient())
            {
                redis.Store(userAuth);

                var userId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
                if (!userAuth.UserName.IsNullOrEmpty())
                    redis.SetEntryInHash(IndexUserNameToUserId, userAuth.UserName, userId);
                if (!userAuth.Email.IsNullOrEmpty())
                    redis.SetEntryInHash(IndexEmailToUserId, userAuth.Email, userId);
            }
        }
        public bool TryAuthenticate(string userName, string password, out UserAuth userAuth)
        {
            //userId = null;
            userAuth = GetUserAuthByUserName(userName);
            if (userAuth == null) return false;

            var saltedHash = new SaltedHash();
            if (saltedHash.VerifyHashString(password, userAuth.PasswordHash, userAuth.Salt))
            {
                //userId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
                return true;
            }

            userAuth = null;
            return false;
        }
		public UserAuth UpdateUserAuth(UserAuth existingUser, UserAuth newUser, string password)
		{
			ValidateNewUser(newUser, password);

			AssertNoExistingUser(mongoDatabase, newUser, existingUser);

			var hash = existingUser.PasswordHash;
			var salt = existingUser.Salt;
            if (password != null)
			{
				var saltedHash = new SaltedHash();
				saltedHash.GetHashAndSaltString(password, out hash, out salt);
			}
            // If either one changes the digest hash has to be recalculated
            var digestHash = existingUser.DigestHA1Hash;
            if (password != null || existingUser.UserName != newUser.UserName)
            {
                var digestHelper = new DigestAuthFunctions();
                digestHash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
            }
			newUser.Id = existingUser.Id;
			newUser.PasswordHash = hash;
			newUser.Salt = salt;
            newUser.DigestHA1Hash = digestHash;
			newUser.CreatedDate = existingUser.CreatedDate;
			newUser.ModifiedDate = DateTime.UtcNow;

			var collection = mongoDatabase.GetCollection<UserAuth>("UserAuth");
			collection.Insert(newUser);

			return newUser;
		}
        public UserAuth UpdateUserAuth(UserAuth existingUser, UserAuth newUser, string password)
        {
            ValidateNewUser(newUser, password);

            return dbFactory.Exec(dbCmd => {
                AssertNoExistingUser(dbCmd, newUser, existingUser);

                var hash = existingUser.PasswordHash;
                var salt = existingUser.Salt;
                if (password != null)
                {
                    var saltedHash = new SaltedHash();
                    saltedHash.GetHashAndSaltString(password, out hash, out salt);
                }
                // If either one changes the digest hash has to be recalculated
                var digestHash = existingUser.DigestHA1Hash;
                if (password != null || existingUser.UserName != newUser.UserName)
                {
                    var digestHelper = new DigestAuthFunctions();
                    digestHash = digestHelper.CreateHa1(newUser.UserName, DigestAuthProvider.Realm, password);
                }
                newUser.Id = existingUser.Id;
                newUser.PasswordHash = hash;
                newUser.Salt = salt;
                newUser.DigestHA1Hash = digestHash;
                newUser.CreatedDate = existingUser.CreatedDate;
                newUser.ModifiedDate = DateTime.UtcNow;

                dbCmd.Save(newUser);

                return newUser;
            });
        }
 private void AssertNoExistingUser(IRedisClientFacade redis, UserAuth newUser, UserAuth exceptForExistingUser = null)
 {
     if (newUser.UserName != null)
     {
         var existingUser = GetUserAuthByUserName(redis, newUser.UserName);
         if (existingUser != null &&
             (exceptForExistingUser == null || existingUser.Id != exceptForExistingUser.Id))
         {
             throw new ArgumentException("User {0} already exists".Fmt(newUser.UserName));
         }
     }
     if (newUser.Email != null)
     {
         var existingUser = GetUserAuthByUserName(redis, newUser.Email);
         if (existingUser != null &&
             (exceptForExistingUser == null || existingUser.Id != exceptForExistingUser.Id))
         {
             throw new ArgumentException("Email {0} already exists".Fmt(newUser.Email));
         }
     }
 }