Skip to content

Commit 6f4d79f

Browse files
committed
Add test where AltinnRowId needs to be scrubbed
1 parent 9527fc5 commit 6f4d79f

9 files changed

Lines changed: 53 additions & 34 deletions

File tree

src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,11 @@ public async Task<List<ValidationIssue>> Validate(
8787
);
8888
continue;
8989
}
90-
var formData = await dataAccessor.GetFormData(dataElement);
91-
ObjectUtils.RemoveAltinnRowId(formData);
90+
var formData = await dataAccessor.GetFormDataWrapper(dataElement);
91+
var formDataCopy = formData.Copy();
92+
formDataCopy.RemoveAltinnRowIds();
9293

93-
var serializedFormData = _modelSerializationService.SerializeToXml(formData);
94+
var serializedFormData = _modelSerializationService.SerializeToXml(formDataCopy.BackingData<object>());
9495
var parsedSchema = new XmlSchemaSet { XmlResolver = null };
9596
var xsdReaderSettings = new XmlReaderSettings
9697
{

src/Altinn.App.Core/Internal/Data/IDataElementAccessChecker.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55

66
namespace Altinn.App.Core.Internal.Data;
77

8-
internal interface IDataElementAccessChecker
8+
/// <summary>
9+
/// Interface for checking if the current user has access to perform operations on data elements of an instance.
10+
/// </summary>
11+
public interface IDataElementAccessChecker
912
{
1013
/// <summary>
1114
/// Checks if the user has access to read a data element of a given data type on an instance.

test/Altinn.App.Api.Tests/Controllers/ResourceControllerTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ public ResourceControllerTests(WebApplicationFactory<Program> factory, ITestOutp
1010

1111
private const string Org = "tdd";
1212
private const string App = "contributer-restriction";
13-
private const string DefaultDataTypeId = "Skjema";
13+
private const string DefaultModelName = "Skjema";
1414

1515
[Fact]
1616
public async Task GetModelJsonSchema_ReturnsOk()
1717
{
1818
var client = GetRootedClient(Org, App);
19-
using var response = await client.GetAsync($"/{Org}/{App}/api/jsonschema/{DefaultDataTypeId}");
19+
using var response = await client.GetAsync($"/{Org}/{App}/api/jsonschema/{DefaultModelName}");
2020
response.EnsureSuccessStatusCode();
2121
var content = await response.Content.ReadAsStringAsync();
2222
Assert.NotNull(content);
2323
Assert.Contains("\"$comment\"", content); // TODO: Update when the schema in the test project has more content.
2424
}
2525

2626
[Fact]
27-
public async Task GetModelJsonSchema_InvalidDataTypeId_ReturnsNotFound()
27+
public async Task GetModelJsonSchema_InvalidModelName_ReturnsNotFound()
2828
{
2929
var client = GetRootedClient(Org, App);
3030
await Assert.ThrowsAsync<FileNotFoundException>(async () =>
3131
{
32-
using var response = await client.GetAsync($"/{Org}/{App}/api/jsonschema/InvalidDataTypeId");
32+
using var response = await client.GetAsync($"/{Org}/{App}/api/jsonschema/InvalidModelName");
3333
// TODO: Should probably return 404 NotFound instead of throwing FileNotFoundException,
3434
// but adding test for current behaviour.
3535
// Assert.Equal(System.Net.HttpStatusCode.NotFound, response.StatusCode);
@@ -40,18 +40,18 @@ await Assert.ThrowsAsync<FileNotFoundException>(async () =>
4040
public async Task GetXmlSchema_ReturnsOk()
4141
{
4242
var client = GetRootedClient(Org, App);
43-
using var response = await client.GetAsync($"/{Org}/{App}/api/xsdschema/{DefaultDataTypeId}");
43+
using var response = await client.GetAsync($"/{Org}/{App}/api/xsdschema/{DefaultModelName}");
4444
response.EnsureSuccessStatusCode();
4545
var content = await response.Content.ReadAsStringAsync();
4646
Assert.NotNull(content);
4747
Assert.Contains("<xs:schema xmlns:xs=", content); // TODO: Update when the schema in the test project has more content.
4848
}
4949

5050
[Fact]
51-
public async Task GetXmlSchema_InvalidDataTypeId_ReturnsNotFound()
51+
public async Task GetXmlSchema_InvalidModelName_ReturnsNotFound()
5252
{
5353
var client = GetRootedClient(Org, App);
54-
using var response = await client.GetAsync($"/{Org}/{App}/api/xsdschema/InvalidDataTypeId");
54+
using var response = await client.GetAsync($"/{Org}/{App}/api/xsdschema/InvalidModelName");
5555
Assert.Equal(System.Net.HttpStatusCode.NotFound, response.StatusCode);
5656
}
5757
}

test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,12 @@ public async Task ValidateInstance_WithXsdValidator()
153153
DataGuid,
154154
new Skjema()
155155
{
156-
Melding = new() { Name = "Name is required in layout", MissingFromXsd = "This will error" },
156+
Melding = new()
157+
{
158+
Name = "Name is required in layout",
159+
NestedList = [new() { AltinnRowId = Guid.NewGuid(), Key = "key" }],
160+
MissingFromXsd = "This will error",
161+
},
157162
}
158163
);
159164

test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public class Dummy
3737
[JsonPropertyName("simple_list")]
3838
public ValuesList? SimpleList { get; set; }
3939

40-
[XmlElement("nested_list", Order = 5)]
40+
[XmlArray("nested_list", Order = 5)]
41+
[XmlArrayItem("nested_list_item")]
4142
[JsonProperty("nested_list")]
4243
[JsonPropertyName("nested_list")]
4344
public List<Nested>? NestedList { get; set; }
@@ -116,10 +117,7 @@ public class SimpleKeyvalues
116117
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
117118
public Guid AltinnRowId { get; set; }
118119

119-
public bool AltinnRowIdSpecified()
120-
{
121-
return AltinnRowId != default;
122-
}
120+
public bool ShouldSerializeAltinnRowId() => AltinnRowId != default;
123121

124122
[XmlElement("key", Order = 1)]
125123
[JsonProperty("key")]
@@ -145,10 +143,7 @@ public class Nested
145143
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
146144
public Guid AltinnRowId { get; set; }
147145

148-
public bool AltinnRowIdSpecified()
149-
{
150-
return AltinnRowId != default;
151-
}
146+
public bool ShouldSerializeAltinnRowId() => AltinnRowId != default;
152147

153148
[XmlElement("key", Order = 1)]
154149
[JsonProperty("key")]

test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.xsd

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<xs:element name="random" type="xs:string" minOccurs="0" maxOccurs="1"/>
2121
<xs:element name="tags" type="xs:string" minOccurs="0" maxOccurs="1"/>
2222
<xs:element name="simple_list" type="ValuesListType" minOccurs="0" maxOccurs="1"/>
23-
<xs:element name="nested_list" type="NestedType" minOccurs="0" maxOccurs="unbounded"/>
23+
<xs:element name="nested_list" type="NestedListType" minOccurs="0" maxOccurs="1"/>
2424
<xs:element name="toggle" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
2525
<xs:element name="tag-with-attribute" type="TagWithAttributeType" minOccurs="0" maxOccurs="1" nillable="true"/>
2626
<xs:element name="hidden" type="xs:string" minOccurs="0" maxOccurs="1"/>
@@ -62,7 +62,13 @@
6262
<xs:element name="doubleValue" type="xs:decimal" minOccurs="0" maxOccurs="1"/>
6363
<xs:element name="intValue" type="xs:decimal" minOccurs="0" maxOccurs="1"/>
6464
</xs:sequence>
65-
<xs:attribute name="altinnRowId" type="xs:string" use="optional"/>
65+
</xs:complexType>
66+
67+
<!-- NestedList Type -->
68+
<xs:complexType name="NestedListType">
69+
<xs:sequence>
70+
<xs:element name="nested_list_item" type="NestedType" minOccurs="0" maxOccurs="unbounded"/>
71+
</xs:sequence>
6672
</xs:complexType>
6773

6874
<!-- Nested Type -->
@@ -71,7 +77,6 @@
7177
<xs:element name="key" type="xs:string" minOccurs="0" maxOccurs="1"/>
7278
<xs:element name="values" type="SimpleKeyvaluesType" minOccurs="0" maxOccurs="unbounded"/>
7379
</xs:sequence>
74-
<xs:attribute name="altinnRowId" type="xs:string" use="optional"/>
7580
</xs:complexType>
7681

7782
</xs:schema>

test/Altinn.App.Api.Tests/Data/apps/tdd/permissive-app/models/Skjema.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,7 @@ public class SimpleKeyvalues
9696
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
9797
public Guid AltinnRowId { get; set; }
9898

99-
public bool AltinnRowIdSpecified()
100-
{
101-
return AltinnRowId != default;
102-
}
99+
public bool ShouldSerializeAltinnRowId() => AltinnRowId != default;
103100

104101
[XmlElement("key", Order = 1)]
105102
[JsonProperty("key")]
@@ -125,10 +122,7 @@ public class Nested
125122
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
126123
public Guid AltinnRowId { get; set; }
127124

128-
public bool AltinnRowIdSpecified()
129-
{
130-
return AltinnRowId != default;
131-
}
125+
public bool ShouldSerializeAltinnRowId() => AltinnRowId != default;
132126

133127
[XmlElement("key", Order = 1)]
134128
[JsonProperty("key")]

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveCustomOpenApiSpec.verified.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,10 @@
37413741
"hiddenPageNotRemove": {
37423742
"type": "string",
37433743
"nullable": true
3744+
},
3745+
"missing-from-xsd": {
3746+
"type": "string",
3747+
"nullable": true
37443748
}
37453749
},
37463750
"additionalProperties": false

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,7 +2454,7 @@ namespace Altinn.App.Core.Implementation
24542454
public byte[] GetText(string org, string app, string textResource) { }
24552455
public System.Threading.Tasks.Task<Altinn.Platform.Storage.Interface.Models.TextResource?> GetTexts(string org, string app, string language) { }
24562456
public string? GetValidationConfiguration(string dataTypeId) { }
2457-
public string? GetXsdSchema(string dataTypeId) { }
2457+
public string? GetXsdSchema(string modelId) { }
24582458
}
24592459
public class DefaultAppEvents : Altinn.App.Core.Internal.App.IAppEvents
24602460
{
@@ -3018,7 +3018,7 @@ namespace Altinn.App.Core.Internal.App
30183018
byte[] GetText(string org, string app, string textResource);
30193019
System.Threading.Tasks.Task<Altinn.Platform.Storage.Interface.Models.TextResource?> GetTexts(string org, string app, string language);
30203020
string? GetValidationConfiguration(string dataTypeId);
3021-
string? GetXsdSchema(string dataTypeId);
3021+
string? GetXsdSchema(string modelId);
30223022
}
30233023
public interface IApplicationClient
30243024
{
@@ -3170,6 +3170,18 @@ namespace Altinn.App.Core.Internal.Data
31703170
{
31713171
public static System.Threading.Tasks.Task<T> GetFormData<T>(this Altinn.App.Core.Internal.Data.IDataClient dataClient, Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataElement dataElement, Altinn.App.Core.Features.StorageAuthenticationMethod? authenticationMethod = null, System.Threading.CancellationToken cancellationToken = default) { }
31723172
}
3173+
public interface IDataElementAccessChecker
3174+
{
3175+
System.Threading.Tasks.Task<bool> CanCreate(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType, Altinn.App.Core.Features.Auth.Authenticated? auth = null, long? contentLength = default);
3176+
System.Threading.Tasks.Task<bool> CanDelete(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType, System.Guid dataElementId, Altinn.App.Core.Features.Auth.Authenticated? auth = null);
3177+
System.Threading.Tasks.Task<bool> CanRead(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType);
3178+
System.Threading.Tasks.Task<bool> CanUpdate(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType, Altinn.App.Core.Features.Auth.Authenticated? auth = null);
3179+
System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.ProblemDetails?> GetCreateProblem(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType, Altinn.App.Core.Features.Auth.Authenticated? auth = null, long? contentLength = default);
3180+
System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.ProblemDetails?> GetDeleteProblem(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType, System.Guid dataElementId, Altinn.App.Core.Features.Auth.Authenticated? auth = null);
3181+
System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.ProblemDetails?> GetReaderProblem(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataElement dataElement);
3182+
System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.ProblemDetails?> GetReaderProblem(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType);
3183+
System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.ProblemDetails?> GetUpdateProblem(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.Platform.Storage.Interface.Models.DataType dataType, Altinn.App.Core.Features.Auth.Authenticated? auth = null);
3184+
}
31733185
public interface IDataService
31743186
{
31753187
System.Threading.Tasks.Task<bool> DeleteById(Altinn.App.Core.Models.InstanceIdentifier instanceIdentifier, System.Guid dataElementId, Altinn.App.Core.Features.StorageAuthenticationMethod? authenticationMethod = null, System.Threading.CancellationToken ct = default);

0 commit comments

Comments
 (0)