Example #1
0
        public static JObject AddPathObjects(this JObject spec, ApiMetaData data)
        {
            var paths =
                from s in data.Sections
                from r in s.Resources
                from e in r.Endpoints
                orderby e.Route
                select new
            {
                Path        = $"/{e.Route.TrimStart("v1")}",
                Verb        = e.HttpVerb.Method.ToLower(),
                EndpointObj = new EndpointObject(r, e, data).ToJObject()
            };

            var jp = new JObject();

            foreach (var p in paths.GroupBy(p => p.Path))
            {
                var je = new JObject();
                foreach (var e in p.OrderBy(x => x.Verb.SortOrder()))
                {
                    je.Add(e.Verb, e.EndpointObj);
                }
                jp.Add(p.Key, je);
            }
            spec.Add("paths", jp);
            return(spec);
        }
Example #2
0
 public static JObject AddComponents(this JObject spec, ApiMetaData data)
 {
     spec.Add("components", new JObject(
                  new JProperty("securitySchemes", new SecurityObject(data).ToJObject()),
                  new JProperty("schemas", new SchemaObject(data).ToJObject())));
     return(spec);
 }
Example #3
0
        public SecurityObject(ApiMetaData data)
        {
            var scopes = new JObject();

            foreach (var role in data.Roles)
            {
                scopes.Add(role, "");
            }

            var flowDefinition = new JObject(
                new JProperty("tokenUrl", "/oauth/token"),
                new JProperty("scopes", scopes)
                );

            _obj = new JObject
            {
                {
                    "OAuth2", new JObject(
                        new JProperty("type", "oauth2"),
                        new JProperty("flows", new JObject(
                                          new JProperty("password", flowDefinition),
                                          new JProperty("clientCredentials", flowDefinition)
                                          )))
                }
            };
        }
Example #4
0
        public EndpointObject(ApiResource res, ApiEndpoint method, ApiMetaData data)
        {
            //Add responses obj
            _obj.Add("responses", new ResponseObject(method).ToJObject());
            //Add operationId and tags
            _obj.Add("operationId", res.Name + '.' + method.Name);
            _obj.Add("tags", new JArray(res.Description));
            //Add parameters obj
            var param = new ParamObject(res, method, data).ToTuples();

            param.ForEach(p => _obj.Add(p.Item1, p.Item2));

            _obj.Add("summary", method.Description);
            _obj.Add("description", string.Join("<br/></br>", method.Comments));

            //Add scopes needed to access this endpoint
            _obj.Add("security", new JArray(new JObject(new JProperty("OAuth2", method.RequiredRoles))));
        }
Example #5
0
        public static JObject AddResourceTags(this JObject spec, ApiMetaData data)
        {
            var tagsArray = new JArray();

            foreach (var section in data.Sections)
            {
                tagsArray.Add(new JObject(
                                  new JProperty("name", section.Name),
                                  new JProperty("description", String.Join("\n", section.Description)),
                                  new JProperty("x-id", section.ID)));

                foreach (var resource in section.Resources)
                {
                    tagsArray.Add(new JObject(
                                      new JProperty("name", resource.Description),
                                      new JProperty("description", String.Join("\n", resource.Comments)),
                                      new JProperty("x-section-id", section.ID)));
                }
            }
            spec.Add("tags", tagsArray);
            return(spec);
        }
Example #6
0
        public ParamObject(ApiResource resource, ApiEndpoint endpoint, ApiMetaData data)
        {
            _param = new List <Tuple <string, JRaw> >();
            if (endpoint.SubResource != null)
            {
                // Used to get correct enumerables on query params such as sortBy and searchOn for the Me resource
                resource = data.Resources.FirstOrDefault(r => r.Name == endpoint.SubResource);
            }

            var paramArray = new JArray();

            foreach (var p in endpoint.PathArgs)
            {
                var paramObj = new JObject
                {
                    { "name", p.Name },
                    { "in", "path" },
                    { "description", string.Join("\n", p.Description) },
                    { "required", p.Required }
                };
                var type = p.SimpleType;
                if (type == "date")
                {
                    type = "string";
                }

                var paramSchema = new JObject(new JProperty("type", type));

                if (p.Type.IsEnum)
                {
                    paramSchema.Add("enum", new JArray(p.Type.GetEnumNames()));
                }

                paramObj.Add("schema", paramSchema);
                paramArray.Add(paramObj);
            }

            foreach (var p in endpoint.QueryArgs)
            {
                var paramObj = new JObject
                {
                    { "name", p.Name },
                    { "in", "query" },
                    { "description", string.Join("\n", p.Description) },
                    { "required", p.Required }
                };
                var type = p.SimpleType;
                if (type == "date")
                {
                    type = "string";
                }


                var paramSchema = new JObject();

                //TODO: figure out how to identify List<string> types vs. simple string types.
                if (p.Name == "sortBy" || p.Name == "searchOn")
                {
                    var model = (endpoint.ResponseModel.Type.WithoutGenericArgs() == typeof(ListPage <>)
                        ? endpoint.ResponseModel.InnerModel
                        : endpoint.ResponseModel).BuildStringListEnum(p.Name);

                    //TODO: evaluate the best way to handle this.. It's hard coded to OC
                    paramSchema.Add("type", "array");
                    paramSchema.Add("items", new JObject(
                                        new JProperty("type", "string"),
                                        new JProperty("enum", model.Count > 0 ? model : new JArray("ID"))));
                }
                else
                {
                    paramSchema.Add("type", p.Name == "filters" ? "object" : type);

                    if (p.Type.IsEnum)
                    {
                        paramSchema.Add("enum", new JArray(p.Type.GetEnumNames()));
                    }
                }
                paramObj.Add("schema", paramSchema);

                if (p.Name != "defaultSearchOn" && p.Name != "defaultSortBy")
                {
                    paramArray.Add(paramObj);
                }
            }

            if (endpoint.RequestModel != null)
            {
                var requestObj = new JObject {
                    { "required", true }, { "description", "" }
                };
                //Body params are always required
                var type   = endpoint.RequestModel.Type.PropertySimpleName();
                var schema = new JObject(
                    new JProperty("allOf", new JArray(new JObject(new JProperty("$ref", "#/components/schemas/" + type)))));
                if (!endpoint.HttpVerb.Equals(new HttpMethod("patch")))
                {
                    var requiredFields = new JArray();
                    foreach (var property in endpoint.RequestModel.Properties)
                    {
                        if (property.Required)
                        {
                            requiredFields.Add(property.Name);
                        }
                    }
                    ;
                    if (requiredFields.Count > 0)
                    {
                        schema.Add("required", requiredFields);
                    }
                }

                requestObj.Add("content", new JObject(
                                   new JProperty("application/json", new JObject(
                                                     new JProperty("schema", schema)
                                                     ))));

                _param.Add(new Tuple <string, JRaw>("requestBody", requestObj.ToJRaw()));
            }

            if (paramArray.Count > 0)
            {
                _param.Add(new Tuple <string, JRaw>("parameters", paramArray.ToJRaw()));
            }
        }
Example #7
0
 public OpenApiGenerator <TController> CollectMetaData(string refPath, IDictionary <string, IErrorCode> errors)
 {
     this._data = ApiReflector.GetMetaData <TController>(refPath, errors);
     return(this);
 }
Example #8
0
        public SchemaObject(ApiMetaData data)
        {
            var schemas = new Dictionary <string, JToken>();

            foreach (var model in data.Models)
            {
                if (!model.Name.Contains("Partial"))
                {
                    var modelDefinitionKey = model.Name;
                    var schemaDef          = new JObject {
                        { "type", "object" }
                    };

                    var propertiesDef = new JObject();
                    foreach (var prop in model.Properties)
                    {
                        var propDefinitionKey = prop.Name;
                        var propObject        = new PropertyObject(prop.Type).ToJObject();
                        if (prop.HasDefaultValue)
                        {
                            propObject.Add("default", new JValue(prop.DefaultValue));
                        }

                        if (prop.ReadOnly || model.IsReadOnly)
                        {
                            propObject.Add("readOnly", true);
                        }

                        var docCommentsAttribute =
                            prop.PropInfo.GetCustomAttribute <DocCommentsAttribute>();

                        if (docCommentsAttribute != null)
                        {
                            propObject.Add("description", string.Join("\n", docCommentsAttribute.Comments));
                        }

                        var minValueAttribute =
                            prop.PropInfo.GetCustomAttribute <MinValueAttribute>();

                        if (minValueAttribute != null)
                        {
                            propObject.Add("minimum", minValueAttribute.Minimum.ToJRaw());
                        }

                        var maxValueAttribute =
                            prop.PropInfo.GetCustomAttribute <MaxValueAttribute>();

                        if (maxValueAttribute != null)
                        {
                            propObject.Add("maximum", maxValueAttribute.Maximum.ToJRaw());
                        }

                        var maxLengthAttribute =
                            prop.PropInfo.GetCustomAttribute <MaxLengthAttribute>();

                        if (maxLengthAttribute != null)
                        {
                            propObject.Add("maxLength", maxLengthAttribute.Length);
                        }

                        var minLengthAttribute =
                            prop.PropInfo.GetCustomAttribute <MinLengthAttribute>();

                        if (minLengthAttribute != null)
                        {
                            propObject.Add("minLength", minLengthAttribute.Length);
                        }

                        if (propDefinitionKey.Contains("Password"))
                        {
                            if (propObject.ContainsKey("format"))
                            {
                                propObject.Merge(new JObject(new JProperty("format", "password")));
                            }
                            else
                            {
                                propObject.Add("format", "password");
                            }
                        }
                        propertiesDef.Add(propDefinitionKey, propObject);
                    }

                    schemaDef.Add("example", model.Sample.ToJRaw());
                    schemaDef.Add("properties", propertiesDef);
                    schemas.Add(modelDefinitionKey, schemaDef);
                }
            }
            schemas.Add("Meta", new DefinitionObject(typeof(ListPageMeta)).ToJObject());
            schemas.Add("MetaWithFacets", new DefinitionObject(typeof(ListPageMetaWithFacets)).ToJObject());
            schemas.Add("ListFacet", new DefinitionObject(typeof(ListFacet)).ToJObject());
            schemas.Add("ListFacetValue", new DefinitionObject(typeof(ListFacetValue)).ToJObject());

            //Find all methods that return ListPage and create all the different types of List objects
            foreach (var endpoint in data.Resources.SelectMany(r => r.Endpoints).Where(e => e.IsList))
            {
                var itemType = endpoint.ResponseModel.Type
                               .UnwrapGeneric(typeof(ListPage <>))
                               .UnwrapGeneric(typeof(ListPageWithFacets <>)).PropertySimpleName();

                var listTypeName = "List" + itemType;
                //Check if this list type doesn't exist yet
                if (!schemas.ContainsKey(listTypeName))
                {
                    var listObj = new JObject {
                        { "type", "object" }
                    };
                    var listProperties = new JObject
                    {
                        {
                            "Items", new JObject(
                                new JProperty("type", "array"),
                                new JProperty("items",
                                              new JObject(new JProperty("$ref", "#/components/schemas/" + itemType)))
                                )
                        }
                    };
                    var metaDef = (endpoint.ResponseModel.Type.WithoutGenericArgs() == typeof(ListPageWithFacets <>)) ? "MetaWithFacets" : "Meta";
                    listProperties.Add("Meta", new JObject(new JProperty("$ref", "#/components/schemas/" + metaDef)));
                    listObj.Add("properties", listProperties);
                    schemas.Add(listTypeName, listObj);
                }
            }

            foreach (var def in schemas.OrderBy(d => d.Key))
            {
                _obj.Add(def.Key, def.Value);
            }
            _obj.Add("Authentication", new JObject(
                         new JProperty("type", "object"),
                         new JProperty("properties",
                                       new JObject(new JProperty("access_token",
                                                                 new JObject(new JProperty("type", "string"))))
                                       )));
        }