Incremental work on secure endpoints

This commit is contained in:
Sipke Schoorstra 2022-08-27 22:16:48 +02:00
parent 27cfe7eb91
commit 2bd4a9b6e9
14 changed files with 61 additions and 96 deletions

View file

@ -0,0 +1,37 @@
using Elsa.Workflows.Core.Services;
using FastEndpoints;
namespace Elsa.Abstractions;
public abstract class ElsaEndpointWithoutRequest<TResponse> : EndpointWithoutRequest<TResponse> where TResponse : notnull
{
protected void ConfigurePermissions(params string[] permissions)
{
if (!EndpointSecurityOptions.SecurityIsEnabled)
AllowAnonymous();
else
Permissions((new[] { PermissionNames.All }).Concat(permissions).ToArray());
}
}
public class ElsaEndpoint<TRequest, TResponse> : Endpoint<TRequest, TResponse> where TRequest : notnull, new() where TResponse : notnull
{
protected void ConfigurePermissions(params string[] permissions)
{
if (!EndpointSecurityOptions.SecurityIsEnabled)
AllowAnonymous();
else
Permissions((new[] { PermissionNames.All }).Concat(permissions).ToArray());
}
}
public class ElsaEndpoint<TRequest> : Endpoint<TRequest> where TRequest : notnull
{
protected void ConfigurePermissions(params string[] permissions)
{
if (!EndpointSecurityOptions.SecurityIsEnabled)
AllowAnonymous();
else
Permissions((new[] { PermissionNames.All }).Concat(permissions).ToArray());
}
}

View file

@ -0,0 +1,6 @@
namespace Elsa;
public static class PermissionNames
{
public const string All = "*";
}

View file

@ -1,12 +0,0 @@
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.BulkDelete;
/// <summary>
/// Provides policy names accepted by the <see cref="BulkDelete"/> endpoint.
/// </summary>
public static class Constants
{
/// <summary>
/// The policy name accepted by this endpoint.
/// </summary>
public const string PolicyName = "BulkDeleteActivityDefinitions";
}

View file

@ -1,12 +1,12 @@
using Elsa.Abstractions;
using Elsa.ActivityDefinitions.Services;
using FastEndpoints;
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.BulkDelete;
/// <summary>
/// An endpoint that bulk-deletes activity definitions.
/// </summary>
public class BulkDelete : Endpoint<Request, Response>
public class BulkDelete : ElsaEndpoint<Request, Response>
{
private readonly IActivityDefinitionStore _activityDefinitionStore;
@ -20,7 +20,7 @@ public class BulkDelete : Endpoint<Request, Response>
public override void Configure()
{
Post("/bulk-actions/delete/activity-definitions/by-definition-id");
Policies(Constants.PolicyName);
ConfigurePermissions("delete:activity-definitions");
}
/// <inheritdoc />

View file

@ -1,12 +0,0 @@
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.Delete;
/// <summary>
/// Provides policy names accepted by the <see cref="Delete"/> endpoint.
/// </summary>
public static class Constants
{
/// <summary>
/// The policy name accepted by this endpoint.
/// </summary>
public const string PolicyName = "DeleteActivityDefinition";
}

View file

@ -1,12 +1,12 @@
using Elsa.Abstractions;
using Elsa.ActivityDefinitions.Services;
using FastEndpoints;
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.Delete;
/// <summary>
/// An endpoint that deletes a specific activity definition by ID.
/// </summary>
public class Delete : Endpoint<Request>
public class Delete : ElsaEndpoint<Request>
{
private readonly IActivityDefinitionStore _activityDefinitionStore;
@ -20,7 +20,7 @@ public class Delete : Endpoint<Request>
public override void Configure()
{
Delete("/activity-definitions/{definitionId}");
Policies(Constants.PolicyName);
ConfigurePermissions("delete:activity-definitions");
}
/// <inheritdoc />

View file

@ -1,12 +0,0 @@
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.Get;
/// <summary>
/// Provides policy names accepted by the <see cref="Get"/> endpoint.
/// </summary>
public static class Constants
{
/// <summary>
/// The policy name accepted by this endpoint.
/// </summary>
public const string PolicyName = "ReadActivityDefinitions";
}

View file

@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Elsa.Abstractions;
using Elsa.ActivityDefinitions.Entities;
using Elsa.ActivityDefinitions.Models;
using Elsa.ActivityDefinitions.Services;
@ -14,7 +15,7 @@ namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.Get;
/// <summary>
/// An endpoint that returns the specified <see cref="ActivityDefinition"/> by ID.
/// </summary>
public class Get : Endpoint<Request, ActivityDefinitionModel>
public class Get : ElsaEndpoint<Request, ActivityDefinitionModel>
{
private readonly IActivityDefinitionStore _activityDefinitionStore;
private readonly VariableDefinitionMapper _variableDefinitionMapper;
@ -32,7 +33,7 @@ public class Get : Endpoint<Request, ActivityDefinitionModel>
public override void Configure()
{
Get("/activity-definitions/{definitionId}");
Policies(Constants.PolicyName);
ConfigurePermissions("read:activity-definitions");
}
/// <inheritdoc />

View file

@ -1,12 +0,0 @@
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.List;
/// <summary>
/// Provides policy names accepted by the <see cref="List"/> endpoint.
/// </summary>
public static class Constants
{
/// <summary>
/// The policy name accepted by this endpoint.
/// </summary>
public const string PolicyName = "ListActivityDefinitions";
}

View file

@ -1,3 +1,4 @@
using Elsa.Abstractions;
using Elsa.ActivityDefinitions.Models;
using Elsa.ActivityDefinitions.Services;
using Elsa.Models;
@ -8,7 +9,7 @@ namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.List;
/// <summary>
/// An endpoint that returns a page of <see cref="ActivityDefinitionSummary"/> objects.
/// </summary>
public class List : Endpoint<Request, PagedListResponse<ActivityDefinitionSummary>>
public class List : ElsaEndpoint<Request, PagedListResponse<ActivityDefinitionSummary>>
{
private readonly IActivityDefinitionStore _store;
@ -22,7 +23,7 @@ public class List : Endpoint<Request, PagedListResponse<ActivityDefinitionSummar
public override void Configure()
{
Get("/activity-definitions");
Policies(Constants.PolicyName);
ConfigurePermissions("read:activity-definitions");
}
/// <inheritdoc />

View file

@ -1,12 +0,0 @@
namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.Post;
/// <summary>
/// Provides policy names accepted by the <see cref="Post"/> endpoint.
/// </summary>
public static class Constants
{
/// <summary>
/// The policy name accepted by this endpoint.
/// </summary>
public const string PolicyName = "CreateOrUpdateActivityDefinition";
}

View file

@ -1,4 +1,5 @@
using System.Text.Json;
using Elsa.Abstractions;
using Elsa.ActivityDefinitions.Entities;
using Elsa.ActivityDefinitions.Services;
using Elsa.Workflows.Core.Activities.Flowchart.Activities;
@ -12,7 +13,7 @@ namespace Elsa.ActivityDefinitions.Endpoints.ActivityDefinitions.Post;
/// <summary>
/// An endpoint that creates or updates <see cref="ActivityDefinition"/> objects.
/// </summary>
public class Post : Endpoint<Request, Response>
public class Post : ElsaEndpoint<Request, Response>
{
private readonly SerializerOptionsProvider _serializerOptionsProvider;
private readonly IActivityDefinitionPublisher _activityDefinitionPublisher;
@ -33,7 +34,7 @@ public class Post : Endpoint<Request, Response>
public override void Configure()
{
Post("/activity-definitions");
Policies(Constants.PolicyName);
ConfigurePermissions("write:activity-definitions");
}
/// <inheritdoc />

View file

@ -1,13 +0,0 @@
namespace Elsa.Workflows.Api.Endpoints.ActivityDescriptors.List;
/// <summary>
/// Provides policy names accepted by the <see cref="List"/> endpoint.
/// </summary>
public static class Constants
{
/// <summary>
/// The policy name accepted by this endpoint.
/// </summary>
public const string PolicyName = "ListActivityDescriptors";
}

View file

@ -1,13 +1,14 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Abstractions;
using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Management.Services;
using FastEndpoints;
namespace Elsa.Workflows.Api.Endpoints.ActivityDescriptors.List;
public class List : EndpointWithoutRequest<Response>
public class List : ElsaEndpointWithoutRequest<Response>
{
private readonly IActivityRegistry _registry;
@ -19,16 +20,7 @@ public class List : EndpointWithoutRequest<Response>
public override void Configure()
{
Get("/descriptors/activities");
if (!EndpointSecurityOptions.SecurityIsEnabled)
{
AllowAnonymous();
}
else
{
Roles("Admin", "Reader");
Permissions("*", "list:activity-descriptors");
}
ConfigurePermissions("list:activity-descriptors");
}
public override Task<Response> ExecuteAsync(CancellationToken cancellationToken)