-
Notifications
You must be signed in to change notification settings - Fork 123
OpenAPIGenerator upgrade to v7.16.0 - [2] Added new mustache templates #1208
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
Open
Kwok-he-Chu
wants to merge
4
commits into
v7-generator/development-branch
Choose a base branch
from
v7-generator/2-add-mustache-templates
base: v7-generator/development-branch
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+4,461
−1,001
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
d9dcffc
Added /Core classes and tests in preparations for the v7-generator-up…
Kwok-he-Chu 74b88ec
Include updated core classes for review
Kwok-he-Chu d49b160
Add new mustache templates for v7
Kwok-he-Chu 33998d6
Remove HttpSigningConfiguration and HttpSigningToken mustache templates
Kwok-he-Chu 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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| using System.Reflection; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| // General Information about an assembly is controlled through the following | ||
| // set of attributes. Change these attribute values to modify the information | ||
| // associated with an assembly. | ||
| [assembly: AssemblyTitle("{{packageTitle}}")] | ||
| [assembly: AssemblyDescription("{{packageDescription}}")] | ||
| [assembly: AssemblyConfiguration("")] | ||
| [assembly: AssemblyCompany("{{packageCompany}}")] | ||
| [assembly: AssemblyProduct("{{packageProductName}}")] | ||
| [assembly: AssemblyCopyright("{{packageCopyright}}")] | ||
| [assembly: AssemblyTrademark("")] | ||
| [assembly: AssemblyCulture("")] | ||
|
|
||
| // Setting ComVisible to false makes the types in this assembly not visible | ||
| // to COM components. If you need to access a type in this assembly from | ||
| // COM, set the ComVisible attribute to true on that type. | ||
| [assembly: ComVisible(false)] | ||
|
|
||
| // Version information for an assembly consists of the following four values: | ||
| // | ||
| // Major Version | ||
| // Minor Version | ||
| // Build Number | ||
| // Revision | ||
| // | ||
| // You can specify all the values or you can default the Build and Revision Numbers | ||
| // by using the '*' as shown below: | ||
| // [assembly: AssemblyVersion("1.0.*")] | ||
| [assembly: AssemblyVersion("{{packageVersion}}")] | ||
| [assembly: AssemblyFileVersion("{{packageVersion}}")] | ||
| {{^supportsAsync}} | ||
| // Settings which don't support asynchronous operations rely on non-public constructors | ||
| // This is due to how RestSharp requires the type constraint `where T : new()` in places it probably shouldn't. | ||
| [assembly: InternalsVisibleTo("RestSharp")] | ||
| [assembly: InternalsVisibleTo("NewtonSoft.Json")] | ||
| [assembly: InternalsVisibleTo("JsonSubTypes")] | ||
| {{/supportsAsync}} |
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 @@ | ||
| {{#isNullable}}{{nrt?}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}}{{/isNullable}} |
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 @@ | ||
| {{#lambda.first}}{{#isNullable}}{{nrt?}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}} {{/isNullable}}{{^required}}{{nrt?}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}} {{/required}}{{/lambda.first}} |
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,21 @@ | ||
| {{>partial_header}} | ||
| using Newtonsoft.Json.Converters; | ||
|
|
||
| namespace {{packageName}}.Client | ||
| { | ||
| /// <summary> | ||
| /// Formatter for 'date' openapi formats ss defined by full-date - RFC3339 | ||
| /// see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#data-types | ||
| /// </summary> | ||
| public class OpenAPIDateConverter : IsoDateTimeConverter | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="OpenAPIDateConverter" /> class. | ||
| /// </summary> | ||
| public OpenAPIDateConverter() | ||
| { | ||
| // full-date = date-fullyear "-" date-month "-" date-mday | ||
| DateTimeFormat = "yyyy-MM-dd"; | ||
| } | ||
| } | ||
| } |
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,6 @@ | ||
| // {{{name}}} ({{{dataType}}}) pattern. | ||
| Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}); | ||
| if (!regex{{{name}}}.Match(this.{{{name}}}{{#isUuid}}.ToString(){{/isUuid}}).Success) | ||
| { | ||
| yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" }); | ||
| } |
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,136 @@ | ||
| {{>partial_header}} | ||
|
|
||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Newtonsoft.Json; | ||
| using RestSharp; | ||
| using RestSharp.Authenticators; | ||
|
|
||
| namespace {{packageName}}.{{clientPackage}}.Auth | ||
| { | ||
| /// <summary> | ||
| /// An authenticator for OAuth2 authentication flows | ||
| /// </summary> | ||
| public class OAuthAuthenticator : IAuthenticator | ||
| { | ||
| private TokenResponse{{nrt?}} _token; | ||
|
|
||
| /// <summary> | ||
| /// Returns the current authentication token. Can return null if there is no authentication token, or it has expired. | ||
| /// </summary> | ||
| public string{{nrt?}} Token | ||
| { | ||
| get | ||
| { | ||
| if (_token == null) return null; | ||
| if (_token.ExpiresIn == null) return _token.AccessToken; | ||
| if (_token.ExpiresAt < DateTime.Now) return null; | ||
|
|
||
| return _token.AccessToken; | ||
| } | ||
| } | ||
|
|
||
| readonly string _tokenUrl; | ||
| readonly string _clientId; | ||
| readonly string _clientSecret; | ||
| readonly string{{nrt?}} _scope; | ||
| readonly string _grantType; | ||
| readonly JsonSerializerSettings _serializerSettings; | ||
| readonly IReadableConfiguration _configuration; | ||
|
|
||
| /// <summary> | ||
| /// Initialize the OAuth2 Authenticator | ||
| /// </summary> | ||
| public OAuthAuthenticator( | ||
| string tokenUrl, | ||
| string clientId, | ||
| string clientSecret, | ||
| string{{nrt?}} scope, | ||
| OAuthFlow? flow, | ||
| JsonSerializerSettings serializerSettings, | ||
| IReadableConfiguration configuration) | ||
| { | ||
| _tokenUrl = tokenUrl; | ||
| _clientId = clientId; | ||
| _clientSecret = clientSecret; | ||
| _scope = scope; | ||
| _serializerSettings = serializerSettings; | ||
| _configuration = configuration; | ||
|
|
||
| switch (flow) | ||
| { | ||
| /*case OAuthFlow.ACCESS_CODE: | ||
| _grantType = "authorization_code"; | ||
| break; | ||
| case OAuthFlow.IMPLICIT: | ||
| _grantType = "implicit"; | ||
| break; | ||
| case OAuthFlow.PASSWORD: | ||
| _grantType = "password"; | ||
| break;*/ | ||
| case OAuthFlow.APPLICATION: | ||
| _grantType = "client_credentials"; | ||
| break; | ||
| default: | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Creates an authentication parameter from an access token. | ||
| /// </summary> | ||
| /// <returns>An authentication parameter.</returns> | ||
| protected async ValueTask<Parameter> GetAuthenticationParameter() | ||
| { | ||
| var token = string.IsNullOrEmpty(Token) ? await GetToken().ConfigureAwait(false) : Token; | ||
| return new HeaderParameter(KnownHeaders.Authorization, token); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the token from the OAuth2 server. | ||
| /// </summary> | ||
| /// <returns>An authentication token.</returns> | ||
| async Task<string> GetToken() | ||
| { | ||
| var client = new RestClient(_tokenUrl, configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(_serializerSettings, _configuration))); | ||
|
|
||
| var request = new RestRequest(); | ||
| if (!string.IsNullOrWhiteSpace(_token?.RefreshToken)) | ||
| { | ||
| request.AddParameter("grant_type", "refresh_token") | ||
| .AddParameter("refresh_token", _token.RefreshToken); | ||
| } | ||
| else | ||
| { | ||
| request | ||
| .AddParameter("grant_type", _grantType) | ||
| .AddParameter("client_id", _clientId) | ||
| .AddParameter("client_secret", _clientSecret); | ||
| } | ||
| if (!string.IsNullOrEmpty(_scope)) | ||
| { | ||
| request.AddParameter("scope", _scope); | ||
| } | ||
| _token = await client.PostAsync<TokenResponse>(request).ConfigureAwait(false); | ||
| // RFC6749 - token_type is case insensitive. | ||
| // RFC6750 - In Authorization header Bearer should be capitalized. | ||
| // Fix the capitalization irrespective of token_type casing. | ||
| switch (_token?.TokenType?.ToLower()) | ||
| { | ||
| case "bearer": | ||
| return $"Bearer {_token.AccessToken}"; | ||
| default: | ||
| return $"{_token?.TokenType} {_token?.AccessToken}"; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Retrieves the authentication token (creating a new one if necessary) and adds it to the current request | ||
| /// </summary> | ||
| /// <param name="client"></param> | ||
| /// <param name="request"></param> | ||
| /// <returns></returns> | ||
| public async ValueTask Authenticate(IRestClient client, RestRequest request) | ||
| => request.AddOrUpdateParameter(await GetAuthenticationParameter().ConfigureAwait(false)); | ||
| } | ||
| } | ||
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,19 @@ | ||
| {{>partial_header}} | ||
|
|
||
| namespace {{packageName}}.{{clientPackage}}.Auth | ||
| { | ||
| /// <summary> | ||
| /// Available flows for OAuth2 authentication | ||
| /// </summary> | ||
| public enum OAuthFlow | ||
| { | ||
| /// <summary>Authorization code flow</summary> | ||
| ACCESS_CODE, | ||
| /// <summary>Implicit flow</summary> | ||
| IMPLICIT, | ||
| /// <summary>Password flow</summary> | ||
| PASSWORD, | ||
| /// <summary>Client credentials flow</summary> | ||
| APPLICATION | ||
| } | ||
| } |
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,24 @@ | ||
| {{>partial_header}} | ||
|
|
||
| using System; | ||
| using Newtonsoft.Json; | ||
|
|
||
| namespace {{packageName}}.{{clientPackage}}.Auth | ||
| { | ||
| class TokenResponse | ||
| { | ||
| [JsonProperty("token_type")] | ||
| public string TokenType { get; set; } | ||
| [JsonProperty("access_token")] | ||
| public string AccessToken { get; set; } | ||
| [JsonProperty("expires_in")] | ||
| public int? ExpiresIn { get; set; } | ||
| [JsonProperty("created")] | ||
| public DateTime? Created { get; set; } | ||
|
|
||
| [JsonProperty("refresh_token")] | ||
| public string{{nrt?}} RefreshToken { get; set; } | ||
|
|
||
| public DateTime? ExpiresAt => ExpiresIn == null ? null : Created?.AddSeconds(ExpiresIn.Value); | ||
| } | ||
| } |
47 changes: 47 additions & 0 deletions
47
templates-v7/csharp/libraries/generichost/ApiException.mustache
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,47 @@ | ||
| // <auto-generated> | ||
| {{>partial_header}} | ||
|
|
||
| {{#nrt}} | ||
| #nullable enable | ||
|
|
||
| {{/nrt}} | ||
| using System; | ||
|
|
||
| namespace {{packageName}}.{{corePackageName}}.{{clientPackage}} | ||
| { | ||
| /// <summary> | ||
| /// API Exception | ||
| /// </summary> | ||
| {{>visibility}} class ApiException : Exception | ||
| { | ||
| /// <summary> | ||
| /// The reason the api request failed | ||
| /// </summary> | ||
| public string{{nrt?}} ReasonPhrase { get; } | ||
|
|
||
| /// <summary> | ||
| /// The HttpStatusCode | ||
| /// </summary> | ||
| public System.Net.HttpStatusCode StatusCode { get; } | ||
|
|
||
| /// <summary> | ||
| /// The raw data returned by the api | ||
| /// </summary> | ||
| public string RawContent { get; } | ||
|
|
||
| /// <summary> | ||
| /// Construct the ApiException from parts of the response | ||
| /// </summary> | ||
| /// <param name="reasonPhrase"></param> | ||
| /// <param name="statusCode"></param> | ||
| /// <param name="rawContent"></param> | ||
| public ApiException(string{{nrt?}} reasonPhrase, System.Net.HttpStatusCode statusCode, string rawContent) : base(reasonPhrase ?? rawContent) | ||
| { | ||
| ReasonPhrase = reasonPhrase; | ||
|
|
||
| StatusCode = statusCode; | ||
|
|
||
| RawContent = rawContent; | ||
| } | ||
| } | ||
| } |
48 changes: 48 additions & 0 deletions
48
templates-v7/csharp/libraries/generichost/ApiFactory.mustache
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,48 @@ | ||
| using System; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
|
|
||
| namespace {{packageName}}.{{corePackageName}}.{{clientPackage}} | ||
| { | ||
| /// <summary> | ||
| /// The factory interface for creating the services that can communicate with the {{packageName}} APIs. | ||
| /// </summary> | ||
| {{>visibility}} interface {{interfacePrefix}}ApiFactory | ||
| { | ||
| /// <summary> | ||
| /// A method to create an IApi of type IResult | ||
| /// </summary> | ||
| /// <typeparam name="IResult"></typeparam> | ||
| /// <returns></returns> | ||
| IResult Create<IResult>() where IResult : {{interfacePrefix}}{{packageName}}ApiService; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The implementation of <see cref="{{interfacePrefix}}ApiFactory"/>. | ||
| /// </summary> | ||
| {{>visibility}} class ApiFactory : {{interfacePrefix}}ApiFactory | ||
| { | ||
| /// <summary> | ||
| /// The service provider | ||
| /// </summary> | ||
| public IServiceProvider Services { get; } | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ApiFactory"/> class. | ||
| /// </summary> | ||
| /// <param name="services"></param> | ||
| public ApiFactory(IServiceProvider services) | ||
| { | ||
| Services = services; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// A method to create an IApi of type IResult | ||
| /// </summary> | ||
| /// <typeparam name="IResult"></typeparam> | ||
| /// <returns></returns> | ||
| public IResult Create<IResult>() where IResult : {{interfacePrefix}}{{packageName}}ApiService | ||
| { | ||
| return Services.GetRequiredService<IResult>(); | ||
| } | ||
| } | ||
| } |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
defaultcase in this switch statement does nothing, which means if an unsupportedOAuthFlowis provided, the_grantTypefield will remain uninitialized. This will likely cause anullvalue to be sent in the token request later. It's better to throw an exception for unsupported flows to fail early and clearly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mustache template is unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gcatanese Q: Do we leave this in? I've only included it for completeness as part of the v7 generator upgrade
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO I'd keep only if it already existed in the project and you are just moving things. If this is coming in from the upgrade, then I'd remove.