Skip to content

Commit

Permalink
POST instance: don't attemt to parse instance from body when it's emp…
Browse files Browse the repository at this point in the history
…ty or not json (#888)

* POST instance: don't attemt to parse instance from body when it's empty or not json

* Add test and fix bug in previous code

* Further improve test coverage

* fix warning
  • Loading branch information
ivarne authored Nov 7, 2024
1 parent c45bc7c commit 3410918
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 9 deletions.
22 changes: 13 additions & 9 deletions src/Altinn.App.Api/Controllers/InstancesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,14 +1228,8 @@ string action
{
RequestPart? instancePart = parts.Find(part => part.Name == "instance");

// assume that first part with no name is an instanceTemplate
if (
instancePart == null
&& parts.Count == 1
&& parts[0].ContentType.Contains("application/json")
&& parts[0].Name == null
&& parts[0].Bytes.Length > 0
)
// If the request has a single part with no name, assume it is the instance template
if (instancePart == null && parts.Count == 1 && parts[0].Name == null)
{
instancePart = parts[0];
}
Expand All @@ -1244,7 +1238,17 @@ string action
{
parts.Remove(instancePart);

return System.Text.Json.JsonSerializer.Deserialize<Instance>(instancePart.Bytes, _jsonSerializerOptionsWeb);
// Some clients might set contentType to application/json even if the body is empty
if (
instancePart is { Bytes.Length: > 0 }
&& instancePart.ContentType.Contains("application/json", StringComparison.Ordinal)
)
{
return System.Text.Json.JsonSerializer.Deserialize<Instance>(
instancePart.Bytes,
_jsonSerializerOptionsWeb
);
}
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Net;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
Expand Down Expand Up @@ -273,6 +274,56 @@ public async Task InstationAllowedByOrg_Returns_Forbidden_For_user()
createResponse.StatusCode.Should().Be(HttpStatusCode.Forbidden, createResponseContent);
}

[Fact]
public async Task PostNewInstanceWithInstanceTemplate()
{
string org = "tdd";
string app = "contributer-restriction";
int instanceOwnerPartyId = 501337;
int userId = 1337;
HttpClient client = GetRootedClient(org, app, userId, null);

using var content = JsonContent.Create(
new Instance() { InstanceOwner = new InstanceOwner() { PartyId = instanceOwnerPartyId.ToString() }, }
);

var response = await client.PostAsync($"{org}/{app}/instances", content);
response.Should().HaveStatusCode(HttpStatusCode.Created);
var responseContent = await response.Content.ReadAsStringAsync();
var instance = JsonSerializer.Deserialize<Instance>(responseContent, JsonSerializerOptions);
instance.Should().NotBeNull();
instance!.Id.Should().NotBeNullOrEmpty();

TestData.DeleteInstanceAndData(org, app, instance.Id);
}

[Fact]
public async Task PostNewInstanceWithMissingTemplate()
{
string org = "tdd";
string app = "contributer-restriction";
int instanceOwnerPartyId = 501337;
int userId = 1337;
HttpClient client = GetRootedClient(org, app, userId, null);

using var content = new ByteArrayContent([])
{
Headers = { ContentType = new MediaTypeHeaderValue("application/json") }
};

var response = await client.PostAsync(
$"{org}/{app}/instances?instanceOwnerPartyId={instanceOwnerPartyId}",
content
);
response.Should().HaveStatusCode(HttpStatusCode.Created);
var responseContent = await response.Content.ReadAsStringAsync();
var instance = JsonSerializer.Deserialize<Instance>(responseContent, JsonSerializerOptions);
instance.Should().NotBeNull();
instance!.Id.Should().NotBeNullOrEmpty();

TestData.DeleteInstanceAndData(org, app, instance.Id);
}

[Fact]
public async Task InstationAllowedByOrg_Returns_Forbidden_For_User_SimplifiedEndpoint()
{
Expand Down

0 comments on commit 3410918

Please sign in to comment.