Skip to content

Commit

Permalink
Replace with Swagger filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Hinton committed Feb 9, 2024
1 parent dfd1c22 commit 1caac50
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#nullable enable

using System.ComponentModel.DataAnnotations;
using Bit.Core.Models.Api;
using Bit.Core.SecretsManager.Entities;

Expand All @@ -27,10 +26,8 @@ public BaseSecretResponseModel(Secret secret, string objectName = _objectName) :
Projects = secret.Projects?.Select(p => new SecretResponseInnerProject(p));
}

[Required]
public Guid Id { get; }

[Required]
public Guid OrganizationId { get; }

public string? Key { get; }
Expand All @@ -39,10 +36,8 @@ public BaseSecretResponseModel(Secret secret, string objectName = _objectName) :

public string? Note { get; }

[Required]
public DateTime CreationDate { get; }

[Required]
public DateTime RevisionDate { get; }

public IEnumerable<SecretResponseInnerProject>? Projects { get; init; }
Expand Down
1 change: 1 addition & 0 deletions src/Api/Utilities/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public static void AddSwagger(this IServiceCollection services, GlobalSettings g
// config.UseReferencedDefinitionsForEnums();

config.SchemaFilter<EnumSchemaFilter>();
config.SchemaFilter<RequireNotNullableSchemaFilter>();

var apiFilePath = Path.Combine(AppContext.BaseDirectory, "Api.xml");
config.IncludeXmlComments(apiFilePath, true);
Expand Down
66 changes: 66 additions & 0 deletions src/SharedWeb/Swagger/RequireNotNullableSchemaFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Reflection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Bit.SharedWeb.Swagger;

/// <summary>
///
/// </summary>
/// <remarks>
/// Credits: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/2036#issuecomment-894015122
/// </remarks>
public class RequireNotNullableSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (schema.Properties == null)
{
return;
}

FixNullableProperties(schema, context);

var notNullableProperties = schema
.Properties
.Where(x => !x.Value.Nullable && x.Value.Default == default && !schema.Required.Contains(x.Key))
.ToList();

foreach (var property in notNullableProperties)
{
schema.Required.Add(property.Key);
}
}

/// <summary>
/// Option "SupportNonNullableReferenceTypes" not working with complex types ({ "type": "object" }),
/// so they always have "Nullable = false",
/// see method "SchemaGenerator.GenerateSchemaForMember"
/// </summary>
private static void FixNullableProperties(OpenApiSchema schema, SchemaFilterContext context)
{
foreach (var property in schema.Properties)
{
var field = context.Type
.GetMembers(BindingFlags.Public | BindingFlags.Instance)
.FirstOrDefault(x =>
string.Equals(x.Name, property.Key, StringComparison.InvariantCultureIgnoreCase));

if (field == null)
{
continue;
}

var fieldType = field switch
{
FieldInfo fieldInfo => fieldInfo.FieldType,
PropertyInfo propertyInfo => propertyInfo.PropertyType,
_ => throw new NotSupportedException(),
};

property.Value.Nullable = fieldType.IsValueType
? Nullable.GetUnderlyingType(fieldType) != null
: !field.IsNonNullableReferenceType();
}
}
}

0 comments on commit 1caac50

Please sign in to comment.