Skip to content

Commit

Permalink
Remove remaining usage of "pub", render roles on sync
Browse files Browse the repository at this point in the history
  • Loading branch information
kzu committed Jun 12, 2024
1 parent ccbb6c3 commit cbf6f9d
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 16 deletions.
14 changes: 9 additions & 5 deletions src/Cli/Cli.csproj
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyName>sl</AssemblyName>
<AssemblyName>sponsorlink</AssemblyName>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<PackageId>dotnet-sl</PackageId>
<ToolCommandName>sl</ToolCommandName>
<PackageId>dotnet-sponsorlink</PackageId>
<ToolCommandName>sponsorlink</ToolCommandName>
<RollForward>Major</RollForward>
<PackAsTool>true</PackAsTool>
<PackContent>false</PackContent>
<Description>SponsorLink CLI</Description>
<PackageTags>dotnet dotnet-tool tools</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NuGetizer" Version="1.2.1" PrivateAssets="all"/>
<PackageReference Include="Spectre.Console.Cli" Version="0.49.1" />
<PackageReference Include="Devlooped.JQ" Version="1.7.1.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Commands\Commands.csproj" />
<ProjectReference Include="..\Core\Core.csproj" />
<ProjectReference Include="..\Commands\Commands.csproj" Pack="false" />
<ProjectReference Include="..\Core\Core.csproj" Pack="false" />
</ItemGroup>

</Project>
5 changes: 4 additions & 1 deletion src/Commands/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ Code for the backend and this app are [link=https://www.devlooped.com/SponsorLin
<value>Requesting manifest signing ...</value>
</data>
<data name="Sync_Thanks" xml:space="preserve">
<value>:check_mark_button: [lime]{sponsorable}[/]: thanks for sponsoring 💟</value>
<value>:check_mark_button: [lime]{sponsorable}[/]: thanks for sponsoring 💟 [dim](roles: {roles})[/]</value>
</data>
<data name="Sync_AutoSync" xml:space="preserve">
<value>[lime]?[/] Do you want to enable [link=https://www.devlooped.com/SponsorLink/github.html#auto-sync][blue]auto sync[/][/] of expired manifests?</value>
Expand Down Expand Up @@ -263,6 +263,9 @@ Code for the backend and this app are [link=https://www.devlooped.com/SponsorLin
<data name="Validate_InvalidExpired" xml:space="preserve">
<value>:cross_mark: [lime]{sponsorable}[/]: manifest expired {date}. Run [yellow]gh sponsors sync[/] to generate a new one.</value>
</data>
<data name="Validate_InvalidPublicKey" xml:space="preserve">
<value>:cross_mark: [lime]{sponsorable}[/]: invalid public key (JWK) provided by issuer</value>
</data>
<data name="Validate_InvalidSignature" xml:space="preserve">
<value>:cross_mark: [lime]{sponsorable}[/]: manifest signature is invalid. Run [yellow]gh sponsors sync[/] to generate a new one</value>
</data>
Expand Down
15 changes: 13 additions & 2 deletions src/Commands/SyncCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.ComponentModel;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using DotNetConfig;
using Spectre.Console;
Expand Down Expand Up @@ -195,7 +196,12 @@ await Status().StartAsync(Sync.FetchingManifests(sponsorables.Count), async ctx
if (status == SponsorManifest.Status.Success)
{
File.WriteAllText(Path.Combine(ghDir, manifest.Sponsorable + ".jwt"), jwt, Encoding.UTF8);
MarkupLine(Sync.Thanks(manifest.Sponsorable.PadRight(maxlength)));
var roles = new JwtSecurityTokenHandler()
{
MapInboundClaims = false
}.ReadJwtToken(jwt).Claims.Where(c => c.Type == "roles").Select(c => c.Value).ToHashSet();

MarkupLine(Sync.Thanks(manifest.Sponsorable.PadRight(maxlength), string.Join(", ", roles)));
}
else
{
Expand Down Expand Up @@ -229,7 +235,12 @@ await Status().StartAsync(Sync.Synchronizing(manifest.Sponsorable), async ctx =>
else if (status == SponsorManifest.Status.Success)
{
File.WriteAllText(Path.Combine(ghDir, manifest.Sponsorable + ".jwt"), jwt);
MarkupLine(Sync.Thanks(manifest.Sponsorable.PadRight(maxlength)));
var roles = new JwtSecurityTokenHandler()
{
MapInboundClaims = false
}.ReadJwtToken(jwt).Claims.Where(c => c.Type == "roles").Select(c => c.Value).ToHashSet();
MarkupLine(Sync.Thanks(manifest.Sponsorable.PadRight(maxlength), string.Join(", ", roles)));
}
else
{
Expand Down
16 changes: 12 additions & 4 deletions src/Commands/ViewCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ await Status().StartAsync(Strings.Validate.Validating, async ctx =>
}
var sponsorable = new JwtSecurityTokenHandler().ReadJwtToken(await response.Content.ReadAsStringAsync());
var pub = sponsorable.Claims.FirstOrDefault(x => x.Type == "pub")?.Value;
var pub = sponsorable.Claims.FirstOrDefault(x => x.Type == "sub_jwk")?.Value;
if (pub is null)
{
Expand All @@ -66,16 +66,24 @@ await Status().StartAsync(Strings.Validate.Validating, async ctx =>
}
var aud = sponsorable.Claims.Where(x => x.Type == "aud").Select(x => x.Value.TrimEnd('/')).ToArray();
SecurityKey key;
var key = RSA.Create();
key.ImportRSAPublicKey(Convert.FromBase64String(pub), out _);
try
{
key = JsonWebKey.Create(pub);
}
catch (ArgumentException)
{
MarkupLine(Strings.Validate.InvalidPublicKey(account));
continue;
}
var validation = new TokenValidationParameters
{
RequireExpirationTime = true,
AudienceValidator = (audiences, token, parameters) => audiences.All(audience => aud.Any(uri => uri == audience.TrimEnd('/'))),
ValidIssuer = sponsorable.Issuer,
IssuerSigningKey = new RsaSecurityKey(key),
IssuerSigningKey = key,
RoleClaimType = "roles",
NameClaimType = "sub",
};
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/WelcomeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Devlooped.Sponsors;

[Description("Executes the first-run experience")]
public class WelcomeCommand(ICommandApp app, Config config) : Command<WelcomeCommand.WelcomeSettings>
public class WelcomeCommand(Config config) : Command<WelcomeCommand.WelcomeSettings>
{
public class WelcomeSettings : ToSSettings
{
Expand Down
1 change: 0 additions & 1 deletion src/Tests/Signing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ public void JwtSponsorableManifest()
new("iss", "https://sponsorlink.devlooped.com/"),
new("aud", "https://github.com/devlooped"),
new("client_id", "a82350fb2bae407b3021"),
new("pub", File.ReadAllText(@"../../../signing.txt", Encoding.UTF8)),
new("sub_jwk", JsonSerializer.Serialize(pubJwk, JsonOptions.JsonWebKey), JsonClaimValueTypes.Json),
};

Expand Down
2 changes: 1 addition & 1 deletion src/Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.1" />
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="chromium" Version="2024.4.16" />
<PackageReference Include="chromium.linux-x64" Version="2024.4.16" />
<PackageReference Include="CliWrap" Version="3.6.6" />
Expand Down
2 changes: 1 addition & 1 deletion src/Web/Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.0" />
Expand Down

0 comments on commit cbf6f9d

Please sign in to comment.