예제 #1
0
        public void AssertCurrentUserHasCapability(CapabilitiesAssertionSpec assertionSpec)
        {
            if (assertionSpec == null)
            {
                throw new ArgumentNullException(nameof(assertionSpec));
            }

            var capabilityType     = GetCapabilityType(assertionSpec.CapabilityAttribute);
            var requiredCapability = assertionSpec.CapabilityAttribute.RequiredCapability;
            var entityType         = entityTypeProvider.GetEntityType(requiredCapability);

            if (entityType == null)
            {
                throw new CapabilitiesCouldNotBeCheckedException($@"No entity type could be found to match the capability type {capabilityType}.
Every type of required capability must have a corresponding entity type, provided by the service {nameof(IGetsEntityTypeForCapability)}.
Have you forgotten to add the entity type to the default implementation of that service?");
            }

            if (logger.IsDebugEnabled)
            {
                logger.Debug($@"Executing {OpenGenericAssertMethod.Name} to assert that the user has required capabilities.
    Action name: {assertionSpec.ActionName}
    Entity type: {entityType.FullName}
Capability type: {capabilityType.FullName}");
            }

            // Need to use reflection to get into the generic method from a non-generic one.
            // The trade-off is worth it IMO, because it allows the rest of the capabilities stack 'from here downwards' to be strongly-typed.
            var method = OpenGenericAssertMethod.MakeGenericMethod(entityType, capabilityType);

            method.Invoke(this, new[] { assertionSpec.ParameterValue, requiredCapability, assertionSpec.ActionName });
        }
            Type GetEntityType(ParameterInfo param)
            {
                var capabilityAttribute = param.GetCustomAttribute <RequireCapabilityAttribute>();

                if (capabilityAttribute == null)
                {
                    return(null);
                }

                return(entityTypeProvider.GetEntityType(capabilityAttribute.RequiredCapability));
            }