-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from folkehelseinstituttet/feature/get-access-…
…token Tool to genereate a token based on json file
- Loading branch information
Showing
7 changed files
with
219 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
.github/workflows/Fhi.ClientCredentials.Tools.GetAccessToken.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
Fhi.ClientCredentials.Tools.GetAccessToken/Fhi.ClientCredentials.Tools.GetAccessToken.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} |
8 changes: 8 additions & 0 deletions
8
Fhi.ClientCredentials.Tools.GetAccessToken/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"profiles": { | ||
"Fhi.ClientCredentials.Tools.GetAccessToken": { | ||
"commandName": "Project", | ||
"commandLineArgs": "" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|