From 0c32cf9c760f12d5aae00db7b98cdf9adc8a37c2 Mon Sep 17 00:00:00 2001 From: Christopher Cook Date: Fri, 8 Nov 2024 13:31:02 +0800 Subject: [PATCH] API: per instance deployment task edit/execute, refactor --- src/Certify.Client/CertifyApiClient.cs | 6 + src/Certify.Client/ICertifyClient.cs | 2 + .../CertifyManager.ManagementHub.cs | 27 ++++ .../API/Management/ManagementHubMessages.cs | 4 + .../Certify.API.Public.cs | 116 +++++++++++++++-- .../internal/DeploymentTaskController.cs | 20 +-- .../Services/ManagementAPI.cs | 37 ++++++ src/Certify.SourceGenerators/ApiMethods.cs | 73 ++++++----- .../PublicAPISourceGenerator.cs | 118 ++++++++++-------- 9 files changed, 302 insertions(+), 101 deletions(-) diff --git a/src/Certify.Client/CertifyApiClient.cs b/src/Certify.Client/CertifyApiClient.cs index 014e0603d..11ef64af9 100644 --- a/src/Certify.Client/CertifyApiClient.cs +++ b/src/Certify.Client/CertifyApiClient.cs @@ -620,6 +620,12 @@ public async Task> GetCertificateAuthorities(AuthCont return JsonConvert.DeserializeObject>(result); } + public async Task UpdateCertificateAuthority(CertificateAuthority ca, AuthContext authContext = null) + { + var result = await PostAsync("accounts/authorities", ca, authContext); + return JsonConvert.DeserializeObject(await result.Content.ReadAsStringAsync()); + } + public async Task DeleteCertificateAuthority(string id, AuthContext authContext = null) { var result = await DeleteAsync("accounts/authorities/" + id, authContext); diff --git a/src/Certify.Client/ICertifyClient.cs b/src/Certify.Client/ICertifyClient.cs index e73fba9ba..74ee82378 100644 --- a/src/Certify.Client/ICertifyClient.cs +++ b/src/Certify.Client/ICertifyClient.cs @@ -116,6 +116,8 @@ public partial interface ICertifyInternalApiClient #region Accounts Task> GetCertificateAuthorities(AuthContext authContext = null); + + Task UpdateCertificateAuthority(CertificateAuthority ca, AuthContext authContext = null); Task DeleteCertificateAuthority(string id, AuthContext authContext = null); Task> GetAccounts(AuthContext authContext = null); Task AddAccount(ContactRegistration contact, AuthContext authContext = null); diff --git a/src/Certify.Core/Management/CertifyManager/CertifyManager.ManagementHub.cs b/src/Certify.Core/Management/CertifyManager/CertifyManager.ManagementHub.cs index 225350aa3..90e90a619 100644 --- a/src/Certify.Core/Management/CertifyManager/CertifyManager.ManagementHub.cs +++ b/src/Certify.Core/Management/CertifyManager/CertifyManager.ManagementHub.cs @@ -175,6 +175,12 @@ private async Task _managementServerClient_OnGetCommandRe val = await UpdateCertificateAuthority(item); } + else if (arg.CommandType == ManagementHubCommands.RemoveCertificateAuthority) + { + var args = JsonSerializer.Deserialize[]>(arg.Value); + var itemArg = args.FirstOrDefault(a => a.Key == "id"); + val = await RemoveCertificateAuthority(itemArg.Value); + } else if (arg.CommandType == ManagementHubCommands.GetAcmeAccounts) { val = await GetAccountRegistrations(); @@ -187,6 +193,13 @@ private async Task _managementServerClient_OnGetCommandRe val = await AddAccount(registration); } + else if (arg.CommandType == ManagementHubCommands.RemoveAcmeAccount) + { + var args = JsonSerializer.Deserialize[]>(arg.Value); + var itemArg = args.FirstOrDefault(a => a.Key == "storageKey"); + var deactivateArg = args.FirstOrDefault(a => a.Key == "deactivate"); + val = await RemoveAccount(itemArg.Value, bool.Parse(deactivateArg.Value)); + } else if (arg.CommandType == ManagementHubCommands.GetStoredCredentials) { val = await _credentialsManager.GetCredentials(); @@ -209,6 +222,7 @@ private async Task _managementServerClient_OnGetCommandRe { val = await Core.Management.Challenges.ChallengeProviders.GetChallengeAPIProviders(); } + else if (arg.CommandType == ManagementHubCommands.GetDnsZones) { var args = JsonSerializer.Deserialize[]>(arg.Value); @@ -217,6 +231,19 @@ private async Task _managementServerClient_OnGetCommandRe val = await GetDnsProviderZones(providerTypeArg.Value, credentialIdArg.Value); } + else if (arg.CommandType == ManagementHubCommands.GetDeploymentProviders) + { + val = await GetDeploymentProviders(); + } + else if (arg.CommandType == ManagementHubCommands.ExecuteDeploymentTask) + { + var args = JsonSerializer.Deserialize[]>(arg.Value); + + var managedCertificateIdArg = args.FirstOrDefault(a => a.Key == "managedCertificateId"); + var taskIdArg = args.FirstOrDefault(a => a.Key == "taskId"); + + val = await PerformDeploymentTask(null, managedCertificateIdArg.Value, taskIdArg.Value, isPreviewOnly: false, skipDeferredTasks: false, forceTaskExecution: false); + } else if (arg.CommandType == ManagementHubCommands.Reconnect) { await _managementServerClient.Disconnect(); diff --git a/src/Certify.Models/API/Management/ManagementHubMessages.cs b/src/Certify.Models/API/Management/ManagementHubMessages.cs index 108e35042..a2fc4f48d 100644 --- a/src/Certify.Models/API/Management/ManagementHubMessages.cs +++ b/src/Certify.Models/API/Management/ManagementHubMessages.cs @@ -30,6 +30,7 @@ public class ManagementHubCommands public const string GetAcmeAccounts = "GetAcmeAccounts"; public const string AddAcmeAccount = "AddAcmeAccount"; + public const string RemoveAcmeAccount = "RemoveAcmeAccount"; public const string GetStoredCredentials = "GetStoredCredentials"; public const string UpdateStoredCredential = "UpdateStoredCredential"; @@ -38,6 +39,9 @@ public class ManagementHubCommands public const string GetChallengeProviders = "GetChallengeProviders"; public const string GetDnsZones = "GetDnsZones"; + public const string GetDeploymentProviders = "GetDeploymentProviders"; + public const string ExecuteDeploymentTask = "ExecuteDeploymentTask"; + public const string Reconnect = "Reconnect"; } diff --git a/src/Certify.Server/Certify.Server.Api.Public.Client/Certify.API.Public.cs b/src/Certify.Server/Certify.Server.Api.Public.Client/Certify.API.Public.cs index cb6cf464c..14dfc1607 100644 --- a/src/Certify.Server/Certify.Server.Api.Public.Client/Certify.API.Public.cs +++ b/src/Certify.Server/Certify.Server.Api.Public.Client/Certify.API.Public.cs @@ -2895,23 +2895,26 @@ public virtual async System.Threading.Tasks.Task RemoveAcmeAccount } /// - /// Get List of supported deployment tasks + /// Get Deployment Task Providers [Generated by Certify.SourceGenerators] /// /// OK /// A server side error occurred. - public virtual System.Threading.Tasks.Task> GetDeploymentProvidersAsync() + public virtual System.Threading.Tasks.Task> GetDeploymentProvidersAsync(string instanceId) { - return GetDeploymentProvidersAsync(System.Threading.CancellationToken.None); + return GetDeploymentProvidersAsync(instanceId, System.Threading.CancellationToken.None); } /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// - /// Get List of supported deployment tasks + /// Get Deployment Task Providers [Generated by Certify.SourceGenerators] /// /// OK /// A server side error occurred. - public virtual async System.Threading.Tasks.Task> GetDeploymentProvidersAsync(System.Threading.CancellationToken cancellationToken) + public virtual async System.Threading.Tasks.Task> GetDeploymentProvidersAsync(string instanceId, System.Threading.CancellationToken cancellationToken) { + if (instanceId == null) + throw new System.ArgumentNullException("instanceId"); + var client_ = _httpClient; var disposeClient_ = false; try @@ -2923,8 +2926,9 @@ public virtual async System.Threading.Tasks.Task RemoveAcmeAccount var urlBuilder_ = new System.Text.StringBuilder(); if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "internal/v1/deploymenttask/providers" - urlBuilder_.Append("internal/v1/deploymenttask/providers"); + // Operation Path: "internal/v1/deploymenttask/{instanceId}" + urlBuilder_.Append("internal/v1/deploymenttask/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(instanceId, System.Globalization.CultureInfo.InvariantCulture))); PrepareRequest(client_, request_, urlBuilder_); @@ -2978,6 +2982,104 @@ public virtual async System.Threading.Tasks.Task RemoveAcmeAccount } } + /// + /// Execute Deployment Task [Generated by Certify.SourceGenerators] + /// + /// OK + /// A server side error occurred. + public virtual System.Threading.Tasks.Task> ExecuteDeploymentTaskAsync(string instanceId, string managedCertificateId, string taskId) + { + return ExecuteDeploymentTaskAsync(instanceId, managedCertificateId, taskId, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Execute Deployment Task [Generated by Certify.SourceGenerators] + /// + /// OK + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task> ExecuteDeploymentTaskAsync(string instanceId, string managedCertificateId, string taskId, System.Threading.CancellationToken cancellationToken) + { + if (instanceId == null) + throw new System.ArgumentNullException("instanceId"); + + if (managedCertificateId == null) + throw new System.ArgumentNullException("managedCertificateId"); + + if (taskId == null) + throw new System.ArgumentNullException("taskId"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("text/plain")); + + var urlBuilder_ = new System.Text.StringBuilder(); + if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); + // Operation Path: "internal/v1/deploymenttask/{instanceId}/execute/{managedCertificateId}/{taskId}" + urlBuilder_.Append("internal/v1/deploymenttask/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(instanceId, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/execute/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(managedCertificateId, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append('/'); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(taskId, System.Globalization.CultureInfo.InvariantCulture))); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + /// /// Get all managed certificates matching criteria /// diff --git a/src/Certify.Server/Certify.Server.Api.Public/Controllers/internal/DeploymentTaskController.cs b/src/Certify.Server/Certify.Server.Api.Public/Controllers/internal/DeploymentTaskController.cs index c26c79d6d..d3f0009bf 100644 --- a/src/Certify.Server/Certify.Server.Api.Public/Controllers/internal/DeploymentTaskController.cs +++ b/src/Certify.Server/Certify.Server.Api.Public/Controllers/internal/DeploymentTaskController.cs @@ -1,4 +1,5 @@ using Certify.Client; +using Certify.Server.Api.Public.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -16,31 +17,18 @@ public partial class DeploymentTaskController : ApiControllerBase private readonly ILogger _logger; private readonly ICertifyInternalApiClient _client; + private readonly ManagementAPI _mgmtAPI; /// /// Constructor /// /// /// - public DeploymentTaskController(ILogger logger, ICertifyInternalApiClient client) + public DeploymentTaskController(ILogger logger, ICertifyInternalApiClient client, ManagementAPI mgmtAPI) { _logger = logger; _client = client; - } - - /// - /// Get List of supported deployment tasks - /// - /// - [HttpGet] - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List))] - [Route("providers")] - public async Task GetDeploymentProviders() - { - var list = await _client.GetDeploymentProviderList(); - return new OkObjectResult(list); + _mgmtAPI = mgmtAPI; } } } diff --git a/src/Certify.Server/Certify.Server.Api.Public/Services/ManagementAPI.cs b/src/Certify.Server/Certify.Server.Api.Public/Services/ManagementAPI.cs index 06d031dd5..f97adddf3 100644 --- a/src/Certify.Server/Certify.Server.Api.Public/Services/ManagementAPI.cs +++ b/src/Certify.Server/Certify.Server.Api.Public/Services/ManagementAPI.cs @@ -197,6 +197,16 @@ public async Task GetManagedCertificateSummary(AuthContext? curre return await PerformInstanceCommandTaskWithResult(instanceId, args, ManagementHubCommands.UpdateCertificateAuthority); } + public async Task RemoveCertificateAuthority(string instanceId, string id, AuthContext? currentAuthContext) + { + var args = new KeyValuePair[] { + new("instanceId", instanceId), + new("id", id) + }; + + return await PerformInstanceCommandTaskWithResult(id, args, ManagementHubCommands.RemoveCertificateAuthority); + } + public async Task?> GetAcmeAccounts(string instanceId, AuthContext? currentAuthContext) { var args = new KeyValuePair[] { @@ -215,7 +225,16 @@ public async Task GetManagedCertificateSummary(AuthContext? curre return await PerformInstanceCommandTaskWithResult(instanceId, args, ManagementHubCommands.AddAcmeAccount); } + public async Task RemoveAcmeAccount(string instanceId, string storageKey, bool deactivate, AuthContext? currentAuthContext) + { + var args = new KeyValuePair[] { + new("instanceId", instanceId), + new("storageKey", storageKey), + new("deactivate", deactivate.ToString()) + }; + return await PerformInstanceCommandTaskWithResult(instanceId, args, ManagementHubCommands.RemoveAcmeAccount); + } public async Task?> GetChallengeProviders(string instanceId, AuthContext? currentAuthContext) { var args = new KeyValuePair[] { @@ -223,6 +242,24 @@ public async Task GetManagedCertificateSummary(AuthContext? curre }; return await PerformInstanceCommandTaskWithResult>(instanceId, args, ManagementHubCommands.GetChallengeProviders); } + public async Task?> GetDeploymentProviders(string instanceId, AuthContext? currentAuthContext) + { + var args = new KeyValuePair[] { + new("instanceId", instanceId) + }; + return await PerformInstanceCommandTaskWithResult>(instanceId, args, ManagementHubCommands.GetDeploymentProviders); + } + + public async Task?> ExecuteDeploymentTask(string instanceId, string managedCertificateId, string taskId, AuthContext? currentAuthContext) + { + var args = new KeyValuePair[] { + new("instanceId", instanceId), + new("managedCertificateId", managedCertificateId), + new("taskId", taskId) + }; + + return await PerformInstanceCommandTaskWithResult>(instanceId, args, ManagementHubCommands.ExecuteDeploymentTask); + } public async Task?> GetDnsZones(string instanceId, string providerTypeId, string credentialId, AuthContext? currentAuthContext) { diff --git a/src/Certify.SourceGenerators/ApiMethods.cs b/src/Certify.SourceGenerators/ApiMethods.cs index d28395960..30b1dd19d 100644 --- a/src/Certify.SourceGenerators/ApiMethods.cs +++ b/src/Certify.SourceGenerators/ApiMethods.cs @@ -144,6 +144,7 @@ public static List GetApiDefinitions() ReturnType = "Models.Config.ActionResult", Params = new Dictionary{{"id","string"}} }, + /* per instance API, via management hub */ new GeneratedAPI { OperationName = "GetAcmeAccounts", @@ -152,7 +153,6 @@ public static List GetApiDefinitions() UseManagementAPI = true, PublicAPIController = "CertificateAuthority", PublicAPIRoute = "{instanceId}/accounts/", - ServiceAPIRoute = "accounts", ReturnType = "ICollection", Params =new Dictionary{ { "instanceId", "string" } } }, @@ -163,7 +163,6 @@ public static List GetApiDefinitions() UseManagementAPI = true, PublicAPIController = "CertificateAuthority", PublicAPIRoute = "{instanceId}/account/", - ServiceAPIRoute = "accounts", ReturnType = "Models.Config.ActionResult", Params =new Dictionary{ { "instanceId", "string" },{ "registration", "Certify.Models.ContactRegistration" } } }, @@ -171,11 +170,10 @@ public static List GetApiDefinitions() OperationName = "GetCertificateAuthorities", OperationMethod = HttpGet, Comment = "Get list of defined Certificate Authorities", + UseManagementAPI = true, PublicAPIController = "CertificateAuthority", PublicAPIRoute = "{instanceId}/authority", - ServiceAPIRoute = "accounts/authorities", ReturnType = "ICollection", - UseManagementAPI = true, Params =new Dictionary{ { "instanceId", "string" } } }, new GeneratedAPI { @@ -185,7 +183,6 @@ public static List GetApiDefinitions() UseManagementAPI = true, PublicAPIController = "CertificateAuthority", PublicAPIRoute = "{instanceId}/authority", - ServiceAPIRoute = "accounts/authorities", ReturnType = "Models.Config.ActionResult", Params =new Dictionary{ { "instanceId", "string" }, { "ca", "Certify.Models.CertificateAuthority" } } }, @@ -193,9 +190,9 @@ public static List GetApiDefinitions() OperationName = "RemoveCertificateAuthority", OperationMethod = HttpDelete, Comment = "Remove Certificate Authority", + UseManagementAPI = true, PublicAPIController = "CertificateAuthority", PublicAPIRoute = "{instanceId}/authority/{id}", - ServiceAPIRoute = "accounts/authorities/{id}", ReturnType = "Models.Config.ActionResult", Params =new Dictionary{ { "instanceId", "string" },{ "id", "string" } } }, @@ -203,9 +200,9 @@ public static List GetApiDefinitions() OperationName = "RemoveAcmeAccount", OperationMethod = HttpDelete, Comment = "Remove ACME Account", + UseManagementAPI = true, PublicAPIController = "CertificateAuthority", PublicAPIRoute = "{instanceId}/accounts/{storageKey}/{deactivate}", - ServiceAPIRoute = "accounts/remove/{storageKey}/{deactivate}", ReturnType = "Models.Config.ActionResult", Params =new Dictionary{ { "instanceId", "string" }, { "storageKey", "string" }, { "deactivate", "bool" } } }, @@ -213,11 +210,10 @@ public static List GetApiDefinitions() OperationName = "GetStoredCredentials", OperationMethod = HttpGet, Comment = "Get List of Stored Credentials", + UseManagementAPI = true, PublicAPIController = "StoredCredential", PublicAPIRoute = "{instanceId}", - ServiceAPIRoute = "credentials", ReturnType = "ICollection", - UseManagementAPI = true, Params =new Dictionary{ { "instanceId", "string" } } }, new GeneratedAPI { @@ -226,7 +222,6 @@ public static List GetApiDefinitions() Comment = "Add/Update Stored Credential", PublicAPIController = "StoredCredential", PublicAPIRoute = "{instanceId}", - ServiceAPIRoute = "credentials", ReturnType = "Models.Config.ActionResult", UseManagementAPI = true, Params =new Dictionary{ { "instanceId", "string" }, { "item", "Models.Config.StoredCredential" } } @@ -235,22 +230,32 @@ public static List GetApiDefinitions() OperationName = "RemoveStoredCredential", OperationMethod = HttpDelete, Comment = "Remove Stored Credential", + UseManagementAPI = true, PublicAPIController = "StoredCredential", PublicAPIRoute = "{instanceId}/{storageKey}", - ServiceAPIRoute = "credentials", ReturnType = "Models.Config.ActionResult", - UseManagementAPI = true, Params =new Dictionary{ { "instanceId", "string" },{ "storageKey", "string" } } }, + new GeneratedAPI { + OperationName = "GetDeploymentProviders", + OperationMethod = HttpGet, + Comment = "Get Deployment Task Providers", + UseManagementAPI = true, + PublicAPIController = "DeploymentTask", + PublicAPIRoute = "{instanceId}", + ReturnType = "ICollection", + Params =new Dictionary{ + { "instanceId", "string" } + } + }, new GeneratedAPI { OperationName = "GetChallengeProviders", OperationMethod = HttpGet, Comment = "Get Dns Challenge Providers", + UseManagementAPI = true, PublicAPIController = "ChallengeProvider", PublicAPIRoute = "{instanceId}", - ServiceAPIRoute = "managedcertificates/challengeapis/", ReturnType = "ICollection", - UseManagementAPI = true, Params =new Dictionary{ { "instanceId", "string" } } @@ -259,17 +264,41 @@ public static List GetApiDefinitions() OperationName = "GetDnsZones", OperationMethod = HttpGet, Comment = "Get List of Zones with the current DNS provider and credential", + UseManagementAPI = true, PublicAPIController = "ChallengeProvider", PublicAPIRoute = "{instanceId}/dnszones/{providerTypeId}/{credentialId}", - ServiceAPIRoute = "managedcertificates/dnszones/{providerTypeId}/{credentialId}", ReturnType = "ICollection", - UseManagementAPI = true, Params =new Dictionary{ { "instanceId", "string" } , { "providerTypeId", "string" }, { "credentialId", "string" } } }, + new GeneratedAPI { + OperationName = "ExecuteDeploymentTask", + OperationMethod = HttpGet, + Comment = "Execute Deployment Task", + UseManagementAPI = true, + PublicAPIController = "DeploymentTask", + PublicAPIRoute = "{instanceId}/execute/{managedCertificateId}/{taskId}", + ReturnType = "ICollection", + Params =new Dictionary{ + { "instanceId", "string" }, + { "managedCertificateId", "string" }, + { "taskId", "string" } + } + }, + new GeneratedAPI { + OperationName = "RemoveManagedCertificate", + OperationMethod = HttpDelete, + Comment = "Remove Managed Certificate", + UseManagementAPI = true, + PublicAPIController = "Certificate", + PublicAPIRoute = "{instanceId}/settings/{managedCertId}", + ReturnType = "bool", + Params =new Dictionary{ { "instanceId", "string" },{ "managedCertId", "string" } } + }, + // TODO new GeneratedAPI { OperationName = "PerformExport", OperationMethod = HttpPost, @@ -290,18 +319,6 @@ public static List GetApiDefinitions() ReturnType = "ICollection", Params =new Dictionary{{ "importRequest", "Certify.Models.Config.Migration.ImportRequest" } } }, - new GeneratedAPI { - - OperationName = "RemoveManagedCertificate", - OperationMethod = HttpDelete, - Comment = "Remove Managed Certificate", - PublicAPIController = "Certificate", - PublicAPIRoute = "{instanceId}/settings/{managedCertId}", - UseManagementAPI = true, - ServiceAPIRoute = "managedcertificates/delete/{managedCertId}", - ReturnType = "bool", - Params =new Dictionary{ { "instanceId", "string" },{ "managedCertId", "string" } } - }, }; } } diff --git a/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs b/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs index b98821814..c330aeae5 100644 --- a/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs +++ b/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs @@ -44,7 +44,46 @@ public void Execute(GeneratorExecutionContext context) if (context.Compilation.AssemblyName.EndsWith("Api.Public")) { - context.AddSource($"{config.PublicAPIController}Controller.{config.OperationName}.g.cs", SourceText.From($@" + ImplementPublicAPI(context, config, apiParamDeclWithoutAuthContext, apiParamCall); + } + + if (context.Compilation.AssemblyName.EndsWith("Certify.UI.Blazor")) + { + ImplementAppModel(context, config, apiParamDeclWithoutAuthContext, apiParamCallWithoutAuthContext); + } + + if (context.Compilation.AssemblyName.EndsWith("Certify.Client") && !config.UseManagementAPI) + { + // for methods which directly call the backend service (e.g. main server settings), implement the client API + ImplementInternalAPIClient(context, config, apiParamDecl, apiParamCall); + } + } + } + + private static void ImplementAppModel(GeneratorExecutionContext context, GeneratedAPI config, string apiParamDeclWithoutAuthContext, string apiParamCallWithoutAuthContext) + { + context.AddSource($"AppModel.{config.OperationName}.g.cs", SourceText.From($@" +using System.Collections.Generic; +using System.Threading.Tasks; +using Certify.Models; +using Certify.Models.Providers; +using Certify.Models.Config.AccessControl; + + namespace Certify.UI.Client.Core + {{ + public partial class AppModel + {{ + public async Task<{config.ReturnType}> {config.OperationName}({apiParamDeclWithoutAuthContext}) + {{ + return await _api.{config.OperationName}Async({apiParamCallWithoutAuthContext}); + }} + }} + }}", Encoding.UTF8)); + } + + private static void ImplementPublicAPI(GeneratorExecutionContext context, GeneratedAPI config, string apiParamDeclWithoutAuthContext, string apiParamCall) + { + context.AddSource($"{config.PublicAPIController}Controller.{config.OperationName}.g.cs", SourceText.From($@" using Certify.Client; using Certify.Server.Api.Public.Controllers; @@ -79,11 +118,11 @@ public partial class {config.PublicAPIController}Controller }} }}", Encoding.UTF8)); - } + } - if (context.Compilation.AssemblyName.EndsWith("Certify.Client")) - { - var template = @" + private static void ImplementInternalAPIClient(GeneratorExecutionContext context, GeneratedAPI config, string apiParamDecl, string apiParamCall) + { + var template = @" using Certify.Models; using Certify.Models.Config.Migration; using Certify.Models.Providers; @@ -97,9 +136,9 @@ namespace Certify.Client } "; - if (config.OperationMethod == "HttpGet") - { - var source = SourceText.From(template.Replace("MethodTemplate", $@" + if (config.OperationMethod == "HttpGet") + { + var code = template.Replace("MethodTemplate", $@" public partial interface ICertifyInternalApiClient {{ @@ -124,23 +163,24 @@ public partial class CertifyApiClient }} }} - "), Encoding.UTF8); - context.AddSource($"{config.PublicAPIController}.{config.OperationName}.ICertifyInternalApiClient.g.cs", source); - } + "); + var source = SourceText.From(code, Encoding.UTF8); + context.AddSource($"{config.PublicAPIController}.{config.OperationName}.ICertifyInternalApiClient.g.cs", source); + } - if (config.OperationMethod == "HttpPost") - { - var postAPIRoute = config.ServiceAPIRoute; - var postApiCall = apiParamCall; - var postApiParamDecl = apiParamDecl; + if (config.OperationMethod == "HttpPost") + { + var postAPIRoute = config.ServiceAPIRoute; + var postApiCall = apiParamCall; + var postApiParamDecl = apiParamDecl; - if (config.UseManagementAPI) - { - postApiCall = apiParamCall.Replace("instanceId,", ""); - postApiParamDecl = apiParamDecl.Replace("string instanceId,", ""); - } + if (config.UseManagementAPI) + { + postApiCall = apiParamCall.Replace("instanceId,", ""); + postApiParamDecl = apiParamDecl.Replace("string instanceId,", ""); + } - context.AddSource($"{config.PublicAPIController}.{config.OperationName}.ICertifyInternalApiClient.g.cs", SourceText.From(template.Replace("MethodTemplate", $@" + context.AddSource($"{config.PublicAPIController}.{config.OperationName}.ICertifyInternalApiClient.g.cs", SourceText.From(template.Replace("MethodTemplate", $@" public partial interface ICertifyInternalApiClient {{ @@ -167,11 +207,11 @@ public partial class CertifyApiClient }} "), Encoding.UTF8)); - } + } - if (config.OperationMethod == "HttpDelete") - { - context.AddSource($"{config.PublicAPIController}.{config.OperationName}.ICertifyInternalApiClient.g.cs", SourceText.From(template.Replace("MethodTemplate", $@" + if (config.OperationMethod == "HttpDelete") + { + context.AddSource($"{config.PublicAPIController}.{config.OperationName}.ICertifyInternalApiClient.g.cs", SourceText.From(template.Replace("MethodTemplate", $@" public partial interface ICertifyInternalApiClient {{ @@ -202,31 +242,9 @@ public partial class CertifyApiClient }} "), Encoding.UTF8)); - } - } - - if (context.Compilation.AssemblyName.EndsWith("Certify.UI.Blazor")) - { - context.AddSource($"AppModel.{config.OperationName}.g.cs", SourceText.From($@" -using System.Collections.Generic; -using System.Threading.Tasks; -using Certify.Models; -using Certify.Models.Providers; -using Certify.Models.Config.AccessControl; - - namespace Certify.UI.Client.Core - {{ - public partial class AppModel - {{ - public async Task<{config.ReturnType}> {config.OperationName}({apiParamDeclWithoutAuthContext}) - {{ - return await _api.{config.OperationName}Async({apiParamCallWithoutAuthContext}); - }} - }} - }}", Encoding.UTF8)); - } } } + public void Initialize(GeneratorInitializationContext context) { #if DEBUG @@ -234,7 +252,7 @@ public void Initialize(GeneratorInitializationContext context) // then add a watch on if (!Debugger.IsAttached) { - // Debugger.Launch(); + // Debugger.Launch(); } #endif }