public static GraphArguments FromModel(Type modelType)
        {
            var arguments = new GraphArguments();

            foreach (var propertyInfo in modelType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                var fieldName = char.ToLower(propertyInfo.Name[0]) + propertyInfo.Name.Substring(1);
                if (arguments.ContainsKey(fieldName))
                {
                    continue;
                }
                var argument = new GraphArgument()
                {
                    Name      = fieldName,
                    Type      = propertyInfo.PropertyType,
                    GraphType = TypeLoader.GetGraphType(propertyInfo.PropertyType, inputType: true),
                    NonNull   = propertyInfo.CustomAttributes.Any(a => a.AttributeType == typeof(RequiredAttribute))
                };
                if (argument.NonNull)
                {
                    argument.GraphType = typeof(NonNullGraphType <>).MakeGenericType(argument.GraphType);
                }
                arguments.Add(fieldName, argument);
                LoadChildGraphTypes(propertyInfo.PropertyType);
            }
            return(arguments);
        }
        public void AddQuery(string fieldName, Type inputType, Type outputType, Func <object, object> function)
        {
            fieldName = fieldName.ToCamelCase();
            var fieldDescription = "";
            var arguments        = GraphArguments.FromModel(inputType);
            var queryArguments   = arguments.GetQueryArguments();
            // Add function as operation
            var graphType = TypeLoader.GetGraphType(outputType);

            Field(graphType, fieldName, fieldDescription, queryArguments, context =>
            {
                var inputModel = GetInputFromContext(context, inputType);
                ValidationError.ValidateObject(inputModel);

                return(function.Invoke(inputModel));
            });
        }
        public static object GetInputFromContext(ResolveFieldContext <object> context, Type inputType)
        {
            var values = new Dictionary <string, object>();

            if (context.FieldAst.Arguments != null)
            {
                var arguments = GraphArguments.FromModel(inputType);
                var astArgs   = context.FieldAst.Arguments.Children.OfType <Argument>().ToDictionary(a => a.Name, a => a.Value);
                foreach (var argument in arguments)
                {
                    if (!astArgs.ContainsKey(argument.Value.Name))
                    {
                        continue;
                    }
                    var jsonString = JsonConvert.SerializeObject(context.Arguments[argument.Value.Name]);
                    values[argument.Value.Name] = JsonConvert.DeserializeObject(jsonString, argument.Value.Type);
                }
            }
            var valuesJson = JsonConvert.SerializeObject(values);

            return(JsonConvert.DeserializeObject(valuesJson, inputType));
        }
        public void AddQuery <TOutputObject, TInput>(Func <TInput, InputField[], object> function)
            where TOutputObject : GraphType
            where TInput : class, new()
        {
            var fieldName        = function.Method.Name.ToCamelCase();
            var authFieldName    = $"{fieldName}()";
            var fieldDescription = "";
            var arguments        = GraphArguments.FromModel <TInput>();
            var queryArguments   = arguments.GetQueryArguments();
            // Function authorization
            var functionAttributes     = function.Method.GetCustomAttributes(true).OfType <Attribute>().ToArray();
            var authorizeAttributeType = typeof(AuthorizeAttribute);
            var functionAuth           = functionAttributes.FirstOrDefault(attr => typeof(AuthorizeAttribute).IsAssignableFrom(attr.GetType())) as AuthorizeAttribute;

            if (functionAuth == null && function.Method.DeclaringType != null)
            {
                var classAttributes = function.Method.DeclaringType.GetCustomAttributes(true).OfType <Attribute>().ToArray();
                functionAuth = classAttributes.FirstOrDefault(attr => typeof(AuthorizeAttribute).IsAssignableFrom(attr.GetType())) as AuthorizeAttribute;
            }
            if (functionAuth != null)
            {
                var authMap = Container.GetInstance <AuthorizationMap>();
                authMap.Authorizations.Add(new Authorization()
                {
                    TargetName = authFieldName,
                    Roles      = functionAuth.Claims
                });
            }
            // Add function as operation
            Field <TOutputObject>(fieldName, fieldDescription, queryArguments, context =>
            {
                AuthorizeFunction(Container, authFieldName);
                var values          = new Dictionary <string, object>();
                InputField[] fields = null;
                if (context.FieldAst.Arguments != null)
                {
                    var astArgs = context.FieldAst.Arguments.Children.OfType <Argument>().ToDictionary(a => a.Name, a => a.Value);

                    foreach (var argument in arguments)
                    {
                        if (astArgs.ContainsKey(argument.Value.Name))
                        {
                            try
                            {
                                var jsonString = JsonConvert.SerializeObject(context.Arguments[argument.Value.Name]);
                                values[argument.Value.Name] = JsonConvert.DeserializeObject(jsonString, argument.Value.Type);
                            }
                            catch
                            {
                            }
                        }
                    }
                    fields = CollectFields(astArgs);
                }
                var valuesJson = JsonConvert.SerializeObject(values);
                var inputModel = JsonConvert.DeserializeObject <TInput>(valuesJson);
                ValidationError.ValidateObject(inputModel);
                var operationValues = new OperationValues()
                {
                    Context            = context,
                    FieldName          = fieldName,
                    Fields             = fields,
                    FunctionAttributes = functionAttributes,
                    Input = inputModel,
                };
                operationValues        = Container.GetInstance <ApiSchema>().RunOperationFilters(OperationFilterType.Pre, operationValues);
                operationValues.Output = function.Invoke(inputModel, fields);
                operationValues        = Container.GetInstance <ApiSchema>().RunOperationFilters(OperationFilterType.Post, operationValues);
                return(operationValues.Output);
            });
        }
Exemple #5
0
        public void AddQuery <TOutputObject, TInput>(Func <TInput, InputField[], object> function)
            where TOutputObject : GraphType
            where TInput : class, new()
        {
            var fieldName        = StringExtensions.PascalCase(function.Method.Name);
            var authFieldName    = $"{fieldName}()";
            var fieldDescription = "";
            var arguments        = GraphArguments.FromModel <TInput>();
            var queryArguments   = arguments.GetQueryArguments();
            // Function authorization
            var functionAuth = function.Method.GetCustomAttributes(typeof(AuthorizeAttribute), true).FirstOrDefault() as AuthorizeAttribute;

            if (functionAuth == null && function.Method.DeclaringType != null)
            {
                functionAuth = function.Method.DeclaringType.GetCustomAttributes(typeof(AuthorizeAttribute), true).FirstOrDefault() as AuthorizeAttribute;
            }
            if (functionAuth != null)
            {
                var authMap = Container.GetInstance <AuthorizationMap>();
                authMap.Authorizations.Add(new Authorization()
                {
                    TargetName = authFieldName,
                    Roles      = functionAuth.Claims
                });
            }
            // Add function as operation
            Field <TOutputObject>(fieldName, fieldDescription, queryArguments, context =>
            {
                AuthorizeFunction(Container, authFieldName);
                var values          = new Dictionary <string, object>();
                var errors          = new List <ValidationError>();
                InputField[] fields = null;
                if (context.FieldAst.Arguments != null)
                {
                    var args    = queryArguments.ToDictionary(argument => argument.Name);
                    var astArgs = context.FieldAst.Arguments.Children.OfType <Argument>().ToDictionary(a => a.Name, a => a.Value);

                    foreach (var argument in arguments)
                    {
                        if (astArgs.ContainsKey(argument.Value.Name))
                        {
                            try
                            {
                                var jsonString = JsonConvert.SerializeObject(context.Arguments[argument.Value.Name]);
                                values[argument.Value.Name] = JsonConvert.DeserializeObject(jsonString, argument.Value.Type);
                            }
                            catch
                            {
                            }
                        }
                        ValidationError.ValidateField(argument.Value.Type, errors, args, astArgs, context, argument.Value.Name);
                    }
                    ValidationError.Throw(errors.ToArray());
                    fields = CollectFields(astArgs);
                }
                var valuesJson = JsonConvert.SerializeObject(values);
                var inputModel = JsonConvert.DeserializeObject <TInput>(valuesJson);
                ValidationError.ValidateObject(inputModel);
                try
                {
                    return(function.Invoke(inputModel, fields));
                }
                catch (Exception ex)
                {
                    throw;
                }
            });
        }