private static string GetAuthorizeMethodName(ChangeSetEntry entry)
        {
            switch (entry.Type)
            {
                case ChangeSetEntryType.DataModification:
                    DataModificationEntry dataModification = (DataModificationEntry)entry;
                    string operationName = null;
                    if (dataModification.IsNew)
                    {
                        operationName = ConventionBasedChangeSetConstants.AuthorizeMethodDataModificationInsert;
                    }
                    else if (dataModification.IsUpdate)
                    {
                        operationName = ConventionBasedChangeSetConstants.AuthorizeMethodDataModificationUpdate;
                    }
                    else if (dataModification.IsDelete)
                    {
                        operationName = ConventionBasedChangeSetConstants.AuthorizeMethodDataModificationDelete;
                    }

                    return operationName + dataModification.EntitySetName;

                case ChangeSetEntryType.ActionInvocation:
                    ActionInvocationEntry actionEntry = (ActionInvocationEntry)entry;
                    return ConventionBasedChangeSetConstants.AuthorizeMethodActionInvocationExecute +
                        actionEntry.ActionName;

                default:
                    throw new InvalidOperationException(string.Format(
                        CultureInfo.InvariantCulture, Resources.InvalidChangeSetEntryType, entry.Type));
            }
        }
        /// <inheritdoc/>
        public Task<bool> AuthorizeAsync(
            SubmitContext context,
            ChangeSetEntry entry,
            CancellationToken cancellationToken)
        {
            Ensure.NotNull(context, "context");
            bool result = true;

            Type returnType = typeof(bool);
            string methodName = ConventionBasedChangeSetAuthorizer.GetAuthorizeMethodName(entry);
            MethodInfo method = this.targetType.GetQualifiedMethod(methodName);

            if (method != null && method.IsFamily &&
                method.ReturnType == returnType)
            {
                object target = null;
                if (!method.IsStatic)
                {
                    target = context.GetApiService<ApiBase>();
                    if (target == null ||
                        !this.targetType.IsAssignableFrom(target.GetType()))
                    {
                        return Task.FromResult(result);
                    }
                }

                var parameters = method.GetParameters();
                if (parameters.Length == 0)
                {
                    result = (bool)method.Invoke(target, null);
                }
            }

            return Task.FromResult(result);
        }
 /// <inheritdoc/>
 public Task OnExecutedEntryAsync(
     SubmitContext context,
     ChangeSetEntry entry,
     CancellationToken cancellationToken)
 {
     return this.InvokeFilterMethodAsync(
         context, entry, ConventionBasedChangeSetConstants.FilterMethodNamePostFilterSuffix);
 }
        /// <inheritdoc/>
        public Task ValidateEntityAsync(
            SubmitContext context,
            ChangeSetEntry entry,
            ValidationResults validationResults,
            CancellationToken cancellationToken)
        {
            Ensure.NotNull(validationResults, "validationResults");
            DataModificationEntry dataModificationEntry = entry as DataModificationEntry;
            if (dataModificationEntry != null)
            {
                object entity = dataModificationEntry.Entity;

                // TODO GitHubIssue#50 : should this PropertyDescriptorCollection be cached?
                PropertyDescriptorCollection properties =
                    new DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider(entity.GetType())
                    .GetTypeDescriptor(entity).GetProperties();

                DataAnnotations.ValidationContext validationContext = new DataAnnotations.ValidationContext(entity);

                foreach (PropertyDescriptor property in properties)
                {
                    validationContext.MemberName = property.Name;

                    IEnumerable<DataAnnotations.ValidationAttribute> validationAttributes =
                        property.Attributes.OfType<DataAnnotations.ValidationAttribute>();
                    foreach (DataAnnotations.ValidationAttribute validationAttribute in validationAttributes)
                    {
                        object value = property.GetValue(entity);
                        DataAnnotations.ValidationResult validationResult =
                            validationAttribute.GetValidationResult(value, validationContext);
                        if (validationResult != DataAnnotations.ValidationResult.Success)
                        {
                            validationResults.Add(new ValidationResult()
                            {
                                Id = validationAttribute.GetType().FullName,
                                Message = validationResult.ErrorMessage,
                                Severity = ValidationSeverity.Error,
                                Target = entity,
                                PropertyName = property.Name
                            });
                        }
                    }
                }
            }

            return Task.WhenAll();
        }
        /// <inheritdoc/>
        public Task ValidateEntityAsync(
            SubmitContext context,
            ChangeSetEntry entry,
            ValidationResults validationResults,
            CancellationToken cancellationToken)
        {
            Ensure.NotNull(validationResults, "validationResults");
            DataModificationEntry dataModificationEntry = entry as DataModificationEntry;
            if (dataModificationEntry != null)
            {
                object entity = dataModificationEntry.Entity;

                // TODO (.NETCORE): Use PropertyDescriptorCollection in .NET Core (when available?)
                // TODO GitHubIssue#50 : should this PropertyDescriptorCollection be cached?
                IEnumerable<PropertyInfo> properties = entity.GetType().GetTypeInfo().DeclaredProperties;

                DataAnnotations.ValidationContext validationContext = new DataAnnotations.ValidationContext(entity);

                foreach (var property in properties)
                {
                    validationContext.MemberName = property.Name;

                    IEnumerable<DataAnnotations.ValidationAttribute> validationAttributes =
                        property.GetCustomAttributes().OfType<DataAnnotations.ValidationAttribute>();

                    foreach (var validationAttribute in validationAttributes)
                    {
                        object value = property.GetValue(entity);
                        DataAnnotations.ValidationResult validationResult =
                            validationAttribute.GetValidationResult(value, validationContext);
                        if (validationResult != DataAnnotations.ValidationResult.Success)
                        {
                            validationResults.Add(new ValidationResult()
                            {
                                Id = validationAttribute.GetType().FullName,
                                Message = validationResult.ErrorMessage,
                                Severity = ValidationSeverity.Error,
                                Target = entity,
                                PropertyName = property.Name
                            });
                        }
                    }
                }
            }

            return Task.WhenAll();
        }
Example #6
0
        private static string GetAuthorizeFailedMessage(ChangeSetEntry entry)
        {
            switch (entry.Type)
            {
                case ChangeSetEntryType.DataModification:
                    DataModificationEntry dataModification = (DataModificationEntry)entry;
                    string message = null;
                    if (dataModification.IsNew)
                    {
                        message = Resources.NoPermissionToInsertEntity;
                    }
                    else if (dataModification.IsUpdate)
                    {
                        message = Resources.NoPermissionToUpdateEntity;
                    }
                    else if (dataModification.IsDelete)
                    {
                        message = Resources.NoPermissionToDeleteEntity;
                    }
                    else
                    {
                        throw new NotSupportedException(Resources.DataModificationMustBeCUD);
                    }

                    return string.Format(CultureInfo.InvariantCulture, message, dataModification.EntitySetName);

                case ChangeSetEntryType.ActionInvocation:
                    ActionInvocationEntry actionInvocation = (ActionInvocationEntry)entry;
                    return string.Format(
                        CultureInfo.InvariantCulture,
                        Resources.NoPermissionToInvokeAction,
                        actionInvocation.ActionName);

                default:
                    throw new InvalidOperationException(string.Format(
                        CultureInfo.InvariantCulture,
                        Resources.InvalidChangeSetEntryType,
                        entry.Type));
            }
        }
        private static string GetAuthorizeFailedMessage(ChangeSetEntry entry)
        {
            switch (entry.Type)
            {
            case ChangeSetEntryType.DataModification:
                DataModificationEntry dataModification = (DataModificationEntry)entry;
                string message = null;
                if (dataModification.IsNew)
                {
                    message = Resources.NoPermissionToInsertEntity;
                }
                else if (dataModification.IsUpdate)
                {
                    message = Resources.NoPermissionToUpdateEntity;
                }
                else if (dataModification.IsDelete)
                {
                    message = Resources.NoPermissionToDeleteEntity;
                }
                else
                {
                    throw new NotSupportedException(Resources.DataModificationMustBeCUD);
                }

                return(string.Format(CultureInfo.InvariantCulture, message, dataModification.EntitySetName));

            case ChangeSetEntryType.ActionInvocation:
                ActionInvocationEntry actionInvocation = (ActionInvocationEntry)entry;
                return(string.Format(
                           CultureInfo.InvariantCulture,
                           Resources.NoPermissionToInvokeAction,
                           actionInvocation.ActionName));

            default:
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.InvariantCulture,
                                                        Resources.InvalidChangeSetEntryType,
                                                        entry.Type));
            }
        }
        private static object[] GetParameters(ChangeSetEntry entry)
        {
            switch (entry.Type)
            {
            case ChangeSetEntryType.DataModification:
                DataModificationEntry dataModification = (DataModificationEntry)entry;
                return new object[] { dataModification.Entity };

            case ChangeSetEntryType.ActionInvocation:
                ActionInvocationEntry actionEntry = (ActionInvocationEntry)entry;
                return actionEntry.GetArgumentArray();

            default:
                throw new InvalidOperationException(string.Format(
                    CultureInfo.InvariantCulture, Resources.InvalidChangeSetEntryType, entry.Type));
            }
        }
        private Task InvokeFilterMethodAsync(
            SubmitContext context,
            ChangeSetEntry entry,
            string methodNameSuffix)
        {
            string methodName = ConventionBasedChangeSetEntryFilter.GetMethodName(entry, methodNameSuffix);
            object[] parameters = ConventionBasedChangeSetEntryFilter.GetParameters(entry);

            MethodInfo method = this.targetType.GetQualifiedMethod(methodName);

            if (method != null &&
                (method.ReturnType == typeof(void) ||
                typeof(Task).IsAssignableFrom(method.ReturnType)))
            {
                object target = null;
                if (!method.IsStatic)
                {
                    target = context.ApiContext.GetProperty(
                        typeof(Api).AssemblyQualifiedName);
                    if (target == null ||
                        !this.targetType.IsAssignableFrom(target.GetType()))
                    {
                        return Task.WhenAll();
                    }
                }

                ParameterInfo[] methodParameters = method.GetParameters();
                if (ConventionBasedChangeSetEntryFilter.ParametersMatch(methodParameters, parameters))
                {
                    object result = method.Invoke(target, parameters);
                    Task resultTask = result as Task;
                    if (resultTask != null)
                    {
                        return resultTask;
                    }
                }
            }

            return Task.WhenAll();
        }