Skip to content

Commit ed4a2a6

Browse files
committed
Add 403 status when client-generated IDs are forbidden (default)
1 parent c64e308 commit ed4a2a6

File tree

13 files changed

+73
-2
lines changed

13 files changed

+73
-2
lines changed

src/JsonApiDotNetCore.OpenApi/SwaggerComponents/JsonApiOperationDocumentationFilter.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,20 @@ internal sealed class JsonApiOperationDocumentationFilter : IOperationFilter
3333
private const string TextRequestBodyIncompatibleType = "A resource type in the request body is incompatible.";
3434
private const string TextRequestBodyIncompatibleIdOrType = "A resource type or identifier in the request body is incompatible.";
3535
private const string TextRequestBodyValidationFailed = "Validation of the request body failed.";
36+
private const string TextRequestBodyClientId = "Client-generated IDs cannot be used at this endpoint.";
3637

38+
private readonly IJsonApiOptions _options;
3739
private readonly IControllerResourceMapping _controllerResourceMapping;
3840
private readonly ResourceFieldValidationMetadataProvider _resourceFieldValidationMetadataProvider;
3941

40-
public JsonApiOperationDocumentationFilter(IControllerResourceMapping controllerResourceMapping,
42+
public JsonApiOperationDocumentationFilter(IJsonApiOptions options, IControllerResourceMapping controllerResourceMapping,
4143
ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider)
4244
{
45+
ArgumentGuard.NotNull(options);
4346
ArgumentGuard.NotNull(controllerResourceMapping);
4447
ArgumentGuard.NotNull(resourceFieldValidationMetadataProvider);
4548

49+
_options = options;
4650
_controllerResourceMapping = controllerResourceMapping;
4751
_resourceFieldValidationMetadataProvider = resourceFieldValidationMetadataProvider;
4852
}
@@ -190,6 +194,13 @@ private void ApplyPostResource(OpenApiOperation operation, ResourceType resource
190194
SetResponseDescription(operation.Responses, HttpStatusCode.BadRequest, TextRequestBodyMissingOrMalformed);
191195
SetResponseDescription(operation.Responses, HttpStatusCode.Conflict, TextRequestBodyIncompatibleType);
192196
SetResponseDescription(operation.Responses, HttpStatusCode.UnprocessableEntity, TextRequestBodyValidationFailed);
197+
198+
ClientIdGenerationMode clientIdGeneration = resourceType.ClientIdGeneration ?? _options.ClientIdGeneration;
199+
200+
if (clientIdGeneration == ClientIdGenerationMode.Forbidden)
201+
{
202+
SetResponseDescription(operation.Responses, HttpStatusCode.Forbidden, TextRequestBodyClientId);
203+
}
193204
}
194205

195206
private void ApplyPatchResource(OpenApiOperation operation, ResourceType resourceType)

test/OpenApiClientTests/LegacyClient/swagger.g.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}
@@ -544,6 +547,9 @@
544547
},
545548
"422": {
546549
"description": "Validation of the request body failed."
550+
},
551+
"403": {
552+
"description": "Client-generated IDs cannot be used at this endpoint."
547553
}
548554
}
549555
}
@@ -1262,6 +1268,9 @@
12621268
},
12631269
"422": {
12641270
"description": "Validation of the request body failed."
1271+
},
1272+
"403": {
1273+
"description": "Client-generated IDs cannot be used at this endpoint."
12651274
}
12661275
}
12671276
}

test/OpenApiClientTests/NamingConventions/CamelCase/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiClientTests/NamingConventions/KebabCase/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiClientTests/NamingConventions/PascalCase/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOn/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOff/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOn/swagger.g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}

test/OpenApiTests/DocComments/DocCommentsStartup.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using JetBrains.Annotations;
2+
using JsonApiDotNetCore.Configuration;
23
using Microsoft.Extensions.DependencyInjection;
34
using Microsoft.OpenApi.Models;
45
using Swashbuckle.AspNetCore.SwaggerGen;
@@ -10,6 +11,12 @@ namespace OpenApiTests.DocComments;
1011
public sealed class DocCommentsStartup<TDbContext> : OpenApiStartup<TDbContext>
1112
where TDbContext : TestableDbContext
1213
{
14+
protected override void SetJsonApiOptions(JsonApiOptions options)
15+
{
16+
options.ClientIdGeneration = ClientIdGenerationMode.Allowed;
17+
base.SetJsonApiOptions(options);
18+
}
19+
1320
protected override void SetupSwaggerGenAction(SwaggerGenOptions options)
1421
{
1522
options.SwaggerDoc("v1", new OpenApiInfo

test/OpenApiTests/DocComments/DocCommentsTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,17 @@ public async Task Enums_are_documented()
483483
schemasElement.Should().HaveProperty("spaceKind.description", "Lists the various kinds of spaces within a skyscraper.");
484484
});
485485
}
486+
487+
[Fact]
488+
public async Task Forbidden_status_is_added_when_client_generated_IDs_are_disabled()
489+
{
490+
// Act
491+
JsonElement document = await _testContext.GetSwaggerDocumentAsync();
492+
493+
// Assert
494+
document.Should().ContainPath("paths./elevators.post.responses").With(responseElement =>
495+
{
496+
responseElement.Should().HaveProperty("403.description", "Client-generated IDs cannot be used at this endpoint.");
497+
});
498+
}
486499
}

test/OpenApiTests/DocComments/Elevator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using JetBrains.Annotations;
2+
using JsonApiDotNetCore.Configuration;
23
using JsonApiDotNetCore.Resources;
34
using JsonApiDotNetCore.Resources.Annotations;
45

@@ -8,7 +9,7 @@ namespace OpenApiTests.DocComments;
89
/// An elevator within a skyscraper.
910
/// </summary>
1011
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
11-
[Resource(ControllerNamespace = "OpenApiTests.DocComments")]
12+
[Resource(ControllerNamespace = "OpenApiTests.DocComments", ClientIdGeneration = ClientIdGenerationMode.Forbidden)]
1213
public sealed class Elevator : Identifiable<long>
1314
{
1415
/// <summary>

test/OpenApiTests/LegacyOpenApiIntegration/swagger.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
},
7777
"422": {
7878
"description": "Validation of the request body failed."
79+
},
80+
"403": {
81+
"description": "Client-generated IDs cannot be used at this endpoint."
7982
}
8083
}
8184
}
@@ -544,6 +547,9 @@
544547
},
545548
"422": {
546549
"description": "Validation of the request body failed."
550+
},
551+
"403": {
552+
"description": "Client-generated IDs cannot be used at this endpoint."
547553
}
548554
}
549555
}
@@ -1262,6 +1268,9 @@
12621268
},
12631269
"422": {
12641270
"description": "Validation of the request body failed."
1271+
},
1272+
"403": {
1273+
"description": "Client-generated IDs cannot be used at this endpoint."
12651274
}
12661275
}
12671276
}

0 commit comments

Comments
 (0)