public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var odataParam = operation.Parameters.SingleOrDefault(x => x.Schema.Reference?.Id != null && x.Schema.Reference.Id.Contains("ODataQueryOptions"));

            if (odataParam != null)
            {
                operation.Parameters.Remove(odataParam);

                var odataParams = new string[] { "$expand", "$filter", "$orderby", "$pageindex", "$pagesize" };

                foreach (var param in odataParams)
                {
                    operation.Parameters.Add(new OpenApiParameter
                    {
                        Name     = param,
                        In       = ParameterLocation.Query,
                        Required = false,
                        Schema   = new OpenApiSchema {
                            Type = "String"
                        }
                    });
                }
            }
        }
Example #2
0
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType <AuthorizeAttribute>().Any() ||
                               context.MethodInfo.GetCustomAttributes(true).OfType <AuthorizeAttribute>().Any();

            if (hasAuthorize)
            {
                operation.Responses.Add("401", new OpenApiResponse {
                    Description = "Unauthorized"
                });
                operation.Responses.Add("403", new OpenApiResponse {
                    Description = "Forbidden"
                });

                operation.Security = new List <OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        [new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } }]
                            = new[] { "api1" }
                    }
                };
            }
        }
Example #3
0
        public void TestInitialize()
        {
            _operation = new OpenApiOperation
            {
                Parameters = new List <OpenApiParameter>(_inputApiParameters.Select(
                                                             param => new OpenApiParameter
                {
                    Name = param.Name,
                    In   = param.Location
                }))
            };
            var method = FunctionMethodTestSource.GetMethodInfo();

            _schemaRegistry   = A.Fake <ISchemaGenerator>();
            _schemaRepository = new SchemaRepository();
            var apiDescription = new ApiDescription();

            foreach (var inputApiParameter in _inputApiParameters.Where(param => param.Location == ParameterLocation.Path))
            {
                var parameterDescription = new ApiParameterDescription
                {
                    Name = inputApiParameter.Name,
                    Type = inputApiParameter.Type
                };
                apiDescription.ParameterDescriptions.Add(parameterDescription);
            }

            _context = new OperationFilterContext(apiDescription, _schemaRegistry, _schemaRepository, method);
            A.CallTo(() => _schemaRegistry.GenerateSchema(A <Type> ._, _schemaRepository, A <MemberInfo> ._, A <ParameterInfo> ._))
            .ReturnsLazily((Type type, SchemaRepository repository, MemberInfo memberInfo, ParameterInfo parameterInfo) =>
                           new OpenApiSchema
            {
                Type = type.Name
            });
            _sut = new HttpFunctionPathParameterTypeFilter();
        }
        /// <summary>
        /// Applies the filter to the specified operation using the given context.
        /// </summary>
        /// <param name="operation">The operation to apply the filter to.</param>
        /// <param name="context">The current operation filter context.</param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var apiDescription = context.ApiDescription;

            operation.Deprecated |= apiDescription.IsDeprecated();

            if (operation.Parameters == null)
            {
                return;
            }

            foreach (var parameter in operation.Parameters)
            {
                var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);

                if (parameter.Description == null)
                {
                    parameter.Description = description.ModelMetadata?.Description;
                }


                parameter.Required |= description.IsRequired;
            }
        }
Example #5
0
        /// <inheritdoc />
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            // Since all the operations in our api are protected, we need not
            // check separately if the operation has Authorize attribute
            operation.Responses.Add("401", new OpenApiResponse {
                Description = "Unauthorized"
            });
            operation.Responses.Add("403", new OpenApiResponse {
                Description = "Forbidden"
            });

            operation.Security = new List <OpenApiSecurityRequirement>
            {
                new OpenApiSecurityRequirement
                {
                    [
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
                        }
                    ] = new[] { "weatheapi" }
                }
            };
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var apiDescription = context.ApiDescription;

            operation.Deprecated |= apiDescription.IsDeprecated();

            if (operation.Parameters == null)
            {
                return;
            }

            foreach (var parameter in operation.Parameters)
            {
                var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
                parameter.Description ??= description.ModelMetadata?.Description;

                if (parameter.Schema.Default == null && description.DefaultValue != null)
                {
                    parameter.Schema.Default = new OpenApiString(description.DefaultValue.ToString());
                }

                parameter.Required |= description.IsRequired;
            }
        }
        /// <summary>
        /// 添加请求头
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="context"></param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            string GetVersionName()
            => ApiExplorerGroupNameConvention.GetApiVersion(context.ApiDescription.GroupName).ToString();

            if (operation.Parameters == null)
            {
                operation.Parameters = new List <OpenApiParameter>();
            }

            var apiversion = new OpenApiParameter
            {
                In          = ParameterLocation.Header,
                Required    = false,
                Name        = this.HeaderName,
                Style       = ParameterStyle.Simple,
                Description = "api版本,不填则对应1.0",
                Schema      = new OpenApiSchema {
                    Type = "string", Default = new OpenApiString(GetVersionName())
                }
            };

            operation.Parameters.Add(apiversion);
        }
Example #8
0
        /// <inheritdoc/>
        protected override void SetBasicInfo(OpenApiOperation operation)
        {
            // Summary
            operation.Summary = "Invoke " + (EdmOperation.IsAction() ? "action " : "function ") + EdmOperation.Name;

            // OperationId
            if (Context.Settings.EnableOperationId)
            {
                string operationId = String.Join(".", Path.Segments.Where(s => !(s is ODataKeySegment)).Select(s => s.Name));
                if (EdmOperation.IsAction())
                {
                    operation.OperationId = operationId;
                }
                else
                {
                    ODataOperationSegment operationSegment = Path.LastSegment as ODataOperationSegment;
                    string pathItemName = operationSegment.GetPathItemName(Context.Settings);
                    string md5          = pathItemName.GetHashMd5();
                    operation.OperationId = operationId + "." + md5.Substring(0, 4);
                }
            }

            base.SetBasicInfo(operation);
        }
Example #9
0
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List <OpenApiParameter>();
            }

            // var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
            // var isHeader = filterPipeline.Any(filter => filter.Filter is HeaderFilter);

            foreach (var header in _headers)
            {
                operation.Parameters.Add(new OpenApiParameter
                {
                    In       = ParameterLocation.Header,
                    Name     = header,
                    Required = true,
                    Schema   = new OpenApiSchema
                    {
                        Type = "string"
                    }
                });
            }
        }
Example #10
0
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var secure = context.ApiDescription.ActionDescriptor.FilterDescriptors.Any(x => x.Filter is AuthorizeFilter);

            if (!secure)
            {
                return;
            }

            if (operation.Security == null)
            {
                operation.Security = new List <OpenApiSecurityRequirement>();
            }

            var oAuthRequirements = new OpenApiSecurityRequirement
            {
                { new OpenApiSecurityScheme {
                      Type = SecuritySchemeType.OAuth2
                  }, new Collection <string>() }
            };


            operation.Security.Add(oAuthRequirements);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="context"></param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            Type allowAnonymousAttribute = typeof(AllowAnonymousAttribute);

            foreach (var item in context.ApiDescription.ActionDescriptor.EndpointMetadata)
            {
                if (item.GetType() == allowAnonymousAttribute)
                {
                    //接口允许匿名访问
                    return;
                }
            }

            if (operation.Parameters == null)
            {
                operation.Parameters = new List <OpenApiParameter>();
            }
            operation.Parameters.Add(new OpenApiParameter()
            {
                Name     = CustomAuthorizationFilter.HEADER_TOKEN,
                In       = ParameterLocation.Header,
                Required = true
            });
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List <OpenApiParameter>();
            }

            var descriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;

            if (descriptor != null && !descriptor.ControllerName.StartsWith("Weather"))
            {
                operation.Parameters.Add(new OpenApiParameter()
                {
                    Name        = "timestamp",
                    In          = ParameterLocation.Query,
                    Description = "The timestamp of now",
                    Required    = true
                });

                operation.Parameters.Add(new OpenApiParameter()
                {
                    Name        = "nonce",
                    In          = ParameterLocation.Query,
                    Description = "The random value",
                    Required    = true
                });

                operation.Parameters.Add(new OpenApiParameter()
                {
                    Name        = "sign",
                    In          = ParameterLocation.Query,
                    Description = "The signature",
                    Required    = true
                });
            }
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            // Policy names map to scopes
            IEnumerable <string> requiredScopes = context.MethodInfo
                                                  .GetCustomAttributes(true)
                                                  .OfType <AuthorizeAttribute>()
                                                  .Select(attr => attr.Policy)
                                                  .Distinct();

            IEnumerable <string> enumerable = requiredScopes as string[] ?? requiredScopes.ToArray();

            if (enumerable.Any())
            {
                operation.Responses.Add("401", new OpenApiResponse {
                    Description = "Unauthorized"
                });
                operation.Responses.Add("403", new OpenApiResponse {
                    Description = "Forbidden"
                });

                var oAuthScheme = new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference {
                        Type = ReferenceType.SecurityScheme, Id = "oauth2"
                    },
                };

                operation.Security = new List <OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        [oAuthScheme] = enumerable.ToList(),
                    },
                };
            }
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
            var isAuthorized   = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
            var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);

            if (isAuthorized && !allowAnonymous)
            {
                if (operation.Parameters == null)
                {
                    operation.Parameters = new List <OpenApiParameter>();
                }

                operation.Parameters.Add(new OpenApiParameter
                {
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Description = "access token",
                    Required    = false,
                    //Type = "string",
                    //Default = "Bearer <token>"
                });
            }
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var httpMethodAttributes = context.MethodInfo
                                       .GetCustomAttributes(true)
                                       .OfType <Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute>();

            var httpMethodWithOptional = httpMethodAttributes?.FirstOrDefault(m => m.Template?.Contains("?") ?? false);

            if (httpMethodWithOptional == null)
            {
                return;
            }

            var regex = $"{{(?<{captureName}>\\w+)\\?}}";

            var matches = System.Text.RegularExpressions.Regex.Matches(httpMethodWithOptional.Template, regex);

            foreach (System.Text.RegularExpressions.Match match in matches)
            {
                var name = match.Groups[captureName].Value;

                var parameter =
                    operation.Parameters.FirstOrDefault(p => p.In == ParameterLocation.Path && p.Name == name);
                if (parameter == null)
                {
                    continue;
                }

                parameter.AllowEmptyValue = true;
                parameter.Description     =
                    "Must check \"Send empty value\" or Swagger passes a comma for empty values otherwise";
                parameter.Required = false;
                //parameter.Schema.Default = new OpenApiString(string.Empty);
                parameter.Schema.Nullable = true;
            }
        }
 /// <inheritdoc/>
 public void Apply(OpenApiOperation operation, OperationFilterContext context)
 {
     if (context.ApiDescription.ActionDescriptor.Parameters.Any(x => x.ParameterType == Configuration.BaseType || EnumerableOfBaseType.IsAssignableFrom(x.ParameterType)))
     {
         foreach (var contenType in operation.RequestBody.Content)
         {
             var request = contenType.Value.Schema;
             if (request.Reference?.Id == Configuration.BaseType.Name ||
                 request.Items?.Reference?.Id == Configuration.BaseType.Name)
             {
                 if (request.Reference?.Id == Configuration.BaseType.Name)
                 {
                     request.Reference = null;
                     request.OneOf     = Configuration.AllOfReferences;
                 }
                 else
                 {
                     request.Items.Reference = null;
                     request.Items.AnyOf     = Configuration.AllOfReferences;
                 }
             }
         }
     }
 }
Example #17
0
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
            {
                return;
            }

            for (var i = 0; i < operation.Parameters.Count; ++i)
            {
                var parameter = operation.Parameters[i];

                var enumType = context.ApiDescription.ParameterDescriptions[i].ParameterDescriptor.ParameterType;
                if (!enumType.IsEnum)
                {
                    continue;
                }

                var schema = context.SchemaRepository.Schemas.GetOrAdd($"#/definitions/{enumType.Name}", () =>
                                                                       context.SchemaGenerator.GenerateSchema(enumType, context.SchemaRepository)
                                                                       );

                parameter.Schema = schema;
            }
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List <OpenApiParameter>();
            }

            operation.Parameters.Add(new OpenApiParameter
            {
                Name        = "Accept-Language",
                In          = ParameterLocation.Header,
                Description = "Supported languages",
                Schema      = new OpenApiSchema
                {
                    Default = new OpenApiString("en"),
                    Type    = "string",
                    Enum    = Localization.SupportedCultures
                              .Select(c => OpenApiAnyFactory.CreateFor(new OpenApiSchema {
                        Type = "string"
                    }, c)).ToList()
                },
                Required = false
            });
        }
Example #19
0
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (context.MethodInfo.Has <DisabledAttribute>())
            {
                operation.Tags.Add(new DisabledTag());
            }
            else if (ApiParameters.IsPagingResult(context.MethodInfo, out _))
            {
                operation.Tags.Add(new PagingTag());
            }

            foreach (var parameter in operation.Parameters)
            {
                ModifySchema(parameter.Schema, parameter, operation, context);
            }

            foreach (var(_, response) in operation.Responses)
            {
                foreach (var(_, content) in response.Content)
                {
                    ModifySchema(content.Schema, null, operation, context);
                }
            }
        }
Example #20
0
 public void Describe(string pathTemplate, OperationType operationType, OpenApiOperation operationSpec)
 {
     _apiTestRunner.ConfigureOperation(_documentName, pathTemplate, operationType, operationSpec);
 }
        /// <summary>
        /// Applies the OperationFilter to the API <paramref name="operation"/>.
        /// </summary>
        /// <param name="operation">The operation instance on which the OperationFilter must be applied.</param>
        /// <param name="context">Provides meta-information on the <paramref name="operation"/> instance.</param>
#if NETCOREAPP3_1
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
 public void Apply(OpenApiOperation operation, OperationFilterContext context)
 {
     throw new NotImplementedException();
 }
        /// <inheritdoc />
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            operation.OperationId = $"{context.MethodInfo.DeclaringType.Name}.{context.MethodInfo.Name}";

            var authAttributes = context
                                 .MethodInfo
                                 .DeclaringType
                                 .GetCustomAttributes(true)
                                 .Union(
                context
                .MethodInfo
                .GetCustomAttributes(true))
                                 .OfType <TgsAuthorizeAttribute>();

            if (authAttributes.Any())
            {
                var tokenScheme = new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id   = TokenSecuritySchemeId
                    }
                };

                operation.Security = new List <OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        {
                            tokenScheme,
                            new List <string>()
                        }
                    }
                };

                if (authAttributes.Any(attr => attr.RightsType.HasValue && RightsHelper.IsInstanceRight(attr.RightsType.Value)))
                {
                    operation.Parameters.Add(new OpenApiParameter
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.Parameter,
                            Id   = ApiHeaders.InstanceIdHeader
                        }
                    });
                }
            }
            else
            {
                // HomeController.CreateToken
                var passwordScheme = new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id   = PasswordSecuritySchemeId
                    }
                };

                operation.Security = new List <OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        {
                            passwordScheme,
                            new List <string>()
                        }
                    }
                };
            }
        }
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            context.ApiDescription.TryGetMethodInfo(out var methodInfo);

            if (methodInfo == null)
            {
                return;
            }

            var hasAuthorizeAttribute = false;

            if (methodInfo.MemberType == MemberTypes.Method)
            {
                // NOTE: Check the controller itself has Authorize attribute
                hasAuthorizeAttribute = methodInfo.DeclaringType.GetCustomAttributes(true).OfType <AuthorizeAttribute>().Any();

                // NOTE: Controller has Authorize attribute, so check the endpoint itself.
                //       Take into account the allow anonymous attribute
                if (hasAuthorizeAttribute)
                {
                    hasAuthorizeAttribute = !methodInfo.GetCustomAttributes(true).OfType <AllowAnonymousAttribute>().Any();
                }
                else
                {
                    hasAuthorizeAttribute = methodInfo.GetCustomAttributes(true).OfType <AuthorizeAttribute>().Any();
                }
            }

            if (!hasAuthorizeAttribute)
            {
                return;
            }

            if (!operation.Responses.Any(r => r.Key == StatusCodes.Status401Unauthorized.ToString()))
            {
                operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(), new OpenApiResponse {
                    Description = "Unauthorized"
                });
            }
            if (!operation.Responses.Any(r => r.Key == StatusCodes.Status403Forbidden.ToString()))
            {
                operation.Responses.Add(StatusCodes.Status403Forbidden.ToString(), new OpenApiResponse {
                    Description = "Forbidden"
                });
            }

            // NOTE: This adds the "Padlock" icon to the endpoint in swagger,
            //       we can also pass through the names of the policies in the string[]
            //       which will indicate which permission you require.
            operation.Security = new List <OpenApiSecurityRequirement>
            {
                new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name   = "Bearer",
                            In     = ParameterLocation.Header
                        },
                        new List <string>()
                    }
                }
            };
        }
Example #25
0
        public OpenApiPath GetOpenApi([FromBody] Entities.OpenApi data)
        {
            var openApi = new OpenApiPath();

            OpenApiDiagnostic diagnostic = new OpenApiDiagnostic();

            //var specData = new StreamReader(@"C:\Users\Naveen\Desktop\UI from Open API Doc\Demo\Petstore.yml").ReadToEnd();
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(data.Data)))
            {
                var openApiDocument = new OpenApiStreamReader().Read(ms, out diagnostic);
                foreach (var tag in openApiDocument.Tags)
                {
                    openApi.Tags.Add(new OpenApiTag()
                    {
                        Tag         = tag.Name,
                        Description = tag.Description
                    });
                }
                if (openApi.Tags.Count == 0)
                {
                    openApi.Tags.Add(new OpenApiTag()
                    {
                        Tag = "Default"
                    });
                }

                foreach (var path in openApiDocument.Paths)
                {
                    foreach (var operation in path.Value.Operations)
                    {
                        var objOperation = new OpenApiOperation()
                        {
                            Id   = operation.Value.OperationId,
                            Name = path.Key,
                            Verb = operation.Key.ToString()
                        };

                        foreach (var param in operation.Value.Parameters)
                        {
                            var objparam = new OpenApiOperationParam()
                            {
                                Name        = param.Name,
                                Type        = param.Schema.Type,
                                IsRequired  = param.Required,
                                Description = param.Description
                            };

                            if (param.Schema.Enum != null && param.Schema.Enum.Count > 0)
                            {
                                foreach (var val in param.Schema.Enum)
                                {
                                    objparam.Values.Add((val as Microsoft.OpenApi.Any.OpenApiString).Value);
                                }
                            }

                            if (param.Schema.Type == "array")
                            {
                                //objparam.Type = "string"; // hard code
                                foreach (var val in param.Schema.Items.Enum)
                                {
                                    objparam.Values.Add((val as Microsoft.OpenApi.Any.OpenApiString).Value);
                                }
                            }

                            objOperation.ParamTree.Add(new ParameterTree()
                            {
                                Name     = objparam.Name,
                                Type     = objparam.Type,
                                Node     = 1,
                                Position = "query",
                                Values   = objparam.Values
                            });

                            objOperation.Params.Add(objparam);
                        }

                        if (operation.Value.RequestBody != null && operation.Value.RequestBody.Content.Count > 0)
                        {
                            var content = operation.Value.RequestBody.Content.FirstOrDefault();
                            objOperation.BodyParams = GetBodyParam(content.Value.Schema, null, null, objOperation.ParamTree, 0)[0].Property;
                        }

                        foreach (var server in openApiDocument.Servers)
                        {
                            objOperation.Server.Add(server.Url);
                        }

                        if (objOperation.ParamTree.Count > 0)
                        {
                            var paramTree = objOperation.ParamTree.ToList();
                            objOperation.ParamTree.Clear();
                            foreach (var item in paramTree)
                            {
                                if (objOperation.ParamTree.Count > 0 &&
                                    objOperation.ParamTree.Last().Type == "array" &&
                                    objOperation.ParamTree.Last().Node < item.Node)
                                {
                                    objOperation.ParamTree.Last().Items.Add(item);
                                }
                                else
                                {
                                    objOperation.ParamTree.Add(item);
                                }
                            }
                        }

                        if (operation.Value.Tags != null && operation.Value.Tags.Count > 0)
                        {
                            openApi.Tags.Where(x => x.Tag == operation.Value.Tags[0].Name).FirstOrDefault().Operations.Add(objOperation);
                        }
                        else
                        {
                            openApi.Tags.Where(x => x.Tag == "Default").FirstOrDefault().Operations.Add(objOperation);
                        }
                    }
                }
            }

            return(openApi);
        }
Example #26
0
        private static void CreateOperationsFromRoutes(HttpFunctionDefinition[] functionDefinitions,
                                                       OpenApiDocument openApiDocument, SchemaReferenceRegistry registry, string apiPrefix)
        {
            string prependedApiPrefix = string.IsNullOrEmpty(apiPrefix) ? $"" : $"/{apiPrefix}";
            var    operationsByRoute  = functionDefinitions.Where(x => x.Route != null).GroupBy(x => $"{prependedApiPrefix}/{x.Route}");

            foreach (IGrouping <string, HttpFunctionDefinition> route in operationsByRoute)
            {
                OpenApiPathItem pathItem = new OpenApiPathItem()
                {
                    Operations = new Dictionary <OperationType, OpenApiOperation>()
                };

                foreach (HttpFunctionDefinition functionByRoute in route)
                {
                    Type commandType = functionByRoute.CommandType;
                    foreach (HttpMethod method in functionByRoute.Verbs)
                    {
                        OpenApiOperation operation = new OpenApiOperation
                        {
                            Description = functionByRoute.OpenApiDescription,
                            Responses   = new OpenApiResponses(),
                            Tags        = string.IsNullOrWhiteSpace(functionByRoute.RouteConfiguration.OpenApiName) ? null : new List <OpenApiTag>()
                            {
                                new OpenApiTag {
                                    Name = functionByRoute.RouteConfiguration.OpenApiName
                                }
                            }
                        };
                        foreach (KeyValuePair <int, string> kvp in functionByRoute.OpenApiResponseDescriptions)
                        {
                            operation.Responses.Add(kvp.Key.ToString(), new OpenApiResponse
                            {
                                Description = kvp.Value
                            });
                        }

                        if (!operation.Responses.ContainsKey("200"))
                        {
                            OpenApiResponse response = new OpenApiResponse
                            {
                                Description = "Successful API operation"
                            };
                            if (functionByRoute.CommandResultType != null)
                            {
                                OpenApiSchema schema = registry.FindOrAddReference(functionByRoute.CommandResultType);
                                response.Content = new Dictionary <string, OpenApiMediaType>
                                {
                                    { "application/json", new OpenApiMediaType {
                                          Schema = schema
                                      } }
                                };
                            }
                            operation.Responses.Add("200", response);
                        }

                        string lowerCaseRoute = functionByRoute.Route;
                        foreach (HttpParameter property in functionByRoute.PossibleBindingProperties)
                        {
                            if (method == HttpMethod.Get || method == HttpMethod.Delete)
                            {
                                operation.Parameters.Add(new OpenApiParameter
                                {
                                    Name        = property.Name.ToCamelCase(),
                                    In          = ParameterLocation.Query,
                                    Required    = !property.IsOptional,
                                    Schema      = property.Type.MapToOpenApiSchema(),
                                    Description = ""
                                });
                            }
                        }

                        if (functionByRoute.Authorization == AuthorizationTypeEnum.Function && method == HttpMethod.Get || method == HttpMethod.Delete)
                        {
                            operation.Parameters.Add(new OpenApiParameter
                            {
                                Name        = "code",
                                In          = ParameterLocation.Query,
                                Required    = true,
                                Schema      = typeof(string).MapToOpenApiSchema(),
                                Description = ""
                            });
                        }

                        foreach (HttpParameter property in functionByRoute.RouteParameters)
                        {
                            operation.Parameters.Add(new OpenApiParameter
                            {
                                Name        = property.RouteName.ToCamelCase(),
                                In          = ParameterLocation.Path,
                                Required    = !property.IsOptional,
                                Schema      = property.Type.MapToOpenApiSchema(),
                                Description = ""
                            });
                            // TODO: We need to consider what to do with the payload model here - if its a route parameter
                            // we need to ignore it in the payload model
                        }

                        if (method == HttpMethod.Post || method == HttpMethod.Put || method == HttpMethod.Patch)
                        {
                            OpenApiRequestBody requestBody = new OpenApiRequestBody();
                            OpenApiSchema      schema      = registry.FindReference(commandType);
                            requestBody.Content = new Dictionary <string, OpenApiMediaType>
                            {
                                { "application/json", new OpenApiMediaType {
                                      Schema = schema
                                  } }
                            };
                            operation.RequestBody = requestBody;
                        }


                        pathItem.Operations.Add(MethodToOperationMap[method], operation);
                    }
                }

                openApiDocument.Paths.Add(route.Key, pathItem);
            }
        }
        /// <summary>
        /// Fetches the value of "param" tags from xml documentation with in valus of "body"
        /// and populates operation's request body.
        /// </summary>
        /// <param name="operation">The operation to be updated.</param>
        /// <param name="element">The xml element representing an operation in the annotation xml.</param>
        /// <param name="settings">The operation filter settings.</param>
        /// <remarks>
        /// Care should be taken to not overwrite the existing value in Operation if already present.
        /// This guarantees the predictable behavior that the first tag in the XML will be respected.
        /// It also guarantees that common annotations in the config file do not overwrite the
        /// annotations in the main documentation.
        /// </remarks>
        public void Apply(OpenApiOperation operation, XElement element, OperationFilterSettings settings)
        {
            var bodyElements = element.Elements()
                               .Where(
                p => p.Name == KnownXmlStrings.Param &&
                p.Attribute(KnownXmlStrings.In)?.Value == KnownXmlStrings.Body)
                               .ToList();

            foreach (var bodyElement in bodyElements)
            {
                var name      = bodyElement.Attribute(KnownXmlStrings.Name)?.Value.Trim();
                var mediaType = bodyElement.Attribute(KnownXmlStrings.Type)?.Value ?? "application/json";

                var childNodes  = bodyElement.DescendantNodes().ToList();
                var description = string.Empty;

                var lastNode = childNodes.LastOrDefault();

                if (lastNode != null && lastNode.NodeType == XmlNodeType.Text)
                {
                    description = lastNode.ToString();
                }

                var seeNodes = bodyElement.Descendants(KnownXmlStrings.See);

                var allListedTypes = seeNodes
                                     .Select(node => node.Attribute(KnownXmlStrings.Cref)?.Value)
                                     .Where(crefValue => crefValue != null).ToList();

                if (!allListedTypes.Any())
                {
                    throw new InvalidRequestBodyException(
                              string.Format(SpecificationGenerationMessages.MissingSeeCrefTag, name));
                }

                var type   = settings.TypeFetcher.LoadTypeFromCrefValues(allListedTypes);
                var schema = settings.ReferenceRegistryManager.SchemaReferenceRegistry.FindOrAddReference(type);

                if (operation.RequestBody == null)
                {
                    operation.RequestBody = new OpenApiRequestBody
                    {
                        Description = description.RemoveBlankLines(),
                        Content     =
                        {
                            [mediaType] = new OpenApiMediaType {
                                Schema = schema
                            }
                        },
                        Required = true
                    };
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(operation.RequestBody.Description))
                    {
                        operation.RequestBody.Description = description.RemoveBlankLines();
                    }

                    if (!operation.RequestBody.Content.ContainsKey(mediaType))
                    {
                        operation.RequestBody.Content[mediaType] = new OpenApiMediaType
                        {
                            Schema = schema
                        };
                    }
                    else
                    {
                        if (!operation.RequestBody.Content[mediaType].Schema.AnyOf.Any())
                        {
                            var existingSchema = operation.RequestBody.Content[mediaType].Schema;
                            var newSchema      = new OpenApiSchema();
                            newSchema.AnyOf.Add(existingSchema);

                            operation.RequestBody.Content[mediaType].Schema = newSchema;
                        }

                        operation.RequestBody.Content[mediaType].Schema.AnyOf.Add(schema);
                    }
                }
            }
        }
 public static IDictionary <OperationType, OpenApiOperation> OperationMap(OperationType type, OpenApiOperation operation)
 {
     return(new ConcurrentDictionary <OperationType, OpenApiOperation>
     {
         [type] = operation
     });
 }
Example #29
0
 public void Apply(OpenApiOperation operation, OperationFilterContext context)
 {
     operation.OperationId = FriendlyId(context.ApiDescription);
 }
 /// <summary>
 /// 获取方法对应的类名
 /// </summary>
 /// <param name="document"></param>
 /// <param name="path"></param>
 /// <param name="httpMethod"></param>
 /// <param name="operation"></param>
 /// <returns></returns>
 public override string GetClientName(OpenApiDocument document, string path, string httpMethod, OpenApiOperation operation)
 {
     return(operation.Tags.FirstOrDefault());
 }