Ejemplo n.º 1
0
        public void testMD5()
        {
            var hash = new SecureHash("MD5");
            var h    = hash.Hash("123456").ToUpper();

            Assert.AreEqual(h, "E10ADC3949BA59ABBE56E057F20F883E");
        }
Ejemplo n.º 2
0
        public void DocumentConstructorThrowsArgumentNullExceptionIfCompressionNullOnOverloadedConstructor()
        {
            IAes        aes  = new Aes();
            ISecureHash hash = new SecureHash();

            new DocumentOverload(aes, hash, null, null, null);
        }
        public void HashFunctions(string testValue)
        {
            //Use a for loop to similate gen sequence.
            var hashString1 = SecureHash.CreateHash(testValue);
            var hashString2 = SecureHash.CreateHash(testValue);

            Assert.NotEqual(hashString1, hashString2); //two hashes in a row should not be equal as they are salted;

            var hashString3 = SecureHash.CreateHash(testValue + " ");

            Assert.True(SecureHash.ValidateHash(testValue, hashString1));
            Assert.True(SecureHash.ValidateHash(testValue, hashString2));

            Assert.False(SecureHash.ValidateHash(testValue, hashString3));
            Assert.False(SecureHash.ValidateHash(testValue + "1", hashString1));

            var uniqueHash1 = UniqueHash.CreateHash(testValue);
            var uniqueHash2 = UniqueHash.CreateHash(testValue);

            Assert.Equal(uniqueHash1, uniqueHash2);

            var uniqueHash3 = UniqueHash.CreateHash(testValue + " ");

            Assert.NotEqual(uniqueHash1, uniqueHash3);
        }
Ejemplo n.º 4
0
        private async Task <MemoryStream> CreateAppSettingsFile(RemoteAgentSettings settings, CancellationToken cancellationToken)
        {
            var remoteSettings = new RemoteSettings();

            // copy any settings across.
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.AppSettings);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Network);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Permissions);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Plugins);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Alerts);
            //TODO these should be copied by the copy properties.
            remoteSettings.Permissions.AllowedHubs  = settings.RemoteApplicationSettings.AllowedHubs;
            remoteSettings.Permissions.AllowedPaths = settings.RemoteApplicationSettings.AllowedPaths;
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Privacy);
            remoteSettings.NamingStandards.LoadDefault();

            remoteSettings.AppSettings.UserPrompt = false;
            remoteSettings.AppSettings.WebServer  = (HttpContext.Request.IsHttps ? "https://" : "http://") +
                                                    HttpContext.Request.Host + HttpContext.Request.PathBase.Value;
            remoteSettings.AppSettings.RemoteAgentId = Guid.NewGuid().ToString();

            var user = await _operations.RepositoryManager.GetUserAsync(User, cancellationToken);

            var dbRemoteAgent = new DexihRemoteAgent()
            {
                RemoteAgentId = remoteSettings.AppSettings.RemoteAgentId,
                RestrictIp    = false,
                Name          = remoteSettings.AppSettings.Name,
                UserId        = user.Id
            };

            if (settings.EmbedUserName)
            {
                remoteSettings.AppSettings.UserToken = await _operations.RepositoryManager.GenerateRemoteUserTokenAsync(user, remoteSettings.AppSettings.RemoteAgentId, cancellationToken);

                var hashedToken = SecureHash.CreateHash(remoteSettings.AppSettings.UserToken);
                dbRemoteAgent.HashedToken       = hashedToken;
                remoteSettings.AppSettings.User = user.UserName;
            }

            if (settings.RemoteApplicationSettings.AutoGenerateCertificate)
            {
                remoteSettings.Network.CertificateFilename = "dexih.pfx";
                remoteSettings.Network.CertificatePassword = EncryptString.GenerateRandomKey();
            }

            remoteSettings.Logging.LogLevel.Default   = settings.LogLevel;
            remoteSettings.Logging.LogLevel.System    = settings.LogLevel;
            remoteSettings.Logging.LogLevel.Microsoft = settings.LogLevel;

            await _operations.RepositoryManager.SaveRemoteAgent(user.Id, dbRemoteAgent, cancellationToken);

            var json = JsonSerializer.Serialize(remoteSettings, new JsonSerializerOptions()
            {
                WriteIndented = true
            });
            var appSettingsStream = new MemoryStream(Encoding.ASCII.GetBytes(json));

            return(appSettingsStream);
        }
Ejemplo n.º 5
0
        public void DocumentConstructorThrowsArgumentNullExceptionIfPasswordNullOnOverloadedConstructor()
        {
            IAes         aes         = new Aes();
            ISecureHash  hash        = new SecureHash();
            ICompression compression = new GZipCompression();

            new DocumentOverload(aes, hash, compression, null, null);
        }
Ejemplo n.º 6
0
        public void ComputeHashCreatesHashOfSomeInputDataAndItIs256BitsInLength()
        {
            var data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            ISecureHash hash       = new SecureHash();
            var         hashedData = hash.ComputeHash(data);

            Assert.AreEqual(32, hashedData.Length);
        }
Ejemplo n.º 7
0
        public void ComputeHashCreatesHashOfSomeInputDataAndItIsDifferentToInputData()
        {
            var data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            ISecureHash hash       = new SecureHash();
            var         hashedData = hash.ComputeHash(data);

            Assert.IsTrue(ByteArrayCompare(data, hashedData));
        }
Ejemplo n.º 8
0
        public void DocumentConstructorThrowsArgumentNullExceptionIfFileProxyNullOnOverloadedConstructor()
        {
            IAes         aes         = new Aes();
            ISecureHash  hash        = new SecureHash();
            ICompression compression = new GZipCompression();
            IPassword    password    = new Password("password1", "password2");

            new DocumentOverload(aes, hash, compression, password, null);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Validates a text given a hash of the correct one.
        /// </summary>
        /// <param name="text">The text to check.</param>
        /// <param name="goodHash">A hash to compare with.</param>
        /// <returns>True if it matches. False otherwise.</returns>
        public bool Validate(string text, SecureHash goodHash)
        {
            // Extract the parameters from the hash

            byte[] salt = Convert.FromBase64String(goodHash.Salt);
            byte[] hash = Convert.FromBase64String(goodHash.HashedText);

            byte[] testHash = PBKDF2(text, salt, PBKDF2_ITERATIONS, hash.Length);
            return(SlowEquals(hash, testHash));
        }
Ejemplo n.º 10
0
        public void ComputeHashCreatesHashOfSomeInputData()
        {
            var data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            ISecureHash hash = new SecureHash();

            byte[] hashedData = hash.ComputeHash(data);

            Assert.IsNotNull(hashedData);
        }
Ejemplo n.º 11
0
        public void DocumentConstructorAssignsPasswordFromTheOverloadedConstructor()
        {
            IAes         aes         = new Aes();
            ISecureHash  hash        = new SecureHash();
            IPassword    password    = new Password("password1", "password2");
            IFileProxy   fileProxy   = new FileProxy();
            ICompression compression = new GZipCompression();

            var document = new DocumentOverload(aes, hash, compression, password, fileProxy);

            Assert.AreEqual(password, document.Password);
        }
Ejemplo n.º 12
0
        public void SaveThrowsArgumentNullExceptionIfFileNameIsNull()
        {
            IAes         aes         = new Aes();
            ISecureHash  hash        = new SecureHash();
            IPassword    password    = new Password("password1", "password2");
            IFileProxy   fileProxy   = new FileProxy();
            ICompression compression = new GZipCompression();

            var document = new DocumentOverload(aes, hash, compression, password, fileProxy);

            document.Save(null);
        }
Ejemplo n.º 13
0
        public bool Update(long userLoginId, SecureHash usedSecureHash, long createdByOrgRoleUserId)
        {
            var passwordlist = _passwordChangelogRepository.GetOldPasswordList(userLoginId);
            var count        = _configurationSettingRepository.GetConfigurationValue(ConfigurationSettingName.PreviousPasswordNonRepetitionCount);

            if (passwordlist == null || passwordlist.Count() < Convert.ToInt32(count))
            {
                var passwordChangeLog = new PasswordChangelog()
                {
                    UserLoginId            = userLoginId,
                    CreatedByOrgRoleUserId = createdByOrgRoleUserId,
                    Password    = usedSecureHash.HashedText,
                    Salt        = usedSecureHash.Salt,
                    DateCreated = DateTime.Now,
                    Sequence    = passwordlist == null ?1: passwordlist.Count() + 1
                };
                return(_passwordChangelogRepository.Save(passwordChangeLog));
            }

            if (passwordlist.Count() > Convert.ToInt32(count))
            {
                var extraInDb       = passwordlist.Count() - Convert.ToInt32(count);
                var toBeDeletedList = passwordlist.OrderBy(x => x.Sequence).Take(extraInDb);

                foreach (var passwordChangelog in toBeDeletedList)
                {
                    _passwordChangelogRepository.Delete(passwordChangelog);
                }
                passwordlist.ToList().ForEach(x => x.Sequence = x.Sequence - extraInDb);
                passwordlist = passwordlist.Where(x => !toBeDeletedList.Select(d => d.Id).Contains(x.Id));
            }

            if (passwordlist.Any())
            {
                var oldestPassword = passwordlist.OrderBy(x => x.Sequence).First();
                passwordlist.ToList().ForEach(x => x.Sequence = x.Sequence - 1);
                oldestPassword.Sequence               = Convert.ToInt32(count);
                oldestPassword.UserLoginId            = userLoginId;
                oldestPassword.CreatedByOrgRoleUserId = createdByOrgRoleUserId;
                oldestPassword.Password               = usedSecureHash.HashedText;
                oldestPassword.Salt        = usedSecureHash.Salt;
                oldestPassword.DateCreated = DateTime.Now;

                foreach (var passwordChangeLog in passwordlist)
                {
                    _passwordChangelogRepository.Save(passwordChangeLog);
                }
            }

            return(true);
        }
Ejemplo n.º 14
0
        public void Save(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            var salt       = GenerateSalt(32);
            var encrypted3 = EncryptData(salt);

            var hash          = new SecureHash().ComputeHash(encrypted3);
            var versionNumber = new [] { Major, Minor };

            SaveFormattedFile(fileName, encrypted3, hash, salt, versionNumber);
        }
Ejemplo n.º 15
0
        public Password(string password1, string password2)
        {
            if (string.IsNullOrEmpty(password1))
            {
                throw new ArgumentNullException(nameof(password1));
            }

            var optionalPassword2 = password2 ?? string.Empty;

            Password1 = new SecureHash().ComputeHash(Encoding.ASCII.GetBytes(password1));
            Password2 = new SecureHash().ComputeHash(Encoding.ASCII.GetBytes(optionalPassword2));

            BCryptPassword1 = new BCryptHash().ComputeHash(Encoding.ASCII.GetBytes(password1));
            BCryptPassword2 = new BCryptHash().ComputeHash(Encoding.ASCII.GetBytes(optionalPassword2));

            CombinedPasswords = new BCryptHash().ComputeHash(Encoding.ASCII.GetBytes(password1 + optionalPassword2));
        }
Ejemplo n.º 16
0
        public void SetPassword(string id, string password)
        {
            using (var connection = new SqlConnection("Data Source=db-mssql;Initial Catalog=s19041;Integrated Security=True"))
                using (var command = new SqlCommand())
                {
                    command.Connection = connection;
                    connection.Open();

                    var salt = SecureHash.CreateSalt();
                    Console.WriteLine(salt);
                    var passwordHash = SecureHash.Create(password, salt);
                    command.CommandText = "update Student set Password=@Password, Salt=@Salt where IndexNumber=@IndexNumber";
                    command.Parameters.AddWithValue("Password", passwordHash);
                    command.Parameters.AddWithValue("Salt", salt);
                    command.Parameters.AddWithValue("IndexNumber", id);
                    command.ExecuteNonQuery();
                }
        }
Ejemplo n.º 17
0
 public bool CheckPassword(LoginRequest loginRequest)
 {
     using (var connection =
                new SqlConnection("Data Source=db-mssql;Initial Catalog=s19041;Integrated Security=True"))
         using (var command = new SqlCommand())
         {
             command.Connection = connection;
             connection.Open();
             command.CommandText = "SELECT Password,Salt FROM Student WHERE @IndexNumber=IndexNumber";
             command.Parameters.AddWithValue("IndexNumber", loginRequest.Index);
             var reader = command.ExecuteReader();
             if (reader.Read())
             {
                 return(SecureHash.Validate(loginRequest.Password, reader["Salt"].ToString(), reader["Password"].ToString()));
             }
             else
             {
                 return(false);
             }
         }
 }
Ejemplo n.º 18
0
 public SingleKeyScheme(int id, SecureHash keyHash, bool producer, bool consumer)
     : base(id, keyHash, producer, consumer)
 {
 }
Ejemplo n.º 19
0
 public void Setup()
 {
     secureHash = new SecureHash();
 }
Ejemplo n.º 20
0
 public DualKeyScheme(int id, SecureHash keyHash)
     : base(id, keyHash, true, true)
 {
 }
Ejemplo n.º 21
0
 public KeyScheme(int id, SecureHash keyHash, bool producer, bool consumer)
 {
     this.Id = id;
     this.Producer = producer;
     this.Consumer = consumer;
     this.KeyHash = keyHash;
     this.name = CreateName();
 }
Ejemplo n.º 22
0
        public void ComputeHashThrowsArgumentNullExceptionIfDataToHashedIsNull()
        {
            ISecureHash hash = new SecureHash();

            hash.ComputeHash(null);
        }
Ejemplo n.º 23
0
        public UserEditModel Save(UserEditModel userToSave)
        {
            _userModelValidator.ValidateAndThrow(userToSave);

            var userAddress = _addressService.SaveAfterSanitizing(Mapper.Map <AddressEditModel, Address>(userToSave.Address));
            OrganizationRoleUser organizationRoleUser = Mapper.Map <OrganizationRoleUserModel, OrganizationRoleUser>(_sessionContext.UserSession.CurrentOrganizationRole);

            userToSave.DataRecorderMetaData = new DataRecorderMetaData(organizationRoleUser, DateTime.Now, DateTime.Now);

            var        user = Mapper.Map <UserEditModel, User>(userToSave);
            var        isPasswordUpdatedOrCreated = false;
            SecureHash secureHash = null;

            if (userToSave.Id > 0 && string.IsNullOrEmpty(userToSave.Password))
            {
                var existingUser = _userRepository.GetUser(userToSave.Id);
                user.UserLogin.Password               = existingUser.UserLogin.Password;
                user.UserLogin.Salt                   = existingUser.UserLogin.Salt;
                user.UserLogin.UserVerified           = existingUser.UserLogin.UserVerified;//For a scenario: User is created and then immediatly updated
                user.UserLogin.LastPasswordChangeDate = existingUser.UserLogin.LastPasswordChangeDate;
                user.UserLogin.LastLogged             = existingUser.UserLogin.LastLogged;
            }
            else if (!string.IsNullOrEmpty(userToSave.Password))
            {
                secureHash = _oneWayHashingService.CreateHash(userToSave.Password);
                user.UserLogin.Password               = secureHash.HashedText;
                user.UserLogin.Salt                   = secureHash.Salt;
                isPasswordUpdatedOrCreated            = true;
                user.UserLogin.LastPasswordChangeDate = DateTime.Now;
            }

            user.Address = userAddress;
            if (isPasswordUpdatedOrCreated)//&& user.Id > 0 && userToSave.UsersRoles.Count() == 1 && userToSave.UsersRoles.Single().RoleId == (long)Roles.Customer)
            {
                user.UserLogin.UserVerified = false;
            }

            user.UserLogin.IsTwoFactorAuthrequired = userToSave.OverRideTwoFactorAuthrequired ? userToSave.IsTwoFactorAuthrequired : (bool?)null;


            user = _userRepository.SaveUser(user);
            if (isPasswordUpdatedOrCreated && secureHash != null && !(user.Id > 0 && userToSave.UsersRoles.Count() == 1 && userToSave.UsersRoles.Single().RoleId == (long)Roles.Customer))
            {
                _passwordChangelogService.Update(user.Id, secureHash, _sessionContext.UserSession.CurrentOrganizationRole.OrganizationRoleUserId);
            }

            userToSave.Id = user.Id;
            //map & save user roles
            _orgRoleUserRepository.DeactivateAllOrganizationRolesForUser(user.Id);
            foreach (var organizationRoleModel in userToSave.UsersRoles)
            {
                organizationRoleModel.UserId = user.Id;
                var orgRoleUser = _orgRoleUserRepository.SaveOrganizationRoleUser(Mapper.Map <OrganizationRoleUserModel, OrganizationRoleUser>(organizationRoleModel));
                var roleId      = GetParentRoleIdByRoleId(orgRoleUser.RoleId);
                switch (roleId)
                {
                case (long)Roles.Technician:
                    var technician = Mapper.Map <TechnicianModel, Technician>(userToSave.TechnicianProfile);
                    technician.TechnicianId = orgRoleUser.Id;
                    var repository = ((IRepository <Technician>)_technicianRepository);
                    repository.Save(technician);
                    if (!string.IsNullOrWhiteSpace(userToSave.TechnicianProfile.Pin))
                    {
                        _pinChangeLogService.Update(userToSave.TechnicianProfile.Pin.Encrypt(), orgRoleUser.Id, organizationRoleUser.Id);
                    }
                    break;

                case (long)Roles.MedicalVendorUser:
                    var physician = Mapper.Map <PhysicianModel, Physician>(userToSave.PhysicianProfile);
                    physician.PhysicianId             = orgRoleUser.Id;
                    physician.AuthorizedStateLicenses =
                        _physicianLicenseModelFactory.CreateMultiple(userToSave.PhysicianProfile.Licenses,
                                                                     orgRoleUser.Id);
                    _physicianRepository.SavePhysician(physician);
                    break;

                case (long)Roles.CorporateAccountCoordinator:
                    var accountCoordinator = Mapper.Map <AccountCoordinatorProfileModel, AccountCoordinatorProfile>(userToSave.AccountCoordinatorProfile);
                    accountCoordinator.AccountCoordinatorId = orgRoleUser.Id;
                    var accountCoordinatorRepository = ((IRepository <AccountCoordinatorProfile>)_accountCoordinatorProfileRepository);
                    accountCoordinatorRepository.Save(accountCoordinator);
                    break;

                case (long)Roles.CallCenterRep:
                    var callCenterRepProfile = new CallCenterRepProfile
                    {
                        CallCenterRepId = orgRoleUser.Id,
                        CanRefund       = false,
                        CanChangeNotes  = false,
                        DialerUrl       = organizationRoleModel.DialerUrl
                    };
                    _callCenterRepProfileRepository.Save(callCenterRepProfile);
                    break;
                }
            }

            if (userToSave.UsersRoles.Any(x => x.RoleId == (long)Roles.NursePractitioner))
            {
                var userNpiInfo = new UserNpiInfo
                {
                    UserId     = userToSave.Id,
                    Npi        = !string.IsNullOrEmpty(userToSave.Npi) ? userToSave.Npi : null,
                    Credential = !string.IsNullOrEmpty(userToSave.Credential) ? userToSave.Credential : null
                };
                _userNpiInfoRepository.Save(userNpiInfo);
            }

            var systemUserInfo = new SystemUserInfo
            {
                EmployeeId = userToSave.UsersRoles.Count() == 1 && userToSave.UsersRoles.Any(x => x.RoleId == (long)Roles.Customer) ? string.Empty : userToSave.EmployeeId,
                UserId     = userToSave.Id
            };

            _systemUserInfoRepository.Save(systemUserInfo);

            return(userToSave); //this does not return the same object. the saved user are out of sync at this point.!!
        }
Ejemplo n.º 24
0
        public async Task <JsonResult> Login([FromBody] RemoteSettings remoteSettings, CancellationToken cancellationToken)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    _logger.LogInformation(LoggingEvents.RemoteLogin, "Login - Remote Agent Login {user}, {servername}, remoteAgentId {remoteAgentId}, version {version}", User, remoteSettings.AppSettings.User, remoteSettings.AppSettings.Name, remoteSettings.Runtime.Version);

                    var user = await _operations.RepositoryManager.GetUserFromLoginAsync(remoteSettings.AppSettings.User, cancellationToken);

                    if (user == null)
                    {
                        _logger.LogWarning(LoggingEvents.RemoteLogin, "Login - Invalid remote login attempt using Email: " + User);
                        return(Json(new { Success = false, Message = "Invalid login attempt." }));
                    }

                    if (remoteSettings.Runtime.Version.Substring(0, 7) != "1.0-rc.")
                    {
                        _logger.LogWarning(LoggingEvents.RemoteLogin, "Login - Invalid remote login attempt incorrect version: " + remoteSettings.Runtime.Version + " from login: "******"The remote agent version number is not compatible with the current integration hub web site.  Please update." }));
                    }

                    var remoteIp = GetRequestIP(true);
                    if (remoteIp == "::1")
                    {
                        remoteIp = "127.0.0.1";
                    }

                    _logger.LogInformation(LoggingEvents.RemoteLogin, "Login - Remote Agent Login {user}, {servername}, remoteAgentId {remoteAgentId}, version {version}, ipAddress {ipAddress}", User, remoteSettings.AppSettings.User, remoteSettings.AppSettings.Name, remoteSettings.Runtime.Version, remoteIp);

                    var dbRemoteAgent = await _operations.RepositoryManager.RemoteAgentLogin(remoteIp, remoteSettings.AppSettings.RemoteAgentId, cancellationToken);

                    bool authenticated;
                    if (!string.IsNullOrEmpty(remoteSettings.AppSettings.UserToken))
                    {
                        if (dbRemoteAgent == null)
                        {
                            return(Json(new { Success = false, Message = $"The specified remoteAgentId does not exist, cannot be used from this ip address ({remoteIp}) or has been revoked." }));
                        }

                        authenticated = await _operations.RepositoryManager.VerifyUserTokenAsync(user, remoteSettings.AppSettings.RemoteAgentId, remoteSettings.AppSettings.UserToken, cancellationToken);

                        if (!authenticated)
                        {
                            return(Json(new { Success = false, Message = "The authentication token provided is invalid." }));
                        }

                        // validate the login token.
                        var storedUserToken = dbRemoteAgent.HashedToken;
                        var passed          = SecureHash.ValidateHash(remoteSettings.AppSettings.UserToken, storedUserToken);

                        if (!passed)
                        {
                            return(Json(new { Success = false, Message = "The UserToken/RemoteID did not match the current value for this user.  Please generate a new token." }));
                        }
                    }
                    else if (!string.IsNullOrEmpty(remoteSettings.Runtime.Password))
                    {
                        var result = await _signInManager.PasswordSignInAsync(user, remoteSettings.Runtime.Password, false, lockoutOnFailure : false);

                        authenticated = result.Succeeded;
                        remoteSettings.Runtime.GenerateUserToken = true;
                    }
                    else
                    {
                        return(Json(new { Success = false, Message = "There was no password or authentication token provided." }));
                    }

                    var newUserToken = "";

                    if (authenticated && remoteSettings.Runtime.GenerateUserToken)
                    {
                        if (string.IsNullOrEmpty(remoteSettings.Runtime.Password))
                        {
                            return(Json(new { Success = false, Message = "To generate a new user token, a password must be specified." }));
                        }

                        if (dbRemoteAgent == null)
                        {
                            dbRemoteAgent = new DexihRemoteAgent()
                            {
                                UserId        = user.Id,
                                RestrictIp    = true,
                                IpAddresses   = new [] { remoteIp },
                                Name          = remoteSettings.AppSettings.Name,
                                RemoteAgentId = remoteSettings.AppSettings.RemoteAgentId,
                            };
                        }
                        else
                        {
                            if (dbRemoteAgent.UserId != user.Id)
                            {
                                return(Json(new { Success = false, Message = "The remote agent can not be updated as it is registered with a different user id." }));
                            }

                            dbRemoteAgent.Name = remoteSettings.AppSettings.Name;

                            if (dbRemoteAgent.RestrictIp && !(dbRemoteAgent.IpAddresses != null && dbRemoteAgent.IpAddresses.Contains(remoteIp)))
                            {
                                if (dbRemoteAgent.IpAddresses == null)
                                {
                                    dbRemoteAgent.IpAddresses = new [] { remoteIp };
                                }
                                else
                                {
                                    dbRemoteAgent.IpAddresses = dbRemoteAgent.IpAddresses.Append(remoteIp).ToArray();
                                }
                            }
                        }

                        newUserToken = await _operations.RepositoryManager.GenerateRemoteUserTokenAsync(user, remoteSettings.AppSettings.RemoteAgentId, cancellationToken);

                        // hash the token so that it's not stored in plain text.
                        var hashedToken = SecureHash.CreateHash(newUserToken);

                        dbRemoteAgent.HashedToken = hashedToken;

                        dbRemoteAgent = await _operations.RepositoryManager.SaveRemoteAgent(user.Id, dbRemoteAgent, cancellationToken);
                    }

                    if (authenticated)
                    {
                        if (dbRemoteAgent == null)
                        {
                            return(Json(new { Success = false, Message = $"There is no remote agent registered with the id {remoteSettings.AppSettings.RemoteAgentId} ." }));
                        }

                        if (dbRemoteAgent.UserId != user.Id)
                        {
                            return(Json(new { Success = false, Message = $"There user {user.Email} is not associated with this remote agent {remoteSettings.AppSettings.RemoteAgentId} ." }));
                        }

                        if (dbRemoteAgent.RestrictIp && !(dbRemoteAgent.IpAddresses != null && dbRemoteAgent.IpAddresses.Contains(remoteIp)))
                        {
                            return(Json(new { Success = false, Message = $"The remote agent has restrictions on the IP, and the IP address {remoteIp} is not allowed.." }));
                        }

                        if (dbRemoteAgent.Name != remoteSettings.AppSettings.Name)
                        {
                            dbRemoteAgent.Name = remoteSettings.AppSettings.Name;
                            await _operations.RepositoryManager.SaveRemoteAgent(dbRemoteAgent.UserId, dbRemoteAgent, cancellationToken);
                        }

                        await _signInManager.RefreshSignInAsync(user);

                        // create a hash of the userid, which is used as part of the dynamic url.
                        var userHash = user.Id.CreateSHA1();

                        // create a security key, which is not sent the the browser client, and used to ensure the instance id hasn't been hijacked by another remote agent.
                        var(instanceId, securityToken) = await _remoteServers.AuthorizeRemoteAgent(remoteSettings.AppSettings.Name, dbRemoteAgent.RemoteAgentKey, remoteSettings.AppSettings.EncryptionKey, remoteIp, user.Id, cancellationToken);

                        return(Json(new {
                            Success = true,
                            instanceId,
                            securityToken,
                            UserToken = newUserToken,
                            IpAddress = remoteIp,
                            Message = "Login success",
                            UserHash = userHash,
                            _operations.Config.DefaultProxyUrl,
                            dbRemoteAgent.RemoteAgentKey
                        }));
                    }
                    else
                    {
                        return(Json(new { Success = false, Message = "Invalid password or revoked security token." }));
                    }
                }

                // If we got this far, something failed, redisplay form
                return(Json(new { Success = false, Message = "Login failed." }));
            }
            catch (Exception ex)
            {
                return(Json(new ReturnValue(false, "An unexpected error occurred logging in: message: " + ex.Message, ex)));
            }
        }