Simulator.SimulatedAccounts.GetBenignAccountAtRandomUniform C# (CSharp) Method

GetBenignAccountAtRandomUniform() public method

public GetBenignAccountAtRandomUniform ( ) : SimulatedUserAccount
return SimulatedUserAccount
        public SimulatedUserAccount GetBenignAccountAtRandomUniform()
        {
            return BenignAccounts[(int) StrongRandomNumberGenerator.Get32Bits(BenignAccounts.Count)];
        }

Usage Example

        /// <summary>
        /// Get a benign login attempt to simulate
        /// </summary>
        /// <returns></returns>
        public SimulatedLoginAttempt BenignLoginAttempt(DateTime eventTimeUtc)
        {
            // If there is a benign login attempt already scheduled to occur by now,
            // send it instaed
            lock (ScheduledBenignAttempts)
            {
                if (ScheduledBenignAttempts.Count > 0 &&
                    ScheduledBenignAttempts.First().TimeOfAttemptUtc < eventTimeUtc)
                {
                    SimulatedLoginAttempt result = ScheduledBenignAttempts.First();
                    ScheduledBenignAttempts.Remove(result);
                    return(result);
                }
            }

            string mistake = "";
            //1. Pick a user at random
            SimulatedUserAccount account = _simAccounts.BenignAccountSelector.GetItemByWeightedRandom();

            //2. Deal with cookies
            string cookie;

            // Add a new cookie if there are no cookies, or with if we haven't reached the max number of cookies and lose a roll of the dice
            if (account.Cookies.Count == 0 ||
                (account.Cookies.Count < _experimentalConfiguration.MaxCookiesPerUserAccount && StrongRandomNumberGenerator.GetFraction() > _experimentalConfiguration.ChanceOfCoookieReUse))
            {
                // We'll use the decimal represenation of a 64-bit unsigned integer as our cookie
                cookie = StrongRandomNumberGenerator.Get64Bits().ToString();
                account.Cookies.Add(cookie);
            }
            else
            {
                // Use one of the user's existing cookies selected at random
                cookie = account.Cookies.ToArray()[(int)StrongRandomNumberGenerator.Get32Bits(account.Cookies.Count)];
            }

            //Console.WriteLine("The user currently has " + account.Cookies.Count + " cookies.  Using: " + cookie);

            //3. Choose an IP address for the login
            // 1/3 of times login with the primary IP address, otherwise, choose an IP randomly from the benign IP pool
            IPAddress clientIp;

            if (account.ClientAddresses.Count == 0 ||
                (account.ClientAddresses.Count < _experimentalConfiguration.MaxIpPerUserAccount && StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfIpReUse))
            {
                // Use a new IP for the user
                account.ClientAddresses.Add(clientIp = _ipPool.GetNewRandomBenignIp());
            }
            else
            {
                // Use one of the user's existing IP Addresses selected at random
                clientIp = account.ClientAddresses.ToArray()[(int)StrongRandomNumberGenerator.Get32Bits(account.ClientAddresses.Count)];
            }

            string password = account.Password;

            //
            // Add benign failures

            // An automated client begins a string of login attempts using an old (stale) password
            if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfLongRepeatOfStalePassword)
            {
                // To cause this client to be out of date, we'll change the password here.
                string newPassword = _simPasswords.GetPasswordFromWeightedDistribution();
                _userAccountController.SetPassword(account, newPassword, account.Password);
                mistake += "StalePassword";

                // Schedule all the future failed attempts a fixed distance aparat
                lock (ScheduledBenignAttempts)
                {
                    double   additionalMistakes = 0;
                    DateTime currentTimeUtc     = eventTimeUtc;
                    for (additionalMistakes = 1; additionalMistakes < _experimentalConfiguration.LengthOfLongRepeatOfOldPassword; additionalMistakes++)
                    {
                        currentTimeUtc = currentTimeUtc.AddSeconds(_experimentalConfiguration.MinutesBetweenLongRepeatOfOldPassword);
                        ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                        account, password, false, false, clientIp, cookie, mistake, currentTimeUtc));
                    }
                    for (uint correctLogins = 1; correctLogins < _experimentalConfiguration.LengthOfLongRepeatOfOldPassword; correctLogins++)
                    {
                        currentTimeUtc = currentTimeUtc.AddSeconds(_experimentalConfiguration.MinutesBetweenLongRepeatOfOldPassword);
                        ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                        account, newPassword, false, false, clientIp, cookie, mistake, currentTimeUtc));
                    }
                }
            }

            // The benign user may mistype her password causing a typo
            if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfBenignPasswordTypo)
            {
                mistake += "Typo";
                // Typos tend to come in clusters, and are hopefully followed by a correct login
                // Add additional typos to the schedule of future benign attempts and then a submission of the correct password
                lock (ScheduledBenignAttempts)
                {
                    double additionalMistakes = 0;
                    while (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfRepeatTypo)
                    {
                        ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                        account, AddTypoToPassword(password), false, false, clientIp, cookie, mistake,
                                                        eventTimeUtc.AddSeconds(_experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * ++additionalMistakes)));
                    }
                    // Add a correct login after the string of typos
                    ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                    account, password, false, false, clientIp, cookie, "", eventTimeUtc.AddSeconds(
                                                        _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * (1 + additionalMistakes))));
                }
                // Put the typo into the password for the first typo failure, to be returned by this function.
                password = AddTypoToPassword(password);
            }

            // The benign user may mistakenly use a password for another of her accounts, which we draw from same distribution
            // we used to generate user account passwords
            if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfAccidentallyUsingAnotherAccountPassword)
            {
                mistake += "WrongPassword";

                // Choices of the wrong account password may come in clusters, and are hopefully followed by a correct login
                // Add additional typos to the schedule of future benign attempts and then a submission of the correct password
                lock (ScheduledBenignAttempts)
                {
                    double additionalMistakes = 0;
                    while (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfRepeatUseOfPasswordFromAnotherAccount)
                    {
                        ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                        account, _simPasswords.GetPasswordFromWeightedDistribution(), false, false, clientIp, cookie,
                                                        mistake, eventTimeUtc.AddSeconds(_experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * ++additionalMistakes)));
                    }
                    // Add a correct login after mistakes
                    ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                    account, password, false, false, clientIp, cookie, "", eventTimeUtc.AddSeconds(
                                                        _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * (additionalMistakes + 1))));
                }

                // Make the current request have the wrong password
                password = _simPasswords.GetPasswordFromWeightedDistribution();
            }

            // The benign user may mistype her account name, and land on someone else's account name
            if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfBenignAccountNameTypoResultingInAValidUserName)
            {
                mistake += "WrongAccountName";

                // Choices of the wrong account password may come in clusters, and are hopefully followed by a correct login
                // Add additional typos to the schedule of future benign attempts and then a submission of the correct password
                lock (ScheduledBenignAttempts)
                {
                    double additionalMistakes = 0;
                    while (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfRepeatWrongAccountName)
                    {
                        ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                        _simAccounts.GetBenignAccountAtRandomUniform(), password, false, false, clientIp, cookie, mistake, eventTimeUtc.AddSeconds(
                                                            _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * ++additionalMistakes)));
                    }
                    // Add a correct login after mistakes
                    ScheduledBenignAttempts.Add(new SimulatedLoginAttempt(
                                                    account, password, false, false, clientIp, cookie, "", eventTimeUtc.AddSeconds(
                                                        _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * (additionalMistakes + 1))));

                    // Make the current request have the wrong account name
                    account = _simAccounts.GetBenignAccountAtRandomUniform();
                }
            }

            return(new SimulatedLoginAttempt(account, password, false, false, clientIp, cookie, mistake, eventTimeUtc));
        }