diff --git a/src/Certify.SourceGenerators/ApiMethods.cs b/src/Certify.SourceGenerators/ApiMethods.cs index fcafd0d65..d8d8c1fba 100644 --- a/src/Certify.SourceGenerators/ApiMethods.cs +++ b/src/Certify.SourceGenerators/ApiMethods.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using SourceGenerator; @@ -162,7 +162,8 @@ public static List GetApiDefinitions() PublicAPIController = "ManagedChallenge", PublicAPIRoute = "list", ServiceAPIRoute = "managedchallenge", - ReturnType = "ICollection" + ReturnType = "ICollection", + RequiredPermissions = [new ("managedchallenge", "managedchallenge_list")] }, new GeneratedAPI { @@ -176,7 +177,8 @@ public static List GetApiDefinitions() ReturnType = "Models.Config.ActionResult", Params = new Dictionary{ { "update", "Certify.Models.Hub.ManagedChallenge" } - } + }, + RequiredPermissions = [new ("managedchallenge", "managedchallenge_update")] }, new GeneratedAPI { @@ -190,7 +192,8 @@ public static List GetApiDefinitions() ReturnType = "Models.Config.ActionResult", Params = new Dictionary{ { "id", "string" } - } + }, + RequiredPermissions = [new ("managedchallenge", "managedchallenge_delete")] }, new GeneratedAPI { @@ -202,7 +205,8 @@ public static List GetApiDefinitions() ReturnType = "Models.Config.ActionResult", Params = new Dictionary{ { "request", "Certify.Models.Hub.ManagedChallengeRequest" } - } + }, + RequiredPermissions = [new ("managedchallenge", "managedchallenge_request")] }, new GeneratedAPI { diff --git a/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs b/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs index 59f2ea499..1ee719ac8 100644 --- a/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs +++ b/src/Certify.SourceGenerators/PublicAPISourceGenerator.cs @@ -2,7 +2,6 @@ using System.Diagnostics; using System.Linq; using System.Text; -using System.Threading.Tasks; using Certify.SourceGenerators; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; @@ -17,12 +16,24 @@ public class GeneratedAPI public string PublicAPIController { get; set; } = string.Empty; public string PublicAPIRoute { get; set; } = string.Empty; + public List RequiredPermissions { get; set; } = []; public bool UseManagementAPI { get; set; } = false; public string ManagementHubCommandType { get; set; } = string.Empty; public string ServiceAPIRoute { get; set; } = string.Empty; public string ReturnType { get; set; } = string.Empty; public Dictionary Params { get; set; } = new Dictionary(); } + + public class PermissionSpec + { + public string ResourceType { get; set; } + public string Action { get; set; } + public PermissionSpec(string resourceType, string action) + { + ResourceType = resourceType; + Action = action; + } + } [Generator] public class PublicAPISourceGenerator : ISourceGenerator { @@ -86,7 +97,7 @@ public partial class AppModel private static void ImplementPublicAPI(GeneratorExecutionContext context, GeneratedAPI config, string apiParamDeclWithoutAuthContext, string apiParamDecl, string apiParamCall) { - context.AddSource($"{config.PublicAPIController}Controller.{config.OperationName}.g.cs", SourceText.From($@" + var publicApiSrc = $@" using Certify.Client; using Certify.Server.Api.Public.Controllers; @@ -115,12 +126,39 @@ public partial class {config.PublicAPIController}Controller [Route(""""""{config.PublicAPIRoute}"""""")] public async Task {config.OperationName}({apiParamDeclWithoutAuthContext}) {{ + + [RequiredPermissions] + var result = await {(config.UseManagementAPI ? "_mgmtAPI" : "_client")}.{config.OperationName}({apiParamCall.Replace("authContext", "CurrentAuthContext")}); return new OkObjectResult(result); }} }} - }} - ", Encoding.UTF8)); + }}; + "; + + if (config.RequiredPermissions.Any()) + { + var fragment = ""; + foreach (var perm in config.RequiredPermissions) + { + fragment += $@" + if (!await IsAuthorized(_client, ""{perm.ResourceType}"" , ""{perm.Action}"")) + {{ + {{ + return Unauthorized(); + }} + }} + "; + } + + publicApiSrc = publicApiSrc.Replace("[RequiredPermissions]", fragment); + } + else + { + publicApiSrc = publicApiSrc.Replace("[RequiredPermissions]", ""); + } + + context.AddSource($"{config.PublicAPIController}Controller.{config.OperationName}.g.cs", SourceText.From(publicApiSrc, Encoding.UTF8)); // Management API service