Skip to content

Commit

Permalink
[dotnet] Experimental platform-specific token provider with dependenc…
Browse files Browse the repository at this point in the history
…y injection support (#492)

* Experimental token provider implementation

* Host tests

* Add extension methods

* Remove Browser project

* Cleanup

* Update default tests to staging
  • Loading branch information
tmarkovski authored Mar 18, 2022
1 parent 34d38b5 commit 95ac9c2
Show file tree
Hide file tree
Showing 29 changed files with 554 additions and 324 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- run: |
dotnet workload install ios
dotnet restore
dotnet build -c Release /p:IsBrowser=true ./Trinsic
dotnet build -c Release -f net6.0 -p:IsBrowser=true ./Trinsic
dotnet build -c Release
dotnet test -c Release -v n
working-directory: ./dotnet
Expand Down
3 changes: 1 addition & 2 deletions dotnet/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

[*]
charset = utf-8
end_of_line = lf
Expand All @@ -10,7 +9,7 @@ indent_size = 4
# Microsoft .NET properties
csharp_new_line_before_catch = false
csharp_new_line_before_members_in_object_initializers = false
csharp_new_line_before_open_brace = accessors,control_blocks,events,indexers,properties,types
csharp_new_line_before_open_brace = accessors, control_blocks, events, indexers, properties, types
csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = true:suggestion
Expand Down
46 changes: 23 additions & 23 deletions dotnet/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
<Project>
<!-- Set common properties regarding assembly information and nuget packages -->
<PropertyGroup>
<Authors>Trinsic Engineering Team</Authors>
<Company>Trinsic</Company>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/trinsic-id/sdk</PackageProjectUrl>
<PackageTags>Trinsic</PackageTags>
<Product>Trinsic SDK for NET</Product>
<RepositoryUrl>https://github.com/trinsic-id/sdk.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>1.0.0</Version>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<!-- Common compile parameters -->
<PropertyGroup>
<!-- We use full (Windows PDBs) until cross platform support for source link will get better -->
<DebugType>full</DebugType>
<LangVersion>latest</LangVersion>
<NoWarn>$(NoWarn);1591</NoWarn>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<!-- Set common properties regarding assembly information and nuget packages -->
<PropertyGroup>
<Authors>Trinsic Engineering Team</Authors>
<Company>Trinsic</Company>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/trinsic-id/sdk</PackageProjectUrl>
<PackageTags>Trinsic</PackageTags>
<Product>Trinsic SDK for NET</Product>
<RepositoryUrl>https://github.com/trinsic-id/sdk.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>1.0.0</Version>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<!-- Common compile parameters -->
<PropertyGroup>
<!-- We use full (Windows PDBs) until cross platform support for source link will get better -->
<DebugType>full</DebugType>
<LangVersion>latest</LangVersion>
<NoWarn>$(NoWarn);1591</NoWarn>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
69 changes: 69 additions & 0 deletions dotnet/Tests/HostTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Trinsic;
using Trinsic.Services.Common.V1;
using Xunit;

namespace Tests;

public class HostTests
{
[Fact(DisplayName = "Test default service host")]
public async Task TestGenericHost() {
var host = Host
.CreateDefaultBuilder()
.ConfigureServices(services => {
services.AddTrinsic();
}).Build();

await host.StartAsync();

var providerService = host.Services.GetService<ProviderService>();
var accountService = host.Services.GetRequiredService<AccountService>();

providerService.Should().NotBeNull();
accountService.Should().NotBeNull();

accountService.Options.ServerEndpoint.Should().Be(ServiceBase.DefaultServerEndpoint);
accountService.Options.ServerPort.Should().Be(ServiceBase.DefaultServerPort);
accountService.Options.ServerUseTls.Should().Be(ServiceBase.DefaultServerUseTls);
accountService.Options.DefaultEcosystem.Should().Be(ServiceBase.DefaultEcosystem);
accountService.Options.AuthToken.Should().Be(string.Empty);
accountService.TokenProvider.Should().BeOfType<FileTokenProvider>();

await host.StopAsync();
}

[Fact(DisplayName = "Test configured service host")]
public async Task TestConfiguredGenericHost() {
var host = Host
.CreateDefaultBuilder()
.ConfigureServices(services => {
services.AddTrinsic(options => {
options.AuthToken = "auth";
options.DefaultEcosystem = "eco";
options.ServerEndpoint = "example.com";
options.ServerPort = 42;
options.ServerUseTls = true;
});
}).Build();

await host.StartAsync();

var providerService = host.Services.GetService<ProviderService>();
var accountService = host.Services.GetRequiredService<AccountService>();

providerService.Should().NotBeNull();
accountService.Should().NotBeNull();

accountService.Options.ServerEndpoint.Should().Be("example.com");
accountService.Options.ServerPort.Should().Be(42);
accountService.Options.ServerUseTls.Should().BeTrue();
accountService.Options.DefaultEcosystem.Should().Be("eco");
accountService.Options.AuthToken.Should().Be("auth");

await host.StopAsync();
}
}
20 changes: 10 additions & 10 deletions dotnet/Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Trinsic.Services.VerifiableCredentials.V1;
using FieldType = Trinsic.Services.VerifiableCredentials.Templates.V1.FieldType;
using JsonSerializer = System.Text.Json.JsonSerializer;

#pragma warning disable CS0618

namespace Tests;
Expand All @@ -32,9 +33,9 @@ public class Tests
const int DefaultPort = 5000;
const bool DefaultUseTls = false;
#else
const string DefaultEndpoint = "staging-internal.trinsic.cloud";
const int DefaultPort = 443;
const bool DefaultUseTls = true;
private const string DefaultEndpoint = "staging-internal.trinsic.cloud";
private const int DefaultPort = 443;
private const bool DefaultUseTls = true;
#endif

private readonly ITestOutputHelper _testOutputHelper;
Expand Down Expand Up @@ -67,9 +68,9 @@ public async Task TestWalletService() {
// SETUP ACTORS
// Create 3 different profiles for each participant in the scenario
// setupActors() {
var allison = await accountService.SignInAsync(new SignInRequest {EcosystemId = ecosystemId});
var clinic = await accountService.SignInAsync(new SignInRequest {EcosystemId = ecosystemId});
var airline = await accountService.SignInAsync(new SignInRequest {EcosystemId = ecosystemId});
var allison = await accountService.SignInAsync(new() {EcosystemId = ecosystemId});
var clinic = await accountService.SignInAsync(new() {EcosystemId = ecosystemId});
var airline = await accountService.SignInAsync(new() {EcosystemId = ecosystemId});
// }

accountService.Options.AuthToken = clinic;
Expand Down Expand Up @@ -251,7 +252,7 @@ public async Task TestInvitationIdSet() {
invitationResponse.Should().NotBeNull();
invitationResponse.InvitationCode.Should().NotBeEmpty();

await Assert.ThrowsAsync<Exception>(async () => await providerService.InvitationStatusAsync(new InvitationStatusRequest()));
await Assert.ThrowsAsync<Exception>(async () => await providerService.InvitationStatusAsync(new()));
}

[Fact(Skip = "Ecosystem support not complete yet")]
Expand All @@ -263,7 +264,7 @@ public async Task TestInviteParticipant() {
var response = await myProviderService.InviteParticipantAsync(invite);
Assert.NotNull(response);

var statusResponse = await myProviderService.InvitationStatusAsync(new InvitationStatusRequest {InvitationId = response.InvitationId});
var statusResponse = await myProviderService.InvitationStatusAsync(new() {InvitationId = response.InvitationId});
Assert.NotNull(statusResponse);
}

Expand Down Expand Up @@ -352,12 +353,11 @@ public async Task DemoTemplatesWithIssuance() {
}
}
}

public static class Extensions
{
public static ServiceOptions CloneWithAuthToken(this ServiceOptions options, string authToken) {
var cloned = options.Clone();
cloned.AuthToken = authToken;
return cloned;
}
}
}
25 changes: 13 additions & 12 deletions dotnet/Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="FluentAssertions" Version="6.2.0"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand All @@ -27,16 +28,16 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Trinsic\Trinsic.csproj" />
<ProjectReference Include="..\Trinsic\Trinsic.csproj"/>
</ItemGroup>
<ItemGroup>
<None Include="..\..\devops\testdata\vaccination-certificate-unsigned.jsonld">
<Link>TestData/vaccination-certificate-unsigned.jsonld</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\devops\testdata\vaccination-certificate-frame.jsonld">
<Link>TestData/vaccination-certificate-frame.jsonld</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\devops\testdata\vaccination-certificate-unsigned.jsonld">
<Link>TestData/vaccination-certificate-unsigned.jsonld</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\devops\testdata\vaccination-certificate-frame.jsonld">
<Link>TestData/vaccination-certificate-frame.jsonld</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
39 changes: 22 additions & 17 deletions dotnet/Trinsic/AccountService.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.Threading.Tasks;
using Google.Protobuf;
using Microsoft.Extensions.Options;
using Okapi.Security;
using Okapi.Security.V1;
using Trinsic.Sdk.Options.V1;
using Trinsic.Services.Account.V1;
using AccountServiceClient = Trinsic.Services.Account.V1.Account.AccountClient;

namespace Trinsic;

Expand All @@ -22,11 +22,20 @@ public AccountService(ServiceOptions options)
public AccountService() {
Client = new(Channel);
}


internal AccountService(ITokenProvider tokenProvider) : base(new(), tokenProvider) {
Client = new(Channel);
}

internal AccountService(ITokenProvider tokenProvider, IOptions<ServiceOptions> options)
: base(options.Value, tokenProvider) {
Client = new(Channel);
}

/// <summary>
/// Gets the underlying grpc client
/// </summary>
public AccountServiceClient Client { get; }
private Account.AccountClient Client { get; }

/// <summary>
/// Perform a sign-in to obtain an account profile. If the <see cref="AccountDetails" /> are
Expand All @@ -35,16 +44,12 @@ public AccountService() {
/// <param name="request"></param>
/// <returns></returns>
public async Task<string> SignInAsync(SignInRequest request) {
if (string.IsNullOrWhiteSpace(request.EcosystemId)) {
request.EcosystemId = Options.DefaultEcosystem;
}
if (string.IsNullOrWhiteSpace(request.EcosystemId)) request.EcosystemId = Options.DefaultEcosystem;
var response = await Client.SignInAsync(request);

var authToken = Convert.ToBase64String(response.Profile.ToByteArray());

if (!response.Profile.Protection?.Enabled ?? true) {
Options.AuthToken = authToken;
}

if (!response.Profile.Protection?.Enabled ?? true) await TokenProvider.SaveAsync(authToken);
return authToken;
}

Expand All @@ -55,13 +60,13 @@ public async Task<string> SignInAsync(SignInRequest request) {
/// <param name="request"></param>
/// <returns></returns>
public string SignIn(SignInRequest request) {
if (string.IsNullOrWhiteSpace(request.EcosystemId)) {
request.EcosystemId = Options.DefaultEcosystem;
}
if (string.IsNullOrWhiteSpace(request.EcosystemId)) request.EcosystemId = Options.DefaultEcosystem;
var response = Client.SignIn(request);

Options.AuthToken = Convert.ToBase64String(response.Profile.ToByteArray());
return Options.AuthToken;

var authToken = Convert.ToBase64String(response.Profile.ToByteArray());

if (!response.Profile.Protection?.Enabled ?? true) TokenProvider.Save(authToken);
return authToken;
}

/// <summary>
Expand Down Expand Up @@ -150,4 +155,4 @@ public RevokeDeviceResponse RevokeDevice() {
RevokeDeviceRequest request = new();
return Client.RevokeDevice(request, BuildMetadata(request));
}
}
}
Loading

0 comments on commit 95ac9c2

Please sign in to comment.