Skip to content

Commit

Permalink
Add ReportingApi model
Browse files Browse the repository at this point in the history
  • Loading branch information
trejjam committed Jun 17, 2023
1 parent f7a37ed commit 864626f
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/ReportingApi/IReportBody.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace ReportingApi;

public interface IReportBody
{
}
85 changes: 85 additions & 0 deletions src/ReportingApi/JsonConverters/ReportRequestConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using ReportingApi.Models;
using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace ReportingApi.JsonConverters;

public class ReportRequestConverter : JsonConverter<ReportRequest>
{
public const string TypeDiscriminator = "type";

public override ReportRequest? Read(
ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options
)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

var readerClone = reader;

if (readerClone.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}

readerClone.Read();

var depth = readerClone.CurrentDepth;
while (readerClone.Read())
{
if (depth < readerClone.CurrentDepth)
{
continue;
}

switch (readerClone.TokenType)
{
case JsonTokenType.PropertyName:
if (readerClone.GetString() == TypeDiscriminator)
{
readerClone.Read();

if (readerClone.TokenType is JsonTokenType.String)
{
var bodyType = GetBodyType(readerClone.ValueSpan);

var targetType = typeof(ReportRequest<>).MakeGenericType(bodyType);

return (ReportRequest?) JsonSerializer.Deserialize(
ref reader, targetType, options
);
}
}

break;

case JsonTokenType.StartArray:
case JsonTokenType.StartObject:
readerClone.Skip();

break;
}
}

throw new JsonException($"Expected '{TypeDiscriminator}' property, nothing found");
}

private Type GetBodyType(ReadOnlySpan<byte> type)
{
if (type.SequenceEqual("csp-violation"u8))
{
return typeof(CspReport);
}

var typeString = Encoding.UTF8.GetString(type);
throw new JsonException($"Type '{typeString}' does not have defined body type");
}

public override void Write(
Utf8JsonWriter writer, ReportRequest value, JsonSerializerOptions options
) => throw new NotImplementedException();
}
36 changes: 36 additions & 0 deletions src/ReportingApi/Models/CspReport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Text.Json.Serialization;

namespace ReportingApi.Models;

public class CspReport : IReportBody
{
[JsonPropertyName("blockedURL")]
public string BlockedUri { get; set; } = null!;

[JsonPropertyName("disposition")]
public string Disposition { get; set; } = null!;

[JsonPropertyName("documentURL")]
public string DocumentUri { get; set; } = null!;

[JsonPropertyName("effectiveDirective")]
public string EffectiveDirective { get; set; } = null!;

[JsonPropertyName("lineNumber")]
public int LineNumber { get; set; }

[JsonPropertyName("originalPolicy")]
public string OriginalPolicy { get; set; } = null!;

[JsonPropertyName("referrer")]
public string Referrer { get; set; } = null!;

[JsonPropertyName("sample")]
public string Sample { get; set; } = null!;

[JsonPropertyName("sourceFile")]
public string SourceFile { get; set; } = null!;

[JsonPropertyName("statusCode")]
public int StatusCode { get; set; }
}
27 changes: 27 additions & 0 deletions src/ReportingApi/Models/ReportRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using ReportingApi.JsonConverters;
using System.Text.Json.Serialization;

namespace ReportingApi.Models;

[JsonConverter(typeof(ReportRequestConverter))]
public class ReportRequest
{
[JsonPropertyName("age")]
public int Age { get; set; }

[JsonPropertyName("url")]
public string Url { get; set; } = null!;

[JsonPropertyName("user_agent")]
public string UserAgent { get; set; } = null!;
}

public class ReportRequest<TBody> : ReportRequest
where TBody : class, IReportBody
{
[JsonPropertyName("body")]
public TBody Body { get; set; } = null!;

[JsonPropertyName(ReportRequestConverter.TypeDiscriminator)]
public string Type { get; set; } = null!;
}
2 changes: 2 additions & 0 deletions src/ReportingApi/ReportingApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
<PackageReference Include="System.Text.Json" Version="7.0.3" />
</ItemGroup>



</Project>

0 comments on commit 864626f

Please sign in to comment.