/// <summary>
        /// Policy configuration delegate passed into <see cref="PolicyServiceCollectionExtensions.AddAuthorization"/>.
        /// The default implementation adds a series of authorization policies for Cofoundry roles and permissions.
        /// </summary>
        /// <param name="options"></param>
        protected virtual void ConfigurePolicies(AuthorizationOptions options)
        {
            foreach (var userArea in _userAreaDefinitionRepository.GetAll())
            {
                var policyName      = AuthorizationPolicyNames.UserArea(userArea.UserAreaCode);
                var authRequirement = new UserAreaAuthorizationRequirement(userArea.UserAreaCode);
                options.AddPolicy(policyName, p => p.AddRequirements(authRequirement));
            }

            foreach (var role in _roleDefinitionRepository.GetAll())
            {
                var policyName      = AuthorizationPolicyNames.Role(role.UserAreaCode, role.RoleCode);
                var authRequirement = new RoleAuthorizationRequirement(role.UserAreaCode, role.RoleCode);
                options.AddPolicy(policyName, p => p.AddRequirements(authRequirement));
            }

            foreach (var permission in _permissionRepository.GetAll())
            {
                var policyName      = AuthorizationPolicyNames.Permission(permission);
                var authRequirement = new PermissionAuthorizationRequirement(permission);
                options.AddPolicy(policyName, p => p.AddRequirements(authRequirement));
            }
        }
예제 #2
0
        public async Task ExecuteAsync(RegisterPermissionsAndRolesCommand command, IExecutionContext executionContext)
        {
            // ENTITY DEFINITIONS

            var dbEntityDefinitions = await _dbContext
                                      .EntityDefinitions
                                      .ToDictionaryAsync(e => e.EntityDefinitionCode);

            await EnsureAllEntityDefinitionsExistAsync(dbEntityDefinitions);

            // PERMISSIONS

            // permissions already registered in the database
            var dbPermissions = await _dbContext
                                .Permissions
                                .ToDictionaryAsync(p => p.GetUniqueCode());

            // code-based permission objects
            var codePermissions = _permissionRepository.GetAll();

            var newCodePermissions = codePermissions
                                     .Where(p => !dbPermissions.ContainsKey(p.GetUniqueIdentifier()))
                                     .ToList();

            // Add new permissions to db

            AddNewPermissionsToDb(dbEntityDefinitions, dbPermissions, newCodePermissions);

            // ROLES

            var dbRoles = await _dbContext
                          .Roles
                          .Include(r => r.RolePermissions)
                          .ThenInclude(p => p.Permission)
                          .ToListAsync();

            var dbRolesWithCodes = dbRoles
                                   .Where(r => !string.IsNullOrEmpty(r.RoleCode))
                                   .ToDictionary(r => r.RoleCode.ToUpperInvariant());

            await EnsureUserAreaExistsAndValidatePermissionAsync(dbRoles, executionContext);

            foreach (var roleDefinition in _roleDefinitionRepository.GetAll())
            {
                var dbRole = dbRolesWithCodes.GetOrDefault(roleDefinition.RoleCode.ToUpperInvariant());

                if (dbRole == null)
                {
                    // New role
                    ValidateRole(dbRoles, roleDefinition);
                    dbRole = MapAndAddRole(roleDefinition);
                    UpdatePermissions(dbRole, roleDefinition, codePermissions, dbPermissions, dbEntityDefinitions, false);
                }
                else if (command.UpdateExistingRoles)
                {
                    // Existing role, to be updated to match initializer exactly
                    UpdatePermissions(dbRole, roleDefinition, codePermissions, dbPermissions, dbEntityDefinitions, true);
                }
                else
                {
                    // Update for new permissions only
                    UpdatePermissions(dbRole, roleDefinition, newCodePermissions, dbPermissions, dbEntityDefinitions, false);
                }
            }

            await _dbContext.SaveChangesAsync();

            _transactionScopeFactory.QueueCompletionTask(_dbContext, _roleCache.Clear);
        }