/// <summary>
        /// This is a generic endpoint definition generator, you can override it in your test class if you want to send something different.
        /// </summary>
        /// <param name="schemaBuilder"></param>
        /// <returns></returns>
        protected virtual async Task <EndpointClientDefinition> CreateEndpointDefinition(ISchemaBuilder schemaBuilder)
        {
            var endpoint    = new EndpointClientDefinition(typeof(TResult), await schemaBuilder.GetSchema(typeof(TResult)));
            var endpointDoc = new EndpointDoc();

            endpointDoc.RequestSchema = await schemaBuilder.GetSchema(typeof(TInput));

            endpoint.AddLink(new EndpointClientLinkDefinition("Save", endpointDoc, false));
            return(endpoint);
        }
예제 #2
0
        protected override async Task <EndpointClientDefinition> CreateEndpointDefinition(ISchemaBuilder schemaBuilder)
        {
            var endpoint    = new EndpointClientDefinition(typeof(EntryPoint), await schemaBuilder.GetSchema(typeof(EntryPoint)));
            var endpointDoc = new EndpointDoc();

            endpointDoc.ResponseSchema = await schemaBuilder.GetSchema(typeof(EntryPoint));

            endpoint.AddLink(new EndpointClientLinkDefinition("self", endpointDoc, false));
            return(endpoint);
        }
        protected override async Task <IEnumerable <ILabelValuePair> > GetSources()
        {
            var          labels = new List <ILabelValuePair>();
            JsonProperty schemaProp;
            var          schema = await schemaBuilder.GetSchema(typeof(T));

            foreach (var prop in typeof(T).GetProperties())
            {
                if (prop.GetCustomAttributes(typeof(NoPropertyLabelAttribute), true).Any())
                {
                    continue;
                }

                //Only add properties that can be found in the schema
                var schemaPropName = schemaBuilder.GetPropertyName(prop);
                if (schema.Properties.TryGetValue(schemaPropName, out schemaProp))
                {
                    var label = schemaProp.Title ?? prop.Name;
                    labels.Add(new LabelValuePair <String>(label, prop.Name));
                }
            }
            return(labels);
        }
예제 #4
0
        public async Task <IEnumerable <EndpointClientDefinition> > GetEndpointDefinitions()
        {
            var definitions = new List <EndpointClientDefinition>();

            foreach (var type in resultViewProvider.GetResultViewTypes())
            {
                EndpointClientDefinition clientDef = new EndpointClientDefinition(type, await schemaBuilder.GetSchema(type));
                var customAttrs = type.GetTypeInfo().GetCustomAttributes();
                foreach (var link in customAttrs)
                {
                    var actionLink = link as HalActionLinkAttribute;
                    if (actionLink != null)
                    {
                        var doc = await endpointDocBuilder.GetDoc(actionLink.GroupName, actionLink.Method, actionLink.UriTemplate.Substring(1));

                        clientDef.AddLink(new EndpointClientLinkDefinition(actionLink.Rel, doc, actionLink.DocsOnly));
                    }
                    else
                    {
                        var declaredLink = link as DeclareHalLinkAttribute;
                        if (declaredLink != null)
                        {
                            EndpointDoc doc;
                            if (declaredLink.LinkedToControllerRel)
                            {
                                doc = await endpointDocBuilder.GetDoc(declaredLink.GroupName, declaredLink.Method, declaredLink.UriTemplate.Substring(1));
                            }
                            else
                            {
                                doc = new EndpointDoc();
                            }

                            //If the link is response only, send only the response
                            if (declaredLink.ResponseOnly)
                            {
                                var oldDoc = doc;
                                doc = new EndpointDoc();
                                doc.ResponseSchema = oldDoc.ResponseSchema;
                            }

                            clientDef.AddLink(new EndpointClientLinkDefinition(declaredLink.Rel, doc, false));
                        }
                    }
                }
                definitions.Add(clientDef);
            }
            return(definitions);
        }
 public void SetUp()
 {
     schema_builder = new NhibernateSchemaBuilder(config);
     table = schema_builder.GetSchema().Tables.FirstOrDefault(x => x.TableName == "Employees");
 }
        public async Task <EndpointDoc> GetDoc(string groupName, string method, string relativePath, EndpointDocBuilderOptions options)
        {
            if (relativePath == null)
            {
                relativePath = "";
            }
            else if (relativePath.EndsWith("/") || relativePath.EndsWith("\\"))
            {
                relativePath = relativePath.Substring(0, relativePath.Length - 1);
            }

            var group = descriptionProvider.ApiDescriptionGroups.Items.FirstOrDefault(i => i.GroupName == groupName);

            if (group == null)
            {
                throw new InvalidOperationException($"Cannot find an api group for {groupName}. Did you declare a route to that group?");
            }

            var action = group.Items.FirstOrDefault(i => i.HttpMethod == method && i.RelativePath == relativePath);

            if (action == null)
            {
                throw new InvalidOperationException($"Cannot find an api action for {relativePath} and method {method} in api group {groupName}.");
            }

            var  description    = new EndpointDoc();
            bool handleFormData = true;

            if (options.IncludeResponse)
            {
                var controllerActionDesc = action.ActionDescriptor as ControllerActionDescriptor;
                if (controllerActionDesc != null)
                {
                    var methodInfo = controllerActionDesc.MethodInfo;

                    //Check to see if the user can actually access the endpoint we requested
                    if (options.User != null && !HalcyonExtUtils.CanUserAccess(options.User, methodInfo, controllerActionDesc.ControllerTypeInfo))
                    {
                        throw new UnauthorizedAccessException("User cannot access requested endpoint");
                    }

                    var returnType = methodInfo.ReturnType;
                    if (returnType != typeof(void))
                    {
                        description.SetResponseSchema(await endpointDocCache.GetCachedResponse(groupName, method, relativePath, returnType, schemaBuilder.GetSchema));
                    }
                }
            }

            if (options.IncludeRequest)
            {
                foreach (var param in action.ParameterDescriptions)
                {
                    if (param.Source.IsFromRequest)
                    {
                        if (param.Source.CanAcceptDataFrom(BindingSource.Body))
                        {
                            description.SetRequestSchema(await endpointDocCache.GetCachedRequest(groupName, method, relativePath, param.Type, schemaBuilder.GetSchema));
                        }
                        else if (param.Source.CanAcceptDataFrom(BindingSource.Query))
                        {
                            description.SetRequestSchema(await endpointDocCache.GetCachedRequest(groupName, method, relativePath, param.ModelMetadata.ContainerType, schemaBuilder.GetSchema));
                        }
                        else if (handleFormData && param.Source.CanAcceptDataFrom(BindingSource.Form))
                        {
                            handleFormData = false; //This prevents this from running for everything that responsds to form, there should only be 1 per controller method.
                                                    //Discover the type from the action method, there is no way to get the real object type from the description when dealing with form input
                            Type type = null;
                            var  controllerActionDescriptor = action.ActionDescriptor as ControllerActionDescriptor;
                            if (controllerActionDescriptor != null)
                            {
                                foreach (var arg in controllerActionDescriptor.MethodInfo.GetParameters())
                                {
                                    if (arg.CustomAttributes.Any(i => i.AttributeType == typeof(FromFormAttribute)))
                                    {
                                        type = arg.ParameterType;
                                        break;
                                    }
                                }
                            }


                            if (type != null && validSchemaManager.IsValid(type))
                            {
                                description.SetRequestSchema(await endpointDocCache.GetCachedRequest(groupName, method, relativePath, type, async t =>
                                {
                                    var schema = await schemaBuilder.GetSchema(t);
                                    schema.SetDataIsForm(true);
                                    return(schema);
                                }));
                            }
                        }
                    }
                }
            }

            return(description);
        }