Skip to content

Add JSON Source Gen #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<Project>
<!-- See https://aka.ms/dotnet/msbuild/customize for more details on customizing your build -->
<PropertyGroup>
<TargetFrameworks>net6.0;net462</TargetFrameworks>
<CurrentPreviewTfm>net8.0</CurrentPreviewTfm>
<!--<IncludePreview>true</IncludePreview>-->
<IncludePreview Condition=" '$(IncludePreview)' == ''">false</IncludePreview>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -10,7 +12,7 @@
<PropertyGroup>
<PasswordlessMajorVersion>1</PasswordlessMajorVersion>
<PasswordlessMinorVersion>0</PasswordlessMinorVersion>
<PasswordlessPatchVersion>1</PasswordlessPatchVersion>
<PasswordlessPatchVersion>2</PasswordlessPatchVersion>
<PasswordlessMajorMinorVersion>$(PasswordlessMajorVersion).$(PasswordlessMinorVersion)</PasswordlessMajorMinorVersion>
<VersionPrefix>$(PasswordlessMajorMinorVersion).$(PasswordlessPatchVersion)</VersionPrefix>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Sdk/Base64Url.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static string Encode(ReadOnlySpan<byte> arg)

#if NET5_0_OR_GREATER
Convert.TryToBase64Chars(arg, array, out var charsWritten);
#elif NET462
#elif NET462 || NETSTANDARD2_0
var charsWritten = Convert.ToBase64CharArray(arg.ToArray(), 0, minimumLength, array, 0);
#endif
Span<char> span = array.AsSpan(0, charsWritten);
Expand All @@ -42,7 +42,7 @@ public static string Encode(ReadOnlySpan<byte> arg)

#if NET5_0_OR_GREATER
string result = new string(span);
#elif NET462
#elif NET462 || NETSTANDARD2_0
string result = new string(span.ToArray());
#endif
ArrayPool<char>.Shared.Return(array, clearArray: true);
Expand Down
8 changes: 0 additions & 8 deletions src/Sdk/Helpers/Json.cs

This file was deleted.

26 changes: 26 additions & 0 deletions src/Sdk/Helpers/PasswordlessSerializerContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Passwordless.Net.Models;

namespace Passwordless.Net.Helpers;

[JsonSourceGenerationOptions(
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(RegisterTokenResponse))]
[JsonSerializable(typeof(RegisterOptions))]
[JsonSerializable(typeof(VerifyTokenRequest))] // TODO: Use this with JsonContent.Create
[JsonSerializable(typeof(VerifiedUser))]
[JsonSerializable(typeof(DeleteUserRequest))]
[JsonSerializable(typeof(ListResponse<PasswordlessUserSummary>))]
[JsonSerializable(typeof(ListResponse<AliasPointer>))]
[JsonSerializable(typeof(ListResponse<Credential>))]
[JsonSerializable(typeof(DeleteCredentialRequest))]
[JsonSerializable(typeof(UsersCount))]
[JsonSerializable(typeof(PasswordlessProblemDetails))]
[JsonSerializable(typeof(Dictionary<string, JsonElement>))]
[JsonSerializable(typeof(JsonElement))]
internal partial class PasswordlessSerializerContext : JsonSerializerContext
{

}
2 changes: 1 addition & 1 deletion src/Sdk/IPasswordlessClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public interface IPasswordlessClient
/// <param name="cancellationToken"></param>
/// <returns>A task object representing the asynchronous operation containing the <see cref="IReadOnlyList{PasswordlessUserSummary}" />.</returns>
/// <exception cref="PasswordlessApiException">An exception containing details abaout the reason for failure.</exception>
Task<IReadOnlyList<PasswordlessUserSummary>?> ListUsersAsync(CancellationToken cancellationToken = default);
Task<IReadOnlyList<PasswordlessUserSummary>> ListUsersAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Verifies that the given token is valid and returns information packed into it. The token should have been generated
Expand Down
13 changes: 10 additions & 3 deletions src/Sdk/Models/AliasPointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

public class AliasPointer
{
public string UserId { get; set; }
public string Alias { get; set; }
public string Plaintext { get; set; }
public AliasPointer(string userId, string alias, string plaintext)
{
UserId = userId;
Alias = alias;
Plaintext = plaintext;
}

public string UserId { get; }
public string Alias { get; }
public string Plaintext { get; }
}
9 changes: 0 additions & 9 deletions src/Sdk/Models/AuditLog.cs

This file was deleted.

48 changes: 34 additions & 14 deletions src/Sdk/Models/Credential.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,38 @@

public class Credential
{
public CredentialDescriptor Descriptor { get; set; }
public byte[] PublicKey { get; set; }
public byte[] UserHandle { get; set; }
public uint SignatureCounter { get; set; }
public string AttestationFmt { get; set; }
public DateTime CreatedAt { get; set; }
public Guid AaGuid { get; set; }
public DateTime LastUsedAt { get; set; }
public string RPID { get; set; }
public string Origin { get; set; }
public string Country { get; set; }
public string Device { get; set; }
public string Nickname { get; set; }
public string UserId { get; set; }
public Credential(CredentialDescriptor descriptor, byte[] publicKey, byte[] userHandle, uint signatureCounter,
string attestationFmt, DateTime createdAt, Guid aaGuid, DateTime lastUsedAt, string rpid,
string origin, string country, string device, string nickname, string userId)
{
Descriptor = descriptor;
PublicKey = publicKey;
UserHandle = userHandle;
SignatureCounter = signatureCounter;
AttestationFmt = attestationFmt;
CreatedAt = createdAt;
AaGuid = aaGuid;
LastUsedAt = lastUsedAt;
RPID = rpid;
Origin = origin;
Country = country;
Device = device;
Nickname = nickname;
UserId = userId;
}

public CredentialDescriptor Descriptor { get; }
public byte[] PublicKey { get; }
public byte[] UserHandle { get; }
public uint SignatureCounter { get; }
public string AttestationFmt { get; }
public DateTime CreatedAt { get; }
public Guid AaGuid { get; }
public DateTime LastUsedAt { get; }
public string RPID { get; }
public string Origin { get; }
public string Country { get; }
public string Device { get; }
public string Nickname { get; }
public string UserId { get; }
}
7 changes: 5 additions & 2 deletions src/Sdk/Models/CredentialDescriptor.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Text.Json.Serialization;

using static Passwordless.Net.PasswordlessClient;

namespace Passwordless.Net;

public class CredentialDescriptor
{
public CredentialDescriptor(byte[] id)
{
Id = id;
}

[JsonConverter(typeof(Base64UrlConverter))]
public byte[] Id { get; set; }
}
11 changes: 11 additions & 0 deletions src/Sdk/Models/DeleteCredentialRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Passwordless.Net.Models;

internal class DeleteCredentialRequest
{
public DeleteCredentialRequest(string credentialId)
{
CredentialId = credentialId;
}

public string CredentialId { get; }
}
11 changes: 11 additions & 0 deletions src/Sdk/Models/DeleteUserRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Passwordless.Net.Models;

internal class DeleteUserRequest
{
public DeleteUserRequest(string userId)
{
UserId = userId;
}

public string UserId { get; }
}
20 changes: 15 additions & 5 deletions src/Sdk/Models/PasswordlessUserSummary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ namespace Passwordless.Net;

public class PasswordlessUserSummary
{
public string UserId { get; set; }
public List<string> Aliases { get; set; }
public int CredentialsCount { get; set; }
public int AliasCount { get; set; }
public DateTime? LastUsedAt { get; set; }
public PasswordlessUserSummary(string userId, IReadOnlyList<string> aliases, int credentialsCount,
int aliasCount, DateTime? lastUsedAt)
{
UserId = userId;
Aliases = aliases;
CredentialsCount = credentialsCount;
AliasCount = aliasCount;
LastUsedAt = lastUsedAt;
}

public string UserId { get; }
public IReadOnlyList<string> Aliases { get; }
public int CredentialsCount { get; }
public int AliasCount { get; }
public DateTime? LastUsedAt { get; }
}
4 changes: 3 additions & 1 deletion src/Sdk/Models/RegisterOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Passwordless.Net;
using System.Text.Json.Serialization;

namespace Passwordless.Net;

/// <summary>
///
Expand Down
11 changes: 9 additions & 2 deletions src/Sdk/Models/RegisterTokenResponse.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
namespace Passwordless.Net.Models;
using System.Text.Json.Serialization;

namespace Passwordless.Net.Models;

public class RegisterTokenResponse
{
public string Token { get; set; }
public RegisterTokenResponse(string token)
{
Token = token;
}

public string Token { get; }
}
7 changes: 6 additions & 1 deletion src/Sdk/Models/UsersCount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@ namespace Passwordless.Net;

public class UsersCount
{
public int Count { get; set; }
public UsersCount(int count)
{
Count = count;
}

public int Count { get; }
}
42 changes: 30 additions & 12 deletions src/Sdk/Models/VerifiedUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,34 @@

public class VerifiedUser
{
public string UserId { get; set; }
public byte[] CredentialId { get; set; }
public bool Success { get; set; }
public DateTime Timestamp { get; set; }
public string RpId { get; set; }
public string Origin { get; set; }
public string Device { get; set; }
public string Country { get; set; }
public string Nickname { get; set; }
public DateTime ExpiresAt { get; set; }
public Guid TokenId { get; set; }
public string Type { get; set; }
public VerifiedUser(string userId, byte[] credentialId, bool success,
DateTime timestamp, string rpId, string origin, string device,
string country, string nickname, DateTime expiresAt, Guid tokenId,
string type)
{
UserId = userId;
CredentialId = credentialId;
Success = success;
Timestamp = timestamp;
RpId = rpId;
Origin = origin;
Device = device;
Country = country;
Nickname = nickname;
ExpiresAt = expiresAt;
TokenId = tokenId;
Type = type;
}
public string UserId { get; }
public byte[] CredentialId { get; }
public bool Success { get; }
public DateTime Timestamp { get; }
public string RpId { get; }
public string Origin { get; }
public string Device { get; }
public string Country { get; }
public string Nickname { get; }
public DateTime ExpiresAt { get; }
public Guid TokenId { get; }
public string Type { get; }
}
11 changes: 11 additions & 0 deletions src/Sdk/Models/VerifyTokenRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Passwordless.Net.Models;

internal class VerifyTokenRequest
{
public VerifyTokenRequest(string token)
{
Token = token;
}

public string Token { get; }
}
31 changes: 21 additions & 10 deletions src/Sdk/PasswordlessApiException.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
using System.Diagnostics;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Passwordless.Net;

public sealed class PasswordlessApiException : HttpRequestException
{
public ProblemDetails Details { get; }
public PasswordlessProblemDetails Details { get; }

public PasswordlessApiException(ProblemDetails problemDetails) : base(problemDetails.Title)
public PasswordlessApiException(PasswordlessProblemDetails problemDetails) : base(problemDetails.Title)
{
Details = problemDetails;
}
}

public class ProblemDetails
public class PasswordlessProblemDetails
{
// TODO: Make immutable
public PasswordlessProblemDetails(string type,
string title, int status, string? detail, string? instance)
{
Type = type;
Title = title;
Status = status;
Detail = detail;
Instance = instance;
}

// TODO: Include errorCode as a property once it's more common
public string Type { get; set; } = null!;
public string Title { get; set; } = null!;
public int Status { get; set; }
public string? Detail { get; set; }
public string? Instance { get; set; }
public string Type { get; }
public string Title { get; }
public int Status { get; }
public string? Detail { get; }
public string? Instance { get; }

[JsonExtensionData]
public Dictionary<string, object?> Extensions { get; set; }
public Dictionary<string, JsonElement> Extensions { get; set; } = new Dictionary<string, JsonElement>();
}
Loading