Skip to content

Commit

Permalink
Merge pull request #45 from folkehelseinstituttet/feature/get-access-…
Browse files Browse the repository at this point in the history
…token

Tool  to genereate a token based on json file
  • Loading branch information
OsirisTerje authored Apr 26, 2024
2 parents 9abdfb1 + 9ac67f6 commit d344d49
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 8 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/Fhi.ClientCredentials.Refit.Nuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ jobs:
publish:
name: Build, pack & publish
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: ['6.0.x']

steps:
- uses: actions/checkout@v4
Expand All @@ -26,7 +23,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ matrix.dotnet-version }}
dotnet-version: 6.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/Fhi.ClientCredentials.Tools.GetAccessToken.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Fhi.ClientCredentials.Tools.GetAccessToken

on:
push:
branches:
- main
paths:
- 'Fhi.ClientCredentials.Tools.GetAccessToken/**'
defaults:
run:
shell: pwsh
working-directory: ./Fhi.ClientCredentials.Tools.GetAccessToken

jobs:
publish:
name: Build, pack & publish
runs-on: ubuntu-latest


steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore --verbosity normal
- name: Pack
run: dotnet pack --configuration Release --no-build --output package
- name: Publish nupkg and snupkg to NuGet.org
run: |
foreach($file in (Get-ChildItem package -Recurse -Include *.nupkg)) {
dotnet nuget push $file --api-key "${{ secrets.NUGET_ORG_PUSH_API_KEY_HELSEID }}" --source https://api.nuget.org/v3/index.json --skip-duplicate
}
foreach($file in (Get-ChildItem "package" -Recurse -Include *.snupkg)) {
dotnet nuget push $file --api-key "${{ secrets.NUGET_ORG_PUSH_API_KEY_HELSEID }}" --source https://api.nuget.org/v3/index.json --skip-duplicate
}
10 changes: 6 additions & 4 deletions Fhi.CLientCredentials.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fhi.ClientCredentials.Refit", "Fhi.ClientCredentials.Refit\Fhi.ClientCredentials.Refit.csproj", "{333B77A3-BA29-4177-AD4B-ECA8B1868C64}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{6926AC12-4A44-4C85-BE51-22103879BEB7}"
ProjectSection(SolutionItems) = preProject
.github\workflows\CI.yml = .github\workflows\CI.yml
.github\workflows\Fhi.ClientCredentials.Refit.Nuget.yml = .github\workflows\Fhi.ClientCredentials.Refit.Nuget.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fhi.ClientCredentials.Tools.GetAccessToken", "Fhi.ClientCredentials.Tools.GetAccessToken\Fhi.ClientCredentials.Tools.GetAccessToken.csproj", "{B5ECA6A3-EAE7-4DD3-A226-EDDC4E670A37}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -57,6 +55,10 @@ Global
{333B77A3-BA29-4177-AD4B-ECA8B1868C64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{333B77A3-BA29-4177-AD4B-ECA8B1868C64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{333B77A3-BA29-4177-AD4B-ECA8B1868C64}.Release|Any CPU.Build.0 = Release|Any CPU
{B5ECA6A3-EAE7-4DD3-A226-EDDC4E670A37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5ECA6A3-EAE7-4DD3-A226-EDDC4E670A37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5ECA6A3-EAE7-4DD3-A226-EDDC4E670A37}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5ECA6A3-EAE7-4DD3-A226-EDDC4E670A37}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<PackAsTool>true</PackAsTool>
<ToolCommandName>gettoken</ToolCommandName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Fhi.ClientCredentialsKeypairs" Version="1.2.*" />
</ItemGroup>

</Project>
120 changes: 120 additions & 0 deletions Fhi.ClientCredentials.Tools.GetAccessToken/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using Fhi.ClientCredentialsKeypairs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Options;
using System.Text.Json;

try
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";

var validFiles = new List<string>();

var inputFiles = args.Where(x => x.EndsWith(".json", StringComparison.InvariantCultureIgnoreCase)).ToList();
inputFiles.AddRange(inputFiles.Select(x => x.Replace(".json", $".{env}.json", StringComparison.InvariantCultureIgnoreCase)).ToList());

validFiles = inputFiles.Where(x => File.Exists(x)).ToList();
if (inputFiles.Count > 0 && validFiles.Count == 0)
{
throw new Exception("No valid json files found. Tried: " + string.Join(", ", inputFiles));
}

if (args.Length > 0 && Directory.Exists(args[0]))
{
validFiles = GetDefaultFiles(args[0]);
}

if (validFiles.Count == 0)
{
validFiles = GetDefaultFiles(".");
}

if (validFiles.Count == 0)
{
throw new Exception(@"No valid json file found.
Usage: gettoken [appsettings.json] [ConfigSectionName]
Usage: gettoken [directory-to-search] [ConfigSectionName]");
}

var section = args.LastOrDefault(x => !x.EndsWith(".json", StringComparison.InvariantCultureIgnoreCase) && !Directory.Exists(x))
?? nameof(ClientCredentialsConfiguration);

var config = GetConfig(validFiles, section);

var token = await GetToken(config);

if (string.IsNullOrEmpty(token))
{
config.privateJwk = Shorten(config.privateJwk);
config.rsaPrivateKey = Shorten(config.rsaPrivateKey);
var json = JsonSerializer.Serialize(config, new JsonSerializerOptions() { WriteIndented = true });
throw new Exception("Unable to retrieve token for configuration from files " + string.Join(", ", validFiles) + "\n\n" + json);
}

Console.WriteLine(token);
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Environment.Exit(1);
}

ClientCredentialsConfiguration GetConfig(List<string> files, string section)
{
var builder = new ConfigurationBuilder();
foreach (var file in files)
{
if (File.Exists(file))
{
builder.AddJsonFile(file);
}
}
var config = builder.Build().GetSection(section).Get<ClientCredentialsConfiguration>();
if (config?.ClientId == null)
{
config = builder.Build().Get<ClientCredentialsConfiguration>();
}

if (config?.ClientId == null)
{
throw new Exception($"Unable to find ClientCredentialsConfiguration in json files: " + string.Join(", ", files));
}

return config;
}

string? Shorten(string? text, int maxLength = 30)
{
if (text == null || text.Length <= maxLength) return text;
return text?.Substring(0, maxLength) + "..";
}

List<string> GetDefaultFiles(string path)
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";

var matcher = new Matcher(StringComparison.InvariantCultureIgnoreCase);
matcher.AddInclude("**/appsettings.json");
matcher.AddInclude($"**/appsettings.{env}.json");
matcher.AddInclude("**/HelseID Configuration *.json");

var found = matcher.GetResultsInFullPath(path).ToList();

if (found.Any(x => x.Contains("HelseID Configuration")))
found = found.Where(x => x.Contains("HelseID Configuration")).Take(1).ToList();

if (found.Any(x => x.Contains("appsettings.json")))
found = found.Where(x => x.Contains("appsettings.json")).Take(1).ToList();

found.AddRange(found.Select(x => x.Replace(".json", $".{env}.json", StringComparison.InvariantCultureIgnoreCase)).ToList());
return found.Where(x => File.Exists(x)).ToList();
}

Task<string> GetToken(ClientCredentialsConfiguration config)
{
var store = new AuthenticationService(config);
var tokenProvider = new AuthenticationStore(store, Options.Create(config));
return tokenProvider.GetToken();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"profiles": {
"Fhi.ClientCredentials.Tools.GetAccessToken": {
"commandName": "Project",
"commandLineArgs": ""
}
}
}
24 changes: 24 additions & 0 deletions Fhi.ClientCredentials.Tools.GetAccessToken/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## gettoken command line tool

This tool create an access token based on a given JSON file containing a client credentials configuration.
If you are not using the standard heading "ClientCredentialsConfiguration"
you can supply the section name as the last argument.

Usage:

```
gettoken [ConfigSectionName]
gettoken [appsettings.json ..] [ConfigSectionName]
gettoken [directory-to-search] [ConfigSectionName]
```

If no files are given it will search in the given directiory for any "appsettings*.json" files and
"HelseID Configuration *.json" files. If no directory is given it will search the working directory.

The tool will automatically try to add additional information from enviornment-specific files,
so if you supply the file "appsettings.json" it will also include "appsettings.Development.json".

You can change the default environment name ("Development") by setting the env var ASPNETCORE_ENVIRONMENT.

0 comments on commit d344d49

Please sign in to comment.