-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
7 changed files
with
301 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using Auth0.ManagementApi.Models; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Auth0.ManagementApi.Models.Keys; | ||
|
||
namespace Auth0.ManagementApi.Clients | ||
{ | ||
/// <summary> | ||
/// Contains methods to access the /keys endpoints. | ||
/// </summary> | ||
public class KeysClient : BaseClient | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="KeysClient"/> class. | ||
/// </summary> | ||
/// <param name="connection"><see cref="IManagementConnection"/> used to make all API calls.</param> | ||
/// <param name="baseUri"><see cref="Uri"/> of the endpoint to use in making API calls.</param> | ||
/// <param name="defaultHeaders">Dictionary containing default headers included with every request this client makes.</param> | ||
public KeysClient(IManagementConnection connection, Uri baseUri, IDictionary<string, string> defaultHeaders) | ||
: base(connection, baseUri, defaultHeaders) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Get all Application Signing Keys | ||
/// </summary> | ||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param> | ||
/// <returns>All available signing keys <see cref="Key" />.</returns> | ||
public Task<IList<Key>> GetAllAsync(CancellationToken cancellationToken = default) | ||
{ | ||
return Connection.GetAsync<IList<Key>>(BuildUri("keys/signing"), DefaultHeaders, cancellationToken: cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Get an Application Signing Key by its key ID. | ||
/// </summary> | ||
/// <param name="kid">The ID of the key to retrieve.</param> | ||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param> | ||
/// <returns>The <see cref="Key"/> that was requested.</returns> | ||
public Task<Key> GetAsync(string kid, CancellationToken cancellationToken = default) | ||
{ | ||
return Connection.GetAsync<Key>(BuildUri($"keys/signing/{EncodePath(kid)}"), DefaultHeaders, cancellationToken: cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Rotate the Application Signing Key. | ||
/// </summary> | ||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param> | ||
/// <returns>The next rotated key's cert and kid.</returns> | ||
public Task<RotateSigningKeyResponse> RotateSigningKeyAsync( CancellationToken cancellationToken = default) | ||
{ | ||
return Connection.SendAsync<RotateSigningKeyResponse>(HttpMethod.Post, BuildUri("keys/signing/rotate"), null, DefaultHeaders, cancellationToken: cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Revoke an Application Signing Key by its key ID. | ||
/// </summary> | ||
/// <param name="kid">The ID of the key to revoke.</param> | ||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param> | ||
/// <returns>The revoked key's cert and kid.</returns> | ||
public Task<RevokeSigningKeyResponse> RevokeSigningKeyAsync(string kid, CancellationToken cancellationToken = default) | ||
{ | ||
return Connection.SendAsync<RevokeSigningKeyResponse>(HttpMethod.Put, BuildUri($"keys/signing/{EncodePath(kid)}/revoke"), null, DefaultHeaders, cancellationToken: cancellationToken); | ||
} | ||
} | ||
} |
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
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,84 @@ | ||
using System; | ||
using Newtonsoft.Json; | ||
|
||
namespace Auth0.ManagementApi.Models.Keys | ||
{ | ||
|
||
/// <summary> | ||
/// An Application Signing Key | ||
/// </summary> | ||
public class Key | ||
{ | ||
/// <summary> | ||
/// The key id of the signing key | ||
/// </summary> | ||
[JsonProperty("kid")] | ||
public string Kid { get; set; } | ||
|
||
/// <summary> | ||
/// The public certificate of the signing key | ||
/// </summary> | ||
[JsonProperty("cert")] | ||
public string Cert { get; set; } | ||
|
||
/// <summary> | ||
/// The public certificate of the signing key in pkcs7 format | ||
/// </summary> | ||
[JsonProperty("pkcs7")] | ||
public string Pkcs7 { get; set; } | ||
|
||
/// <summary> | ||
/// True if the key is the the current key | ||
/// </summary> | ||
[JsonProperty("current")] | ||
public bool? Current { get; set; } | ||
|
||
/// <summary> | ||
/// True if the key is the the next key | ||
/// </summary> | ||
[JsonProperty("next")] | ||
public bool? Next { get; set; } | ||
|
||
/// <summary> | ||
/// True if the key is the the previous key | ||
/// </summary> | ||
[JsonProperty("previous")] | ||
public bool? Previous { get; set; } | ||
|
||
/// <summary> | ||
/// The date and time when the key became the current key | ||
/// </summary> | ||
[JsonProperty("current_since")] | ||
public DateTime? CurrentSince { get; set; } | ||
|
||
/// <summary> | ||
/// The date and time when the current key was rotated | ||
/// </summary> | ||
[JsonProperty("current_until")] | ||
public DateTime? CurrentUntil { get; set; } | ||
|
||
/// <summary> | ||
/// The cert fingerprint | ||
/// </summary> | ||
[JsonProperty("fingerprint")] | ||
public string Fingerprint { get; set; } | ||
|
||
/// <summary> | ||
/// The cert thumbprint | ||
/// </summary> | ||
[JsonProperty("thumbprint")] | ||
public string Thumbprint { get; set; } | ||
|
||
/// <summary> | ||
/// True if the key is revoked | ||
/// </summary> | ||
[JsonProperty("revoked")] | ||
public bool? Revoked { get; set; } | ||
|
||
/// <summary> | ||
/// The date and time when the key was revoked | ||
/// </summary> | ||
[JsonProperty("revoked_at")] | ||
public DateTime? RevokedAt { get; set; } | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Auth0.ManagementApi/Models/Keys/RevokeSigningKeyResponse.cs
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 @@ | ||
using Newtonsoft.Json; | ||
|
||
namespace Auth0.ManagementApi.Models.Keys | ||
{ | ||
public class RevokeSigningKeyResponse | ||
{ | ||
/// <summary> | ||
/// The id of the revoked signing key | ||
/// </summary> | ||
[JsonProperty("kid")] | ||
public string Kid { get; set; } | ||
|
||
/// <summary> | ||
/// The public certificate of the revoked signing key | ||
/// </summary> | ||
[JsonProperty("cert")] | ||
public string Cert { get; set; } | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Auth0.ManagementApi/Models/Keys/RotateSigningKeyResponse.cs
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 @@ | ||
using Newtonsoft.Json; | ||
|
||
namespace Auth0.ManagementApi.Models.Keys | ||
{ | ||
public class RotateSigningKeyResponse | ||
{ | ||
/// <summary> | ||
/// The id of the next signing key | ||
/// </summary> | ||
[JsonProperty("kid")] | ||
public string Kid { get; set; } | ||
|
||
/// <summary> | ||
/// The public certificate of the next signing key | ||
/// </summary> | ||
[JsonProperty("cert")] | ||
public string Cert { get; set; } | ||
} | ||
} |
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
104 changes: 104 additions & 0 deletions
104
tests/Auth0.ManagementApi.IntegrationTests/KeysTests.cs
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,104 @@ | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Auth0.ManagementApi.Models; | ||
using FluentAssertions; | ||
using Xunit; | ||
using Auth0.Tests.Shared; | ||
|
||
namespace Auth0.ManagementApi.IntegrationTests | ||
{ | ||
public class KeysTests : TestBase, IAsyncLifetime | ||
{ | ||
private ManagementApiClient _apiClient; | ||
private Connection _connection; | ||
private const string Password = "4cX8awB3T%@Aw-R:=h@ae@k?"; | ||
|
||
public async Task InitializeAsync() | ||
{ | ||
await GetTokenAndInitializeAsync(); | ||
|
||
// We will need a connection to add the roles to... | ||
_connection = await _apiClient.Connections.CreateAsync(new ConnectionCreateRequest | ||
{ | ||
Name = "Temp-Int-Test-" + MakeRandomName(), | ||
Strategy = "auth0", | ||
EnabledClients = new[] {GetVariable("AUTH0_CLIENT_ID"), GetVariable("AUTH0_MANAGEMENT_API_CLIENT_ID")} | ||
}); | ||
} | ||
|
||
private async Task GetTokenAndInitializeAsync() | ||
{ | ||
string token = await GenerateManagementApiToken(); | ||
|
||
_apiClient = new ManagementApiClient(token, GetVariable("AUTH0_MANAGEMENT_API_URL"), new HttpClientManagementConnection(options: new HttpClientManagementConnectionOptions { NumberOfHttpRetries = 9 })); | ||
} | ||
|
||
public async Task DisposeAsync() | ||
{ | ||
await _apiClient.Connections.DeleteAsync(_connection.Id); | ||
_apiClient.Dispose(); | ||
} | ||
|
||
[Fact] | ||
public async Task Test_keys_can_be_retrieved() | ||
{ | ||
var signingKeys = await _apiClient.Keys.GetAllAsync(); | ||
|
||
signingKeys.Any().Should().BeTrue(); | ||
} | ||
|
||
[Fact] | ||
public async Task Test_keys_can_be_retrieved_by_kid() | ||
{ | ||
var signingKeys = await _apiClient.Keys.GetAllAsync(); | ||
|
||
// select the current key id | ||
var currentKeyId = signingKeys.First(key => key.Current.HasValue && key.Current.Value).Kid; | ||
|
||
// retrieve the key by id | ||
var currentKey = await _apiClient.Keys.GetAsync(currentKeyId); | ||
|
||
currentKey.Kid.Should().Be(currentKeyId); | ||
} | ||
|
||
[Fact(Skip = "Run Manual")] | ||
public async Task Test_keys_rotate_signing_key() | ||
{ | ||
// Rotate the signing key | ||
var rotateKeyResponse = await _apiClient.Keys.RotateSigningKeyAsync(); | ||
|
||
await GetTokenAndInitializeAsync(); | ||
|
||
// Get all signing key | ||
var signingKeys = await _apiClient.Keys.GetAllAsync(); | ||
|
||
// Select the next key | ||
var nextKey = signingKeys.First(key => key.Next.HasValue && key.Next.Value); | ||
|
||
// Assert | ||
nextKey.Kid.Should().Be(rotateKeyResponse.Kid); | ||
} | ||
|
||
|
||
[Fact(Skip = "Run Manual")] | ||
public async Task Test_keys_can_be_revoked_by_kid() | ||
{ | ||
// Rotate the signing key before we revoke | ||
var rotateKeyResponse = await _apiClient.Keys.RotateSigningKeyAsync(); | ||
|
||
await GetTokenAndInitializeAsync(); | ||
|
||
// Get all signing keys | ||
var signingKeys = await _apiClient.Keys.GetAllAsync(); | ||
|
||
// Select the previous key id | ||
var previousKeyId = signingKeys.First(key => key.Previous.HasValue && key.Previous.Value).Kid; | ||
|
||
// Revoke the key by id | ||
var revoked = await _apiClient.Keys.RevokeSigningKeyAsync(previousKeyId); | ||
|
||
// Assert | ||
revoked.Kid.Should().Be(previousKeyId); | ||
} | ||
} | ||
} |