internal static string LoginImp(string userName, string password)
        {
            SetupImp();

            if (System.Web.HttpContext.Current != null)
            {
                Securable s = new Securable(typeof(ApplicationExceptionSecureService).FullName);
                IPRegistered ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);

                ipr = AddIPImp(s);

                // ipr.SessionsCreated = ipr.SessionsCreated + 1;
                // ipr.Update();
                // IPSessionRegistration

                CheckIPImp(s, ipr);
            }

            ModelSession ms = new ModelSession(GenerateSessionTokenImp());
            CreateSessionImp(ref ms, userName, password);

            return ms.SessionToken;
        }
        internal static void RegisterIPFailureImp(Securable s, IPRegistered ipr)
        {
            ipr.Failures = ipr.Failures + 1;

            if (ipr.Failures >= s.AllowedIPFailures)
            {
                ipr.Allowed = false;
                ipr.DenialIssuedUntilTime = DateTime.Now.AddMinutes(s.IPFailureTimeDenying);
            }

            ipr.Update();
        }
        internal static string LoginAnonymousImp()
        {
            SetupImp();

            Securable s = new Securable(typeof(ApplicationExceptionSecureService).FullName);

            if (!s.AllowAnonymousAccess)
                return null;

            if (System.Web.HttpContext.Current != null)
            {
                IPRegistered ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);

                ipr = AddIPImp(s);

                // ipr.SessionsCreated = ipr.SessionsCreated + 1;
                // ipr.Update();
                // IPSessionRegistration

                CheckIPImp(s, ipr);
            }

            ModelSession ms = new ModelSession(GenerateSessionTokenImp());
            ms.User = new ModelUser("Everyone");
            ms.TimeIssued = DateTime.Now;
            ms.TimeIssuedFor = s.TimeSessionIsIssued;
            ms.Create();

            return ms.SessionToken;
        }
        internal static void CreateSessionImp(ref ModelSession ms, string userName, string password)
        {
            if (userName.ToLowerInvariant() == "everyone")
                throw new InvalidOperationException("Wrong API call for anonymous access.");

            Securable s = new Securable(typeof(ApplicationExceptionSecureService).FullName);

            ModelUser mu = new ModelUser(userName);
            if (!mu.Exists)
            {
                if (System.Web.HttpContext.Current != null)
                {
                    IPRegistered ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);
                    RegisterIPFailureImp(s, ipr);
                }

                throw new UnauthorizedAccessException("Access Denied");
            }

            if (!Platform.Runtime.Security.Hash.VerifyHash(password, "SHA512", mu.PasswordHash))
            {
                if (System.Web.HttpContext.Current != null)
                {
                    IPRegistered ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);
                    RegisterIPFailureImp(s, ipr);
                }

                throw new UnauthorizedAccessException("Access Denied");
            }

            if (!mu.Enabled && !ApplicationExceptionSecureService.CheckUserRightsImp(userName, "CannotBeDisabled"))
            {
                if (System.Web.HttpContext.Current != null)
                {
                    IPRegistered ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);
                    RegisterIPFailureImp(s, ipr);
                }

                throw new UnauthorizedAccessException("Access Denied"); // LoginDisabledException
            }

            ms.User = mu;
            ms.TimeIssued = DateTime.Now;
            ms.TimeIssuedFor = s.TimeSessionIsIssued;
            ms.Create();
        }
        internal static ModelSession CheckSessionImp(string sessionToken)
        {
            // Mark IP first
            Securable s = null;
            IPRegistered ipr = null;
            if (System.Web.HttpContext.Current != null)
            {
                s = new Securable(typeof(ApplicationExceptionSecureService).FullName);
                ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);

                CheckIPImp(s, ipr);
            }
            else
            {
                // What other unique data can be gathered?
            }

            if (String.IsNullOrEmpty(sessionToken))
            {
                // Invalid data is a security error
                if (s != null)
                    RegisterIPFailureImp(s, ipr);

                throw new UnauthorizedAccessException("The session is invalid");
            }

            // Check the consistency of the session
            ModelSession session = new ModelSession(sessionToken.ToLowerInvariant());
            if (!session.Exists)
            {
                if (s != null)
                    RegisterIPFailureImp(s, ipr);

                throw new UnauthorizedAccessException("The session is invalid");
            }

            if (session.User == null)
            {
                if (s != null)
                    RegisterIPFailureImp(s, ipr);

                session.Delete();
                throw new UnauthorizedAccessException("The session is invalid");
            }

            DateTime until = session.TimeIssued.AddMinutes(session.TimeIssuedFor);
            if (until < DateTime.Now)
            {
                session.Delete();
                throw new UnauthorizedAccessException("Your session has expired");
            }

            return session;
        }
        internal static void CheckIPImp(Securable s, IPRegistered ipr)
        {
            if (!ipr.Exists)
            {
                throw new UnauthorizedAccessException("IP has not been authenticated in any way");
            }

            if (!ipr.Allowed && ipr.DenialIssuedUntilTime >= DateTime.Now)
            {
                throw new UnauthorizedAccessException("IP has been blocked until " + ipr.DenialIssuedUntilTime.ToString() + " (Server time)");
            }
            else if (!ipr.Allowed)
            {
                ipr.Allowed = true;
                ipr.Failures = 0;
                ipr.Update();
            }
            else
            {
                ipr.DenialIssuedUntilTime = DateTime.Now;
                ipr.Update();
            }

            // Very expensive
            /*if (!ipr.SessionsRegisteredOnIP.Count >= s.SessionsPerIPAllowed)
            {
                // Check how many are valid (also clean up the expired ones)
                throw new UnauthorizedAccessException("Too many sessions");
            }*/
        }
        internal static IPRegistered AddIPImp(Securable s)
        {
            IPRegistered ipr = null;
            if (System.Web.HttpContext.Current != null)
            {
                ipr = new IPRegistered(System.Web.HttpContext.Current.Request.UserHostAddress);

                if (!ipr.Exists)
                {
                    if (!s.IPsMustBePreregistered)
                    {
                        ipr.Allowed = true;
                        ipr.DenialIssuedUntilTime = DateTime.Now;
                        ipr.Create();
                    }
                    else
                        throw new UnauthorizedAccessException("Your IP is not registered in our allowed range");
                }
                else
                {
                    CheckIPImp(s, ipr);
                }
            }

            return ipr;
        }