// This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
        protected override bool AuthorizeCore(HttpContextBase context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            if (context.Request.Cookies[ConfigurationManager.AppSettings["CookieKey"]] == null)
                return false;

            var cookieValue = context.Request.Cookies[ConfigurationManager.AppSettings["CookieKey"]].Value;

            var data = Encoding.UTF8.GetString(Convert.FromBase64String(cookieValue)).Split('-');

            var userId = Convert.ToInt32(data[0]);
            var userEmail = data[1];

            var enableProfiling = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableProfiling"]);

            IDisposable _step = null;

            if (enableProfiling)
            {
                var _profiler = MiniProfiler.Current;
                _step = _profiler.Step("Get Session In AuthenticateAttribute");
            }

            var sessionRepository = new SessionRepository(ConfigurationManager.AppSettings["DataDbConnectionString"], userId);

            var session = sessionRepository.GetByKey(cookieValue);

            if (enableProfiling)
            {
                _step.Dispose();
            }

            if (session == null)
                return false;

            // If caching is enabled, this is the only place we can reliably set up the dependencies
            // TODO: Could these be added on first Cache.Add() if not already present?
            if (ConfigurationManager.AppSettings["EnableCaching"] != null && Convert.ToBoolean(ConfigurationManager.AppSettings["EnableCaching"]) == true)
            {
                var cacheConfiguration = new ModelCacheConfiguration();
                var cache = new ModelCache(cacheConfiguration);
                var cachingHelpers = new CachingHelpers(cacheConfiguration, userId);

                if (cache.Items.FirstOrDefault(x => x.Key == cachingHelpers.GetDependencyKey("all", userId.ToString())) == null)
                {
                    // Add the cache dependency items to the cache
                    // We have to manually add the user ID to the keys here because it wasn't necessarily present when the cache object was injected
                    cache.Add(cachingHelpers.GetDependencyKey("all", userId.ToString()), Guid.NewGuid().ToString(), (int)CacheExpiry.FifteenMinutes);
                    cache.Add(cachingHelpers.GetDependencyKey("user", userId.ToString()), Guid.NewGuid().ToString(), (int)CacheExpiry.FifteenMinutes);
                    cache.Add(cachingHelpers.GetDependencyKey("transaction", userId.ToString()), Guid.NewGuid().ToString(), (int)CacheExpiry.FifteenMinutes);
                    cache.Add(cachingHelpers.GetDependencyKey("budget", userId.ToString()), Guid.NewGuid().ToString(), (int)CacheExpiry.FifteenMinutes);
                    cache.Add(cachingHelpers.GetDependencyKey("account", userId.ToString()), Guid.NewGuid().ToString(), (int)CacheExpiry.FifteenMinutes);
                    cache.Add(cachingHelpers.GetDependencyKey("category", userId.ToString()), Guid.NewGuid().ToString(), (int)CacheExpiry.FifteenMinutes);
                }
            }

            context.Items.Add("UserID", userId);
            context.Items.Add("Email", userEmail);

            return true;
        }
        public void Data_Read_Sessions()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var data = repository.All().OrderBy(x => x.SessionID).ToList();

            // There are 4 test sessions, but only 1 current for this user
            Assert.IsTrue(data.Count == 1);
            Assert.IsTrue(data[0].SessionID == 1);
            Assert.IsTrue(data[0].Key == "USER1SESSION");
        }
        public void Data_Read_Session_By_Key()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var data = repository.GetByKey("USER1SESSION");

            Assert.IsTrue(data.SessionID == 1);
        }
        public void Data_Read_Other_User_Session()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var data = repository.Get(4);

            Assert.IsTrue(data == null);
        }
        public void Data_Read_Other_User_Session_By_Key()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var data = repository.GetByKey("USER2SESSION");

            Assert.IsTrue(data == null);
        }
        public void Data_Delete_Session_Expired()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            repository.DeleteExpired();

            var session = repository.Get(2);

            Assert.IsTrue(session == null);

            // Read the database directly and check the expired session is now marked as deleted
            using (var conn = new SqlConnection(_dataConnectionString))
            {
                conn.Open();

                var expiredSession = conn.Query<Session>("SELECT * FROM [dbo].[Sessions] WHERE [Key] = 'USER1SESSIONEXPIRED'").Single();

                Assert.IsTrue(expiredSession.Deleted == true);
                Assert.IsTrue(expiredSession.DeletedBy == 1);
                Assert.IsTrue(expiredSession.DeletedDate.Value.Date == DateTime.Now.Date);
            }
        }
        public void Data_Delete_Session_By_Key()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var result = repository.DeleteByKey("USER1SESSION");

            var session = repository.Get(1);

            Assert.IsTrue(session == null);
            Assert.IsTrue(result.Deleted == true);
            Assert.IsTrue(result.DeletedBy == 1);
            Assert.IsTrue(result.DeletedDate.Value.Date == DateTime.Now.Date);
        }
        public void Data_Create_Session()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var session = new MABMoney.Domain.Session {
                User_UserID = 1,
                Key = "ADDED",
                Expiry = new DateTime(2020, 1, 1)
            };

            var result = repository.Add(session);

            Assert.IsTrue(result.SessionID == 5);
            Assert.IsTrue(result.User_UserID == 1);
            Assert.IsTrue(result.Key == "ADDED");
            Assert.IsTrue(result.Expiry.Date == new DateTime(2020, 1, 1).Date);
            Assert.IsTrue(result.CreatedBy == 1);
            Assert.IsTrue(result.CreatedDate.Date == DateTime.Now.Date);
            Assert.IsTrue(result.LastModifiedBy == 1);
            Assert.IsTrue(result.LastModifiedDate.Date == DateTime.Now.Date);
        }
        public void Data_Update_Session_Expiry()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var result = repository.UpdateSessionExpiry("USER1SESSION", new DateTime(2020, 2, 2));

            Assert.IsTrue(result.Key == "USER1SESSION");
            Assert.IsTrue(result.Expiry.Date == new DateTime(2020, 2, 2).Date);
            Assert.IsTrue(result.LastModifiedBy == 1);
            Assert.IsTrue(result.LastModifiedDate.Date == DateTime.Now.Date);
        }
        public void Data_Update_Session()
        {
            var repository = new SessionRepository(_dataConnectionString, 1);

            var session = repository.Get(1);

            session.Key = "UPDATED";
            session.Expiry = new DateTime(2020, 2, 2);

            var result = repository.Update(session);

            Assert.IsTrue(result.Key == "UPDATED");
            Assert.IsTrue(result.Expiry.Date == new DateTime(2020, 2, 2).Date);
            Assert.IsTrue(result.LastModifiedBy == 1);
            Assert.IsTrue(result.LastModifiedDate.Date == DateTime.Now.Date);
        }