public void ExpiringDictionary_GetAndRefreshOrCreate_Refreshes_If_Key_Exists()
        {
            using (var map = new ExpiringDictionary <int, string>(10, 1)) {
                map.Add(2, "kj");
                HeartbeatTick();

                _Clock.AddMilliseconds(10);
                Assert.AreEqual("kj", map.GetAndRefreshOrCreate(2, null));

                HeartbeatTick();
                Assert.AreEqual(1, map.Count);
            }
        }
Example #2
0
        /// <summary>
        /// Does all the work for <see cref="CheckAltitude"/> and <see cref="CheckPosition"/>.
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <typeparam name="TNullable"></typeparam>
        /// <param name="aircraftId"></param>
        /// <param name="timedValue"></param>
        /// <param name="map"></param>
        /// <param name="calculateCertainty"></param>
        /// <param name="findFirstValue"></param>
        /// <returns></returns>
        private Certainty CheckValue <TValue, TNullable>(
            int aircraftId,
            TimedValue <TValue> timedValue,
            ExpiringDictionary <int, ValueHistory <TValue, TNullable> > map,
            Func <bool, TimedValue <TValue>, TimedValue <TValue>, Certainty> calculateCertainty,
            Func <List <TimedValue <TValue> >, TNullable> findFirstValue
            )
        {
            var valueHistory = map.GetAndRefreshOrCreate(aircraftId, (unused) => new ValueHistory <TValue, TNullable>()
            {
                AircraftId = aircraftId,
            });

            if (valueHistory.RecordedFirstGoodValue && valueHistory.FirstGoodValue != null)
            {
                valueHistory.FirstGoodValue = default(TNullable);
            }

            var resetThreshold = timedValue.Time.AddSeconds(-ResetHistorySeconds);
            var resetOnMessage = valueHistory.PreviousValue;

            if (resetOnMessage != null && resetOnMessage.Time <= resetThreshold)
            {
                valueHistory.Reset();
            }

            var result        = Certainty.Uncertain;
            var previousValue = valueHistory.PreviousValue;

            valueHistory.AddValue(timedValue);

            if (previousValue != null)
            {
                result = calculateCertainty(valueHistory.PreviousValueIsGood, previousValue, timedValue);
                if (result != Certainty.ProbablyRight)
                {
                    valueHistory.Reset();
                }
                else
                {
                    if (!valueHistory.RecordedFirstGoodValue)
                    {
                        valueHistory.FirstGoodValue         = findFirstValue(valueHistory.History);
                        valueHistory.RecordedFirstGoodValue = true;
                    }
                    valueHistory.PreviousValueIsGood = true;
                }
            }

            return(result);
        }
Example #3
0
        /// <summary>
        /// Authenticates the request from the browser.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="requestArgs"></param>
        /// <returns></returns>
        private bool Authenticated(IContext context, RequestReceivedEventArgs requestArgs)
        {
            bool result = false;

            var authenticationScheme = AuthenticationScheme;
            var isAdministratorPath  = IsAdministratorPath(requestArgs);

            if (isAdministratorPath)
            {
                authenticationScheme = AuthenticationSchemes.Basic;
            }

            switch (authenticationScheme)
            {
            case AuthenticationSchemes.None:
            case AuthenticationSchemes.Anonymous:
                if (isAdministratorPath)
                {
                    throw new InvalidOperationException("Anonymous access to administrator paths is not supported");
                }
                result = true;
                break;

            case AuthenticationSchemes.Basic:
                bool useCache = CacheCredentials;
                if (useCache && context.BasicUserName != null)
                {
                    CachedCredential cachedCredential;
                    if (_AuthenticatedUserCache.TryGetValue(context.BasicUserName, out cachedCredential))
                    {
                        result = context.BasicPassword == cachedCredential.Password;
                        if (result)
                        {
                            result = !isAdministratorPath || cachedCredential.IsAdministrator;
                        }
                    }
                }

                if (!result)
                {
                    var args = new AuthenticationRequiredEventArgs(context.BasicUserName, context.BasicPassword);
                    OnAuthenticationRequired(args);
                    result = args.IsAuthenticated && (!isAdministratorPath || args.IsAdministrator);
                    if (result)
                    {
                        if (useCache && args.User != null)
                        {
                            var cachedCredential = new CachedCredential()
                            {
                                IsAdministrator = args.IsAdministrator,
                                Password        = context.BasicPassword,
                            };
                            _AuthenticatedUserCache.Add(context.BasicUserName, cachedCredential);
                        }
                    }
                    else
                    {
                        var failedLogin     = _FailedLoginAttempts.GetAndRefreshOrCreate(context.Request.RemoteEndPoint.Address, (unused) => new FailedLogin());
                        var sameCredentials = context.BasicUserName == failedLogin.User && context.BasicPassword == failedLogin.Password;
                        failedLogin.User     = context.BasicUserName;
                        failedLogin.Password = context.BasicPassword;
                        if (!sameCredentials)
                        {
                            if (failedLogin.Attempts < int.MaxValue)
                            {
                                ++failedLogin.Attempts;
                            }
                            if (failedLogin.Attempts > 2)
                            {
                                var pauseMilliseconds = (Math.Min(failedLogin.Attempts, 14) - 2) * 5000;
                                Thread.Sleep(pauseMilliseconds);
                            }
                        }

                        context.Response.StatusCode = HttpStatusCode.Unauthorized;
                        context.Response.AddHeader("WWW-Authenticate", String.Format(@"Basic Realm=""{0}""", Provider.ListenerRealm));
                    }
                }

                if (result)
                {
                    requestArgs.UserName = context.BasicUserName;
                }

                break;

            default:
                throw new NotImplementedException();
            }

            return(result);
        }