private Ban CreateBan(Login user, BanType banType)
        {
            TimeSpan?duration = Ban.CalculateDuration(user.Identity, banType);
            DateTime expirationDate;

            if (duration == TimeSpan.MaxValue)
            {
                expirationDate = SqlDateTime.MaxValue.Value;
            }
            else
            {
                expirationDate = DateTime.Now.Add(duration.Value);
            }

            return(new Ban()
            {
                BannedByLoginId = user.Id,
                BanType = banType,
                BanTypeId = banType.Id,
                DateCreated = DateTime.Now,
                DateExpires = expirationDate,
                InEffect = true,
                Login = user
            });
        }
        public void TestPermanentBanCalculations()
        {
            Initialize();

            DataAccess.BanClass banClass = new BanClass()
            {
                Id   = (int)BanClassType.Major,
                Name = "Major"
            };

            DataAccess.BanType banType = new BanType()
            {
                BanClass                      = banClass,
                BanClassId                    = banClass.Id,
                BaseTimeInMinutes             = 30,
                Description                   = "Permanent ban after one infraction.",
                IsIncremental                 = true,
                InfractionsBeforePermanentBan = 1,
                SrNumber                      = 13
            };

            DataAccess.Login    testUser = CreateUser(Guid.NewGuid().ToString().Substring(0, 20), "Test", "NA", 10);
            DataAccess.Identity identity = testUser.Identity;

            // Test 1x Ban - 30 minutes
            TimeSpan?duration = Ban.CalculateDuration(identity, banType);

            Assert.AreEqual(30, duration.Value.TotalMinutes);

            // Test 2x Ban - Permanent.
            testUser.Bans.Add(CreateBan(testUser, banType));
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(TimeSpan.MaxValue, duration.Value);

            // Test permanent ban on first infraction
            banType = new BanType()
            {
                BanClass                      = banClass,
                BanClassId                    = banClass.Id,
                BaseTimeInMinutes             = 30,
                Description                   = "Permanent ban on first infraction.",
                IsIncremental                 = true,
                InfractionsBeforePermanentBan = 0,
                SrNumber                      = 9
            };

            testUser = CreateUser(Guid.NewGuid().ToString().Substring(0, 20), "Test", "NA", 10);
            identity = testUser.Identity;

            // Test 1x Ban - Permanent.
            testUser.Bans.Add(CreateBan(testUser, banType));
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(TimeSpan.MaxValue, duration.Value);
        }
        internal bool SetBan()
        {
            using (var db = new CSSDataContext())
            {
                Ban ban = null;
                if (BanId != null)
                {
                    ban = db.Bans.Single(p => p.Id == BanId);
                }

                Login       admin;
                LoginStatus loginStatus;
                if (Login.TryGetAuthenticatedLogin(db, Username, Password, out admin, out loginStatus) == false)
                {
                    return(false);
                }

                var bannedLogin = Login.FindLoginByUsernameOrCallsign(db, Alias);
                if (bannedLogin == null)
                {
                    return(false);
                }

                var bannedAlias = DataAccess.Alias.GetAliasByCallsign(db, Alias);
                if (bannedAlias == null)
                {
                    return(false);
                }

                var bannedIdentity = bannedLogin.Identity;

                DateTime?dateExpires = null;
                BanType  banType     = null;
                if (BanMode == BanMode.Auto && BanTypeId != null)
                {
                    banType = db.BanTypes.FirstOrDefault(p => p.Id == BanTypeId);
                    var duration = Ban.CalculateDuration(bannedIdentity, banType);

                    if (duration == TimeSpan.MaxValue)
                    {
                        dateExpires = SqlDateTime.MaxValue.Value;
                    }
                    else
                    {
                        dateExpires = DateTime.Now.Add(duration.Value);
                    }
                }
                else if (BanMode == BanMode.Custom && Duration != null)
                {
                    if (Duration.Value == TimeSpan.MinValue)
                    {
                        dateExpires = SqlDateTime.MinValue.Value;
                    }
                    else
                    {
                        dateExpires = DateTime.Now.Add(Duration.Value);
                    }
                }
                else if (BanMode != BanMode.Permanent)
                {
                    throw new Exception("One or more needed parameters were not provided.");
                }
                else if (BanMode == BanMode.Permanent && !admin.Login_Roles.Any(p => p.RoleId == (int)RoleType.SuperAdministrator))
                {
                    throw new AuthenticationException("Only Super-Administrators may permanently ban a user.");
                }

                if (BanId == null)
                {
                    ban = new Ban()
                    {
                        DateCreated     = DateTime.Now,
                        DateExpires     = dateExpires,
                        BannedByLoginId = admin.Id,
                        LoginId         = bannedLogin.Id,
                        Reason          = Reason,
                        BanType         = banType,
                        InEffect        = true,
                        AliasID         = bannedAlias.Id
                    };
                    db.Bans.InsertOnSubmit(ban);

                    // Kill off any active sessions for the user which will log them out of the game immediatly.
                    db.Sessions.DeleteAllOnSubmit(db.Sessions.Where(p => p.LoginId == bannedLogin.Id));
                }
                else
                {
                    if (!admin.Login_Roles.Any(p => p.RoleId == (int)RoleType.SuperAdministrator))
                    {
                        throw new AuthenticationException("Only Super-Administrators may adjust a ban.");
                    }

                    if (Duration == null)
                    {
                        throw new Exception("Duration must be specified in order to edit a ban.");
                    }

                    if (!string.IsNullOrEmpty(Reason))
                    {
                        ban.Reason = Reason;
                    }

                    if (BanTypeId != null)
                    {
                        banType = db.BanTypes.FirstOrDefault(p => p.Id == BanTypeId);
                    }
                    else
                    {
                        banType = null;
                    }

                    ban.BanType = banType;

                    if (Duration.Value == TimeSpan.MinValue)
                    {
                        ban.DateExpires = SqlDateTime.MinValue.Value;
                    }
                    else
                    {
                        ban.DateExpires = DateTime.Now.Add(Duration.Value);
                    }
                }

                db.SubmitChanges();
                return(true);
            }
        }
        public void TestMajorBanDurationCalculations()
        {
            Initialize();

            DataAccess.BanClass banClass = new BanClass()
            {
                Id   = (int)BanClassType.Major,
                Name = "Major"
            };

            DataAccess.BanType banType = new BanType()
            {
                BanClass          = banClass,
                BanClassId        = banClass.Id,
                BaseTimeInMinutes = 30,
                Description       = "Major 30 minute ban.",
                IsIncremental     = true,
                SrNumber          = 4
            };

            DataAccess.Login    testUser = CreateUser(Guid.NewGuid().ToString().Substring(0, 20), "Test", "NA", 10);
            DataAccess.Identity identity = testUser.Identity;

            // Test 1x Ban - 30 minutes
            TimeSpan?duration = Ban.CalculateDuration(identity, banType);

            Assert.AreEqual(30, duration.Value.TotalMinutes);

            // Test 2x Ban - 120 minutes
            testUser.Bans.Add(CreateBan(testUser, banType));
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(120, duration.Value.TotalMinutes);

            // Test 3x Ban - 600 minutes
            testUser.Bans.Add(CreateBan(testUser, banType));
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(600, duration.Value.TotalMinutes);

            // Test 4x Minor Ban - 30 days
            testUser.Bans.Add(CreateBan(testUser, banType));
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(1440 * 30, duration.Value.TotalMinutes);

            /* TODO: re-add when proper logic is in place.
             * // Test 5x Ban - 60 days
             * identity.Bans.Add(CreateBan(testUser, banType));
             * duration = Ban.CalculateDuration(identity, banType);
             * Assert.AreEqual(1440 * 60, duration.Value.TotalMinutes);
             *
             * // Test 6x Ban - Permanent
             * identity.Bans.Add(CreateBan(testUser, banType));
             * duration = Ban.CalculateDuration(identity, banType);
             * Assert.AreEqual(1440 * 10, duration.Value.TotalMinutes);
             */

            // test rolling window for major bans.
            testUser.Bans.Clear();
            for (int i = 0; i < 3; i++)
            {
                testUser.Bans.Add(CreateBan(testUser, banType));
            }

            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(1440 * 30, duration.Value.TotalMinutes);

            // Test rolling window -- 4 recent bans
            testUser.Bans[0].DateCreated = DateTime.Now.AddDays(-180);
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(600, duration.Value.TotalMinutes);

            // Test rolling window -- 3 recent bans
            testUser.Bans[1].DateCreated = DateTime.Now.AddDays(-180);
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(120, duration.Value.TotalMinutes);

            // Test rolling window -- 2 recent bans
            testUser.Bans[2].DateCreated = DateTime.Now.AddDays(-180);
            duration = Ban.CalculateDuration(identity, banType);
            Assert.AreEqual(30, duration.Value.TotalMinutes);
        }
        public void TestMinorBanDurationCalculations()
        {
            Initialize();

            DataAccess.BanClass minorBanClass = new BanClass()
            {
                Id   = (int)BanClassType.Minor,
                Name = "Minor"
            };

            DataAccess.BanType minorBanType = new BanType()
            {
                BanClass          = minorBanClass,
                BanClassId        = minorBanClass.Id,
                BaseTimeInMinutes = 30,
                Description       = "Minor 30 minute ban.",
                IsIncremental     = true,
                RocNumber         = 1
            };

            DataAccess.Login    testUser = CreateUser(Guid.NewGuid().ToString().Substring(0, 20), "Test", "NA", 10);
            DataAccess.Identity identity = testUser.Identity;

            // Test 1x Minor Ban - 30 minutes
            TimeSpan?duration = Ban.CalculateDuration(identity, minorBanType);

            Assert.AreEqual(30, duration.Value.TotalMinutes);

            // Test 2x Minor Ban - 15 hours
            testUser.Bans.Add(CreateBan(testUser, minorBanType));
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(900, duration.Value.TotalMinutes);

            // Test 3x Minor Ban - 5 days
            testUser.Bans.Add(CreateBan(testUser, minorBanType));
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(7200, duration.Value.TotalMinutes);

            // Test 4x Minor Ban - 5 days
            testUser.Bans.Add(CreateBan(testUser, minorBanType));
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(7200, duration.Value.TotalMinutes);

            // Test 5x Minor Ban - 5 days
            testUser.Bans.Add(CreateBan(testUser, minorBanType));
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(7200, duration.Value.TotalMinutes);

            // Test 6x Minor Ban - 10 days
            testUser.Bans.Add(CreateBan(testUser, minorBanType));
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(1440 * 10, duration.Value.TotalMinutes);

            // TODO: re-add when proper logic is in place.
            //// Test 7x Minor Ban - 30 days
            //identity.Bans.Add(CreateBan(testUser, minorBanType));
            //duration = Ban.CalculateDuration(identity, minorBanType);
            //Assert.AreEqual(1440 * 30, duration.Value.TotalMinutes);

            //// Test 8x Minor Ban - 90 days
            //identity.Bans.Add(CreateBan(testUser, minorBanType));
            //duration = Ban.CalculateDuration(identity, minorBanType);
            //Assert.AreEqual(1440 * 90, duration.Value.TotalMinutes);

            //// Test 9x Minor Ban - 90 days
            //identity.Bans.Add(CreateBan(testUser, minorBanType));
            //duration = Ban.CalculateDuration(identity, minorBanType);
            //Assert.AreEqual(1440 * 90, duration.Value.TotalMinutes);

            // test rolling window for minor bans.
            testUser.Bans.Clear();
            for (int i = 0; i < 5; i++)
            {
                testUser.Bans.Add(CreateBan(testUser, minorBanType));
            }

            Assert.AreEqual(5, identity.Bans.Count());

            // Test rolling window -- 4 recent bans == 5 days
            testUser.Bans[0].DateCreated = DateTime.Now.AddDays(-91);
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(7200, duration.Value.TotalMinutes);

            // Test rolling window -- 3 recent bans == 5 days
            testUser.Bans[1].DateCreated = DateTime.Now.AddDays(-91);
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(7200, duration.Value.TotalMinutes);

            // Test rolling window -- 2 recent bans == 5 days
            testUser.Bans[2].DateCreated = DateTime.Now.AddDays(-91);
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(7200, duration.Value.TotalMinutes);

            // Test rolling window -- 1 recent ban == 15 hours
            testUser.Bans[3].DateCreated = DateTime.Now.AddDays(-91);
            duration = Ban.CalculateDuration(identity, minorBanType);
            Assert.AreEqual(900, duration.Value.TotalMinutes);

            // Test rolling window -- 0 recent bans == 30 minutes
            testUser.Bans[4].DateCreated = DateTime.Now.AddDays(-91);
            duration = Ban.CalculateDuration(testUser.Identity, minorBanType);
            Assert.AreEqual(30, duration.Value.TotalMinutes);
        }