public IStatusGeneric DeleteRole(string roleName, bool removeFromUsers,
                                         ExtraAuthorizeDbContext context)
        {
            var status = new StatusGenericHandler {
                Message = "Deleted role successfully."
            };
            var roleToUpdate = context.Find <RoleToPermissions>(roleName);

            if (roleToUpdate == null)
            {
                return(status.AddError("That role doesn't exists"));
            }

            var usersWithRoles = context.UserToRoles.Where(x => x.RoleName == roleName).ToList();

            if (usersWithRoles.Any())
            {
                if (!removeFromUsers)
                {
                    return(status.AddError($"That role is used by {usersWithRoles.Count} and you didn't ask for them to be updated."));
                }

                context.RemoveRange(usersWithRoles);
                status.Message = $"Removed role from {usersWithRoles.Count} user and then deleted role successfully.";
            }

            context.Remove(roleToUpdate);
            return(status);
        }
        public async Task TestAddRoleToUseTrigger()
        {
            //SETUP
            var fakeAuthChanges = new FakeAuthChanges();
            var options         = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                context.Database.EnsureCreated();
                var rolToPer = RoleToPermissions.CreateRoleWithPermissions
                                   ("test", "test", new List <Permissions> {
                    Permissions.AccessAll
                }, context).Result;
                context.Add(rolToPer);
                context.SaveChanges();
                fakeAuthChanges.Clear();

                //ATTEMPT
                var userToRole = new UserToRole("test", rolToPer);
                context.Add(userToRole);
                await context.SaveChangesAsync();

                //VERIFY
                fakeAuthChanges.CacheValueSet.ShouldBeTrue();
                context.UserToRoles.Count().ShouldEqual(1);
            }
        }
        /// <summary>
        /// This is called if the Permissions that a user needs calculating.
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task <string> CalcPermissionsForUser(ClaimsPrincipal user)
        {
            var usersRoles = user.Claims.Where(x => x.Type == ClaimTypes.Role).Select(x => x.Value)
                             .ToList();

            using (var dbContext = new ExtraAuthorizeDbContext(_extraAuthDbContextOptions))
            {
                //This gets all the permissions, with a distinct to remove duplicates
                var permissionsForUser = await dbContext.RolesToPermissions.Where(x => usersRoles.Contains(x.RoleName))
                                         .SelectMany(x => x.PermissionsInRole)
                                         .Distinct()
                                         .ToListAsync();

                //we get the modules this user is allowed to see
                var userModules =
                    dbContext.ModulesForUsers.Find(user.Claims.SingleOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value)
                    ?.AllowedPaidForModules ?? PaidForModules.None;
                //Now we remove permissions that are linked to modules that the user has no access to
                var filteredPermissions =
                    from permission in permissionsForUser
                    let moduleAttr = typeof(Permissions).GetMember(permission.ToString())[0]
                                     .GetCustomAttribute <LinkedToModuleAttribute>()
                                     where moduleAttr == null || userModules.HasFlag(moduleAttr.PaidForModule)
                                     select permission;

                return(filteredPermissions.PackPermissionsIntoString());
            }
        }
        public void TestUpdateRoleTrigger()
        {
            //SETUP
            var fakeAuthChanges = new FakeAuthChanges();
            var options         = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                context.Database.EnsureCreated();
                var rolToPer = RoleToPermissions.CreateRoleWithPermissions
                                   ("test", "test", new List <Permissions> {
                    Permissions.AccessAll
                }, context).Result;
                context.Add(rolToPer);
                context.SaveChanges();

                //ATTEMPT
                rolToPer.Update("updated", new List <Permissions> {
                    Permissions.EmployeeRead
                });
                context.SaveChanges();

                //VERIFY
                fakeAuthChanges.CacheValueSet.ShouldBeTrue();
                context.RolesToPermissions.Count().ShouldEqual(1);
            }
        }
示例#5
0
        public void TestUpdatePermissionsInRole()
        {
            //SETUP
            var fakeAuthChanges = new FakeAuthChanges();
            var options         = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                context.Database.EnsureCreated();

                var createStatus = RoleToPermissions.CreateRoleWithPermissions(
                    "test", "test", new List <Permissions> {
                    Permissions.StockRead
                }, context);
                createStatus.IsValid.ShouldBeTrue(createStatus.GetAllErrors());
                context.Add(createStatus.Result);
                context.SaveChanges();

                //ATTEMPT
                var roleToUpdate = context.Find <RoleToPermissions>("test");
                roleToUpdate.Update("new name", new List <Permissions> {
                    Permissions.StockAddNew, Permissions.StockRemove
                });
                context.SaveChanges();
            }
            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                //VERIFY
                context.RolesToPermissions.Single().Description.ShouldEqual("new name");
                context.RolesToPermissions.Single().PermissionsInRole
                .ShouldEqual(new List <Permissions> {
                    Permissions.StockAddNew, Permissions.StockRemove
                });
            }
        }
示例#6
0
        public void TestDeleteRole()
        {
            //SETUP
            var fakeAuthChanges = new FakeAuthChanges();
            var options         = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                context.Database.EnsureCreated();
                var createStatus = RoleToPermissions.CreateRoleWithPermissions(
                    "test", "test", new List <Permissions> {
                    Permissions.StockRead
                }, context);
                createStatus.IsValid.ShouldBeTrue(createStatus.GetAllErrors());
                context.Add(createStatus.Result);
                context.SaveChanges();

                //ATTEMPT
                var roleToDelete = context.Find <RoleToPermissions>("test");
                context.Remove(roleToDelete);
                context.SaveChanges();

                //VERIFY
                context.RolesToPermissions.Any().ShouldBeFalse();
            }
        }
        public IActionResult Index([FromServices] ApplicationDbContext applicationDbContext,
                                   [FromServices] ExtraAuthorizeDbContext extraAuthorizeDbContext)
        {
            var userLister = new ListUsers(applicationDbContext, extraAuthorizeDbContext);
            var roleLister = new ListRoles(extraAuthorizeDbContext);

            return(View(new HomePageDto(userLister.ListUserWithRolesAndModules(), roleLister.ListRolesWithPermissionsExplained().ToList())));
        }
示例#8
0
 public AddPermissionsToUserClaims(
     UserManager <IdentityUser> userManager,
     RoleManager <IdentityRole> roleManager,
     IOptions <IdentityOptions> optionsAccessor,
     ExtraAuthorizeDbContext extraAuthDbContext)
     : base(userManager, roleManager, optionsAccessor)
 {
     _extraAuthDbContext = extraAuthDbContext;
 }
示例#9
0
        public async Task ValidateAsync(CookieValidatePrincipalContext context)
        {
            if (context.Principal.Claims.Any(x => x.Type == PermissionConstants.PackedPermissionClaimType))
            {
                return;
            }

            //No permissions in the claims so we need to add it
            //This is only happen once after the user has logged in
            var claims = new List <Claim>();

            foreach (var claim in context.Principal.Claims)
            {
                claims.Add(claim);
            }

            var usersRoles = context.Principal.Claims.Where(x => x.Type == ClaimTypes.Role).Select(x => x.Value)
                             .ToList();

            //I can't inject the DbContext here because that is dynamic, but I can pass in the database options because that is a singleton
            //From that I can create a valid dbContext to access the database
            using (var dbContext = new ExtraAuthorizeDbContext(_extraAuthDbContextOptions))
            {
                //This gets all the permissions, with a distinct to remove duplicates
                var permissionsForUser = await dbContext.RolesToPermissions.Where(x => usersRoles.Contains(x.RoleName))
                                         .SelectMany(x => x.PermissionsInRole)
                                         .Distinct()
                                         .ToListAsync();

                //we get the modules this user is allows to see
                var userModules =
                    dbContext.ModulesForUsers.Find(context.Principal.Claims.SingleOrDefault(x => x.Type == ClaimTypes.Name).Value)
                    ?.AllowedPaidForModules ?? PaidForModules.None;
                //Now we remove permissions that are linked to modules that the user has no access to
                var filteredPermissions =
                    from permission in permissionsForUser
                    let moduleAttr = typeof(Permissions).GetMember(permission.ToString())[0]
                                     .GetCustomAttribute <LinkedToModuleAttribute>()
                                     where moduleAttr == null || userModules.HasFlag(moduleAttr.PaidForModule)
                                     select permission;

                //Now add it to the claim
                claims.Add(new Claim(PermissionConstants.PackedPermissionClaimType,
                                     filteredPermissions.PackPermissionsIntoString()));
            }

            var identity     = new ClaimsIdentity(claims, "Cookie");
            var newPrincipal = new ClaimsPrincipal(identity);

            context.ReplacePrincipal(newPrincipal);
            context.ShouldRenew = true;
        }
示例#10
0
        public static IStatusGeneric <RoleToPermissions> CreateRoleWithPermissions(string roleName, string description, ICollection <Permissions> permissionInRole,
                                                                                   ExtraAuthorizeDbContext context)
        {
            var status = new StatusGenericHandler <RoleToPermissions>();

            if (context.Find <RoleToPermissions>(roleName) != null)
            {
                status.AddError("That role already exists");
                return(status);
            }

            return(status.SetResult(new RoleToPermissions(roleName, description, permissionInRole)));
        }
        protected virtual void Dispose(bool disposing)
        {
            if (_extraAuthDbContextOptions != null && _context != null)
            {
                if (disposing)
                {
                    _context.Dispose();
                }

                // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
                // TODO: set large fields to null.
                _context = null;
            }
        }
示例#12
0
        public void TestGetValueFromStoreNoContent()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                var result = context.GetValueFromStore("test");

                //VERIFY
                result.ShouldBeNull();
            }
        }
        /// <summary>
        /// This will set up the user's feature permissions if either of the following states are found
        /// - The current claims doesn't have the PackedPermissionClaimType. This happens when someone logs in.
        /// - If the LastPermissionsUpdatedClaimType is missing (null) or is a lower number that is stored in the TimeStore cache.
        /// It will also add a HierarchicalKeyClaimName claim with the user's data key if not present.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task ValidateAsync(CookieValidatePrincipalContext context)
        {
            var extraContext = new ExtraAuthorizeDbContext(_extraAuthContextOptions, _authChanges);
            //now we set up the lazy values - I used Lazy for performance reasons, as 99.9% of the time the lazy parts aren't needed
            // ReSharper disable once AccessToDisposedClosure
            var rtoPLazy = new Lazy <CalcAllowedPermissions>(() => new CalcAllowedPermissions(extraContext));
            // ReSharper disable once AccessToDisposedClosure
            var dataKeyLazy = new Lazy <CalcDataKey>(() => new CalcDataKey(extraContext));

            var originalClaims = context.Principal.Claims.ToList();
            var impHandler     = new ImpersonationHandler(context.HttpContext, _protectionProvider, originalClaims);

            var newClaims = new List <Claim>();

            if (originalClaims.All(x => x.Type != PermissionConstants.PackedPermissionClaimType) ||
                impHandler.ImpersonationChange ||
                _authChanges.IsOutOfDateOrMissing(AuthChangesConsts.FeatureCacheKey,
                                                  originalClaims.SingleOrDefault(x => x.Type == PermissionConstants.LastPermissionsUpdatedClaimType)?.Value,
                                                  extraContext))
            {
                //Handle the feature permissions
                var userId = impHandler.GetUserIdForWorkingOutPermissions();
                newClaims.AddRange(await BuildFeatureClaimsAsync(userId, rtoPLazy.Value));
            }

            if (originalClaims.All(x => x.Type != DataAuthConstants.HierarchicalKeyClaimName) ||
                impHandler.ImpersonationChange)
            {
                var userId = impHandler.GetUserIdForWorkingDataKey();
                newClaims.AddRange(BuildDataClaims(userId, dataKeyLazy.Value));
            }

            if (newClaims.Any())
            {
                //Something has changed so we replace the current ClaimsPrincipal with a new one

                newClaims.AddRange(RemoveUpdatedClaimsFromOriginalClaims(originalClaims, newClaims)); //Copy over unchanged claims
                impHandler.AddOrRemoveImpersonationClaim(newClaims);
                //Build a new ClaimsPrincipal and use it to replace the current ClaimsPrincipal
                var identity     = new ClaimsIdentity(newClaims, "Cookie");
                var newPrincipal = new ClaimsPrincipal(identity);
                context.ReplacePrincipal(newPrincipal);
                //THIS IS IMPORTANT: This updates the cookie, otherwise this calc will be done every HTTP request
                context.ShouldRenew = true;
            }
            extraContext.Dispose(); //be tidy and dispose the context.
        }
示例#14
0
        public void TestTestAddUpdateNoExistingKey()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                context.AddUpdateValue("test", (long)1234);
                context.SaveChanges();

                //VERIFY
                context.TimeStores.Single().LastUpdatedTicks.ShouldEqual((long)1234);
            }
        }
示例#15
0
        public void TestGetValueFromStore()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                context.Database.EnsureCreated();
                context.AddUpdateValue("test", (long)1234);
                context.SaveChanges();

                //ATTEMPT
                var result = context.GetValueFromStore("test");

                //VERIFY
                result.ShouldEqual((long)1234);
            }
        }
示例#16
0
        public void TestSeedUserWithTwoRoles()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                context.SeedUserWithTwoRoles();
            }
            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                //VERIFY
                context.UserToRoles.Select(x => x.RoleName).ToArray().ShouldEqual(new[] { "TestRole1", "TestRole2" });
            }
        }
        public static void SeedCacheRole(this ExtraAuthorizeDbContext context, bool hasCache2, string userId = "userId")
        {
            var permissions = new List <Permissions> {
                Permissions.Cache1
            };

            if (hasCache2)
            {
                permissions.Add(Permissions.Cache2);
            }
            var userStatus = RoleToPermissions.CreateRoleWithPermissions(
                CacheRoleService.CacheRoleName, CacheRoleService.CacheRoleName, permissions, context);

            userStatus.IsValid.ShouldBeTrue(userStatus.GetAllErrors());
            context.Add(userStatus.Result);

            context.SaveChanges();
        }
示例#18
0
        public async Task TestSaveChangesAsyncOk()
        {
            //SETUP
            var options = this.CreateUniqueClassOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                var entity = RoleToPermissions.CreateRoleWithPermissions(Guid.NewGuid().ToString(), "description",
                                                                         new List <Permissions> {
                    Permissions.Cache1
                }, context).Result;
                context.Add(entity);
                var numWritten = await context.SaveChangesAsync();

                //VERIFY
                numWritten.ShouldEqual(1);
            }
        }
        public void TestSeedCacheRole(bool hasCache2)
        {
            //SETUP
            var fakeAuthChanges = new FakeAuthChanges();
            var options         = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                context.SeedCacheRole(hasCache2);
            }
            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                //VERIFY
                var role = context.RolesToPermissions.Single();
                role.RoleName.ShouldEqual(CacheRoleService.CacheRoleName);
                role.PermissionsInRole.Count().ShouldEqual(hasCache2 ? 2 : 1);
            }
        }
示例#20
0
        public async Task TestCalcPermissionsForUserAsyncWithModule()
        {
            //SETUP
            var fakeAuthChanges = new FakeAuthChanges();
            var options         = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeAuthChanges))
            {
                context.Database.EnsureCreated();
                context.SeedUserWithDefaultPermissions(PaidForModules.Feature1);

                var calc = new CalcAllowedPermissions(context);
                //ATTEMPT
                var packedP = await calc.CalcPermissionsForUserAsync("userId");

                //VERIFY
                packedP.UnpackPermissionsFromString().ShouldEqual(new List <Permissions> {
                    Permissions.StockRead, Permissions.Feature1Access
                });
            }
        }
        public void TestAddRoleNotTrigger()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, new AuthChanges()))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                var rolToPer = RoleToPermissions.CreateRoleWithPermissions
                                   ("test", "test", new List <Permissions> {
                    Permissions.AccessAll
                }, context).Result;
                context.Add(rolToPer);
                context.SaveChanges();

                //VERIFY
                context.TimeStores.Count().ShouldEqual(0);
                context.RolesToPermissions.Count().ShouldEqual(1);
            }
        }
        public void TestAddRoleNotTrigger()
        {
            //SETUP
            var fakeCache = new FakeSimpleCache();
            var options   = SqliteInMemory.CreateOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, fakeCache))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                var rolToPer = RoleToPermissions.CreateRoleWithPermissions
                                   ("test", "test", new List <Permissions> {
                    Permissions.AccessAll
                }, context).Result;
                context.Add(rolToPer);
                context.SaveChanges();

                //VERIFY
                fakeCache.AddOrUpdateCalled.ShouldBeFalse();
                context.RolesToPermissions.Count().ShouldEqual(1);
            }
        }
示例#23
0
        public void GetValueFromStorePerformance()
        {
            //SETUP
            var options = this.CreateUniqueClassOptions <ExtraAuthorizeDbContext>();

            using (var context = new ExtraAuthorizeDbContext(options, null))
            {
                context.Database.EnsureCreated();
                context.AddUpdateValue("test", (long)1234);
                context.SaveChanges();

                const int numTimes = 1000;
                //ATTEMPT

                using (new TimeThings(_output, "EFCore - startup", 10))
                {
                    for (int i = 0; i < 10; i++)
                    {
                        var result = context.GetValueFromStore("test");
                    }
                }
                using (new TimeThings(_output, "EFCore", numTimes))
                {
                    for (int i = 0; i < numTimes; i++)
                    {
                        var result = context.GetValueFromStore("test");
                    }
                }
                using (new TimeThings(_output, "EFCore", numTimes))
                {
                    for (int i = 0; i < numTimes; i++)
                    {
                        var result = context.GetValueFromStore("test");
                    }
                }
            }
        }
        public static void SeedUserWithDefaultPermissions(this ExtraAuthorizeDbContext context,
                                                          PaidForModules modules = PaidForModules.None, string userId = "userId")
        {
            var defaultPermissions = new List <Permissions> {
                Permissions.StockRead, Permissions.Feature1Access
            };

            var roleStatus = RoleToPermissions.CreateRoleWithPermissions(
                "TestRole1", "TestRole1", defaultPermissions, context);

            roleStatus.IsValid.ShouldBeTrue(roleStatus.GetAllErrors());
            context.Add(roleStatus.Result);

            var moduleUser = new ModulesForUser(userId, modules);

            context.Add(moduleUser);

            var userStatus = UserToRole.AddRoleToUser(userId, "TestRole1", context);

            userStatus.IsValid.ShouldBeTrue(roleStatus.GetAllErrors());
            context.Add(userStatus.Result);

            context.SaveChanges();
        }
示例#25
0
 public ExtraAuthUsersSetup(ExtraAuthorizeDbContext context)
 {
     _context = context;
 }
示例#26
0
 public CacheRoleService(ExtraAuthorizeDbContext context)
 {
     _context = context;
 }
示例#27
0
 public ListRoles(ExtraAuthorizeDbContext extraAuthorizeDbContext)
 {
     _extraAuthorizeDbContext = extraAuthorizeDbContext;
 }
 public CalcAllowedPermissions(ExtraAuthorizeDbContext context)
 {
     _context = context;
 }
        public static IStatusGeneric <UserToRole> AddRoleToUser(string userId, string roleName, ExtraAuthorizeDbContext context)
        {
            if (userId == null)
            {
                throw new ArgumentNullException(nameof(userId));
            }
            if (roleName == null)
            {
                throw new ArgumentNullException(nameof(roleName));
            }

            var status = new StatusGenericHandler <UserToRole>();

            if (context.Find <UserToRole>(userId, roleName) != null)
            {
                status.AddError($"The user already has the Role '{roleName}'.");
                return(status);
            }
            var roleToAdd = context.Find <RoleToPermissions>(roleName);

            if (roleToAdd == null)
            {
                status.AddError($"I could not find the Role '{roleName}'.");
                return(status);
            }

            return(status.SetResult(new UserToRole(userId, roleToAdd)));
        }
 public ListUsersService(UserManager <IdentityUser> userManager, ExtraAuthorizeDbContext extraContext)
 {
     _userManager  = userManager;
     _extraContext = extraContext;
 }