Repository navigation
MT-23076: expose api token expiration in create and reset requests #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f2a32c3
MT-23076: add ApiTokenExpiration type with tri-state expires_at seria…
oshchyhol d13e416
MT-23076: add optional expires_at to create api token request
oshchyhol b56033a
MT-23076: add reset api token overload with optional expiration
oshchyhol 251e8de
MT-23076: cover token expiration request serialization with tests
oshchyhol 02902d7
MT-23076: demonstrate token expiration in api tokens example
oshchyhol f602d49
MT-23076: add masked_token to account access specifier
oshchyhol e90beaf
MT-23076: write json null instead of throwing for a null expiration
oshchyhol e96c146
MT-23076: assert the expiration returned in create and reset responses
oshchyhol 1d5b427
MT-23076: cover the masked token specifier field with a test
oshchyhol 386d051
MT-23076: assert the rejected expiration request and error details
oshchyhol 3919803
MT-23076: use the real 422 body for the rejected expiration tests
oshchyhol 75d1c55
MT-23076: follow the token chain when resetting in the ApiTokens example
oshchyhol File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or 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 hidden or 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
src/Mailtrap.Abstractions/ApiTokens/Converters/ApiTokenExpirationJsonConverter.cs
This file contains hidden or 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 @@ | ||
| namespace Mailtrap.ApiTokens.Converters; | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Custom JSON converter to be used for <see cref="ApiTokenExpiration"/>.<br/> | ||
| /// Writes JSON <see langword="null"/> for <see cref="ApiTokenExpiration.Never"/> | ||
| /// and the ISO 8601 date-time string otherwise. | ||
| /// </summary> | ||
| internal sealed class ApiTokenExpirationJsonConverter : JsonConverter<ApiTokenExpiration> | ||
| { | ||
| public override bool HandleNull => true; | ||
|
|
||
|
|
||
| public override ApiTokenExpiration? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
| { | ||
| return reader.TokenType switch | ||
| { | ||
| JsonTokenType.Null => ApiTokenExpiration.Never, | ||
| JsonTokenType.String => reader.TryGetDateTimeOffset(out var date) | ||
| ? ApiTokenExpiration.At(date) | ||
| : throw new JsonException($"Cannot convert value '{reader.GetString()}' to {nameof(ApiTokenExpiration)}."), | ||
| _ => throw new JsonException($"Unexpected JSON token {reader.TokenType} for {nameof(ApiTokenExpiration)}.") | ||
| }; | ||
| } | ||
|
|
||
| public override void Write(Utf8JsonWriter writer, ApiTokenExpiration value, JsonSerializerOptions options) | ||
| { | ||
| Ensure.NotNull(writer, nameof(writer)); | ||
|
|
||
| // HandleNull is required to map JSON null to Never on read, and it also routes | ||
| // null references here on write, so this has to handle them rather than throw. | ||
| if (value is null || !value.Value.HasValue) | ||
| { | ||
| writer.WriteNullValue(); | ||
| } | ||
| else | ||
| { | ||
| writer.WriteStringValue(value.Value.Value); | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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
53 changes: 53 additions & 0 deletions
53
src/Mailtrap.Abstractions/ApiTokens/Models/ApiTokenExpiration.cs
This file contains hidden or 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,53 @@ | ||
| namespace Mailtrap.ApiTokens.Models; | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Represents an explicit API token expiration, serialized as an ISO 8601 date-time.<br/> | ||
| /// Leave the request property unset to omit the value and get the server default | ||
| /// (a 1-year default is being rolled out).<br/> | ||
| /// Use <see cref="Never"/> for a token that never expires.<br/> | ||
| /// Past or more-than-5-years-ahead values are rejected with 422. | ||
| /// </summary> | ||
| [JsonConverter(typeof(ApiTokenExpirationJsonConverter))] | ||
| public sealed record ApiTokenExpiration | ||
| { | ||
| /// <summary> | ||
| /// Gets the expiration for a token that never expires. | ||
| /// </summary> | ||
| /// | ||
| /// <value> | ||
| /// Expiration for a token that never expires. Serialized as JSON <see langword="null"/>. | ||
| /// </value> | ||
| public static ApiTokenExpiration Never { get; } = new((DateTimeOffset?)null); | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Creates an expiration at the provided date and time. | ||
| /// </summary> | ||
| /// | ||
| /// <param name="value"> | ||
| /// Date and time when the token expires. | ||
| /// </param> | ||
| /// | ||
| /// <returns> | ||
| /// Expiration at the provided date and time. Serialized as an ISO 8601 date-time string. | ||
| /// </returns> | ||
| public static ApiTokenExpiration At(DateTimeOffset value) => new(value); | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Gets the expiration date and time, | ||
| /// or <see langword="null"/> for a token that never expires. | ||
| /// </summary> | ||
| /// | ||
| /// <value> | ||
| /// Expiration date and time, or <see langword="null"/> for a token that never expires. | ||
| /// </value> | ||
| internal DateTimeOffset? Value { get; } | ||
|
|
||
|
|
||
| private ApiTokenExpiration(DateTimeOffset? value) | ||
| { | ||
| Value = value; | ||
| } | ||
| } |
This file contains hidden or 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
22 changes: 22 additions & 0 deletions
22
src/Mailtrap.Abstractions/ApiTokens/Requests/ResetApiTokenRequest.cs
This file contains hidden or 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,22 @@ | ||
| namespace Mailtrap.ApiTokens.Requests; | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Request to reset an API token. | ||
| /// </summary> | ||
| public sealed record ResetApiTokenRequest | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the optional expiration for the new token. | ||
| /// </summary> | ||
| /// | ||
| /// <value> | ||
| /// Optional token expiration as an ISO 8601 date-time.<br/> | ||
| /// Omit for the server default (a 1-year default is being rolled out).<br/> | ||
| /// Use <see cref="ApiTokenExpiration.Never"/> for a token that never expires.<br/> | ||
| /// Past or more-than-5-years-ahead values are rejected with 422. | ||
| /// </value> | ||
| [JsonPropertyName("expires_at")] | ||
| [JsonPropertyOrder(1)] | ||
| public ApiTokenExpiration? ExpiresAt { get; set; } | ||
| } |
This file contains hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.