Browse Source

UI Claims. (#909)

pull/911/head
Sebastian Stehle 3 years ago
committed by GitHub
parent
commit
cc1db76e23
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      backend/src/Squidex.Domain.Apps.Core.Model/Apps/Role.cs
  2. 30
      backend/src/Squidex.Domain.Apps.Core.Model/Apps/Roles.cs
  3. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs
  4. 21
      backend/src/Squidex.Domain.Apps.Entities/Apps/AppExtensions.cs
  5. 22
      backend/src/Squidex.Domain.Apps.Entities/Apps/AppSettingsSearchSource.cs
  6. 12
      backend/src/Squidex.Domain.Apps.Entities/Apps/RolePermissionsProvider.cs
  7. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsSearchSource.cs
  8. 6
      backend/src/Squidex.Domain.Apps.Entities/Assets/DomainObject/AssetsBulkUpdateCommandMiddleware.cs
  9. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/ContentsSearchSource.cs
  10. 16
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs
  11. 14
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentsBulkUpdateCommandMiddleware.cs
  12. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/SecurityExtensions.cs
  13. 12
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentActions.cs
  14. 6
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs
  15. 2
      backend/src/Squidex.Domain.Apps.Entities/Context.cs
  16. 2
      backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemasSearchSource.cs
  17. 2
      backend/src/Squidex.Domain.Users/DefaultUserService.cs
  18. 2
      backend/src/Squidex.Domain.Users/UserClaimsPrincipalFactoryWithEmail.cs
  19. 2
      backend/src/Squidex.Shared/Identity/SquidexClaimTypes.cs
  20. 23
      backend/src/Squidex.Shared/Identity/SquidexClaimsExtensions.cs
  21. 2
      backend/src/Squidex.Shared/PermissionExtensions.cs
  22. 9
      backend/src/Squidex.Shared/PermissionIds.cs
  23. 2
      backend/src/Squidex.Web/Pipeline/ApiPermissionUnifier.cs
  24. 14
      backend/src/Squidex.Web/Pipeline/AppResolver.cs
  25. 108
      backend/src/Squidex.Web/Resources.cs
  26. 4
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppAssetsController.cs
  27. 8
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppClientsController.cs
  28. 6
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppContributorsController.cs
  29. 8
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppLanguagesController.cs
  30. 10
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs
  31. 2
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppSettingsController.cs
  32. 8
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs
  33. 8
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppsController.cs
  34. 53
      backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs
  35. 10
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs
  36. 26
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs
  37. 6
      backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs
  38. 4
      backend/src/Squidex/Areas/Api/Controllers/Backups/RestoreController.cs
  39. 8
      backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs
  40. 24
      backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs
  41. 2
      backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/OperationBuilder.cs
  42. 22
      backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs
  43. 4
      backend/src/Squidex/Areas/Api/Controllers/Diagnostics/DiagnosticsController.cs
  44. 8
      backend/src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs
  45. 2
      backend/src/Squidex/Areas/Api/Controllers/History/HistoryController.cs
  46. 2
      backend/src/Squidex/Areas/Api/Controllers/Ping/PingController.cs
  47. 4
      backend/src/Squidex/Areas/Api/Controllers/Plans/AppPlansController.cs
  48. 32
      backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs
  49. 38
      backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs
  50. 24
      backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs
  51. 2
      backend/src/Squidex/Areas/Api/Controllers/Search/SearchController.cs
  52. 8
      backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs
  53. 2
      backend/src/Squidex/Areas/Api/Controllers/Translations/TranslationsController.cs
  54. 2
      backend/src/Squidex/Areas/Api/Controllers/UI/UIController.cs
  55. 14
      backend/src/Squidex/Areas/Api/Controllers/Users/UserManagementController.cs
  56. 2
      backend/src/Squidex/Areas/IdentityServer/Config/ApplicationExtensions.cs
  57. 4
      backend/src/Squidex/Areas/IdentityServer/Config/CreateAdminInitializer.cs
  58. 22
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppSettingsSearchSourceTests.cs
  59. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsSearchSourceTests.cs
  60. 14
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/DomainObject/AssetsBulkUpdateCommandMiddlewareTests.cs
  61. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentsSearchSourceTests.cs
  62. 48
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/ContentsBulkUpdateCommandMiddlewareTests.cs
  63. 10
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs
  64. 38
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs
  65. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs
  66. 8
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ContentQueryServiceTests.cs
  67. 6
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemasSearchSourceTests.cs
  68. 2
      backend/tests/Squidex.Domain.Users.Tests/DefaultUserServiceTests.cs
  69. 10
      backend/tests/Squidex.Web.Tests/ApiPermissionAttributeTests.cs
  70. 2
      backend/tests/Squidex.Web.Tests/Pipeline/ApiPermissionUnifierTests.cs

25
backend/src/Squidex.Domain.Apps.Core.Model/Apps/Role.cs

@ -9,6 +9,7 @@ using System.Diagnostics.Contracts;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Security;
using Squidex.Shared;
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
@ -18,16 +19,16 @@ namespace Squidex.Domain.Apps.Core.Apps
{
private static readonly HashSet<string> ExtraPermissions = new HashSet<string>
{
Shared.Permissions.AppComments,
Shared.Permissions.AppContributorsRead,
Shared.Permissions.AppHistory,
Shared.Permissions.AppLanguagesRead,
Shared.Permissions.AppPing,
Shared.Permissions.AppRolesRead,
Shared.Permissions.AppSchemasRead,
Shared.Permissions.AppSearch,
Shared.Permissions.AppTranslate,
Shared.Permissions.AppUsage
PermissionIds.AppComments,
PermissionIds.AppContributorsRead,
PermissionIds.AppHistory,
PermissionIds.AppLanguagesRead,
PermissionIds.AppPing,
PermissionIds.AppRolesRead,
PermissionIds.AppSchemasRead,
PermissionIds.AppSearch,
PermissionIds.AppTranslate,
PermissionIds.AppUsage
};
public const string Editor = "Editor";
@ -75,7 +76,7 @@ namespace Squidex.Domain.Apps.Core.Apps
if (Permissions.Any())
{
var prefix = Shared.Permissions.ForApp(Shared.Permissions.App, app).Id;
var prefix = PermissionIds.ForApp(PermissionIds.App, app).Id;
foreach (var permission in Permissions)
{
@ -87,7 +88,7 @@ namespace Squidex.Domain.Apps.Core.Apps
{
foreach (var extraPermissionId in ExtraPermissions)
{
var extraPermission = Shared.Permissions.ForApp(extraPermissionId, app);
var extraPermission = PermissionIds.ForApp(extraPermissionId, app);
result.Add(extraPermission);
}

30
backend/src/Squidex.Domain.Apps.Core.Model/Apps/Roles.cs

@ -24,33 +24,33 @@ namespace Squidex.Domain.Apps.Core.Apps
[Role.Owner] =
new Role(Role.Owner,
new PermissionSet(
WithoutPrefix(Permissions.App)),
WithoutPrefix(PermissionIds.App)),
new JsonObject()),
[Role.Reader] =
new Role(Role.Reader,
new PermissionSet(
WithoutPrefix(Permissions.AppAssetsRead),
WithoutPrefix(Permissions.AppContentsRead)),
WithoutPrefix(PermissionIds.AppAssetsRead),
WithoutPrefix(PermissionIds.AppContentsRead)),
new JsonObject()
.Add("ui.api.hide", true)),
[Role.Editor] =
new Role(Role.Editor,
new PermissionSet(
WithoutPrefix(Permissions.AppAssets),
WithoutPrefix(Permissions.AppContents),
WithoutPrefix(Permissions.AppRolesRead),
WithoutPrefix(Permissions.AppWorkflowsRead)),
WithoutPrefix(PermissionIds.AppAssets),
WithoutPrefix(PermissionIds.AppContents),
WithoutPrefix(PermissionIds.AppRolesRead),
WithoutPrefix(PermissionIds.AppWorkflowsRead)),
new JsonObject()
.Add("ui.api.hide", true)),
[Role.Developer] =
new Role(Role.Developer,
new PermissionSet(
WithoutPrefix(Permissions.AppAssets),
WithoutPrefix(Permissions.AppContents),
WithoutPrefix(Permissions.AppRolesRead),
WithoutPrefix(Permissions.AppRules),
WithoutPrefix(Permissions.AppSchemas),
WithoutPrefix(Permissions.AppWorkflows)),
WithoutPrefix(PermissionIds.AppAssets),
WithoutPrefix(PermissionIds.AppContents),
WithoutPrefix(PermissionIds.AppRolesRead),
WithoutPrefix(PermissionIds.AppRules),
WithoutPrefix(PermissionIds.AppSchemas),
WithoutPrefix(PermissionIds.AppWorkflows)),
new JsonObject())
};
@ -175,9 +175,9 @@ namespace Squidex.Domain.Apps.Core.Apps
private static string WithoutPrefix(string permission)
{
permission = Permissions.ForApp(permission).Id;
permission = PermissionIds.ForApp(permission).Id;
var prefix = Permissions.ForApp(Permissions.App);
var prefix = PermissionIds.ForApp(PermissionIds.App);
if (permission.StartsWith(prefix.Id, StringComparison.OrdinalIgnoreCase))
{

2
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs

@ -149,7 +149,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
var claimsIdentity = new ClaimsIdentity();
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
claimsIdentity.AddClaim(new Claim(SquidexClaimTypes.Permissions, Permissions.All));
claimsIdentity.AddClaim(new Claim(SquidexClaimTypes.Permissions, PermissionIds.All));
return claimsPrincipal;
}

21
backend/src/Squidex.Domain.Apps.Entities/Apps/AppExtensions.cs

@ -5,6 +5,8 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Diagnostics.CodeAnalysis;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Apps
@ -15,5 +17,24 @@ namespace Squidex.Domain.Apps.Entities.Apps
{
return new NamedId<DomainId>(app.Id, app.Name);
}
public static bool TryGetContributorRole(this IAppEntity app, string id, bool isFrontend, [MaybeNullWhen(false)] out Role role)
{
role = null;
return app.Contributors.TryGetValue(id, out var roleName) && app.TryGetRole(roleName, isFrontend, out role);
}
public static bool TryGetClientRole(this IAppEntity app, string id, bool isFrontend, [MaybeNullWhen(false)] out Role role)
{
role = null;
return app.Clients.TryGetValue(id, out var client) && app.TryGetRole(client.Role, isFrontend, out role);
}
public static bool TryGetRole(this IAppEntity app, string roleName, bool isFrontend, [MaybeNullWhen(false)] out Role role)
{
return app.Roles.TryGet(app.Name, roleName, isFrontend, out role);
}
}
}

22
backend/src/Squidex.Domain.Apps.Entities/Apps/AppSettingsSearchSource.cs

@ -42,37 +42,37 @@ namespace Squidex.Domain.Apps.Entities.Apps
}
}
Search("Assets", Permissions.AppAssetsRead,
Search("Assets", PermissionIds.AppAssetsRead,
a => urlGenerator.AssetsUI(a), SearchResultType.Asset);
Search("Backups", Permissions.AppBackupsRead,
Search("Backups", PermissionIds.AppBackupsRead,
urlGenerator.BackupsUI, SearchResultType.Setting);
Search("Clients", Permissions.AppClientsRead,
Search("Clients", PermissionIds.AppClientsRead,
urlGenerator.ClientsUI, SearchResultType.Setting);
Search("Contributors", Permissions.AppContributorsRead,
Search("Contributors", PermissionIds.AppContributorsRead,
urlGenerator.ContributorsUI, SearchResultType.Setting);
Search("Dashboard", Permissions.AppUsage,
Search("Dashboard", PermissionIds.AppUsage,
urlGenerator.DashboardUI, SearchResultType.Dashboard);
Search("Languages", Permissions.AppLanguagesRead,
Search("Languages", PermissionIds.AppLanguagesRead,
urlGenerator.LanguagesUI, SearchResultType.Setting);
Search("Roles", Permissions.AppRolesRead,
Search("Roles", PermissionIds.AppRolesRead,
urlGenerator.RolesUI, SearchResultType.Setting);
Search("Rules", Permissions.AppRulesRead,
Search("Rules", PermissionIds.AppRulesRead,
urlGenerator.RulesUI, SearchResultType.Rule);
Search("Schemas", Permissions.AppSchemasRead,
Search("Schemas", PermissionIds.AppSchemasRead,
urlGenerator.SchemasUI, SearchResultType.Schema);
Search("Subscription", Permissions.AppPlansRead,
Search("Subscription", PermissionIds.AppPlansRead,
urlGenerator.PlansUI, SearchResultType.Setting);
Search("Workflows", Permissions.AppWorkflowsRead,
Search("Workflows", PermissionIds.AppWorkflowsRead,
urlGenerator.WorkflowsUI, SearchResultType.Setting);
return Task.FromResult(result);

12
backend/src/Squidex.Domain.Apps.Entities/Apps/RolePermissionsProvider.cs

@ -21,15 +21,15 @@ namespace Squidex.Domain.Apps.Entities.Apps
{
this.appProvider = appProvider;
foreach (var field in typeof(Permissions).GetFields(BindingFlags.Public | BindingFlags.Static))
foreach (var field in typeof(PermissionIds).GetFields(BindingFlags.Public | BindingFlags.Static))
{
if (field.IsLiteral && !field.IsInitOnly)
{
var value = field.GetValue(null) as string;
if (value?.StartsWith(Permissions.App, StringComparison.OrdinalIgnoreCase) == true)
if (value?.StartsWith(PermissionIds.App, StringComparison.OrdinalIgnoreCase) == true)
{
if (value.IndexOf("{schema}", Permissions.App.Length, StringComparison.OrdinalIgnoreCase) >= 0)
if (value.IndexOf("{schema}", PermissionIds.App.Length, StringComparison.OrdinalIgnoreCase) >= 0)
{
forAppSchemas.Add(value);
}
@ -50,9 +50,9 @@ namespace Squidex.Domain.Apps.Entities.Apps
foreach (var permission in forAppWithoutSchemas)
{
if (permission.Length > Permissions.App.Length + 1)
if (permission.Length > PermissionIds.App.Length + 1)
{
var trimmed = permission[(Permissions.App.Length + 1)..];
var trimmed = permission[(PermissionIds.App.Length + 1)..];
if (trimmed.Length > 0)
{
@ -63,7 +63,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
foreach (var permission in forAppSchemas)
{
var trimmed = permission[(Permissions.App.Length + 1)..];
var trimmed = permission[(PermissionIds.App.Length + 1)..];
foreach (var schema in schemaNames)
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsSearchSource.cs

@ -30,7 +30,7 @@ namespace Squidex.Domain.Apps.Entities.Assets
{
var result = new SearchResults();
if (context.UserPermissions.Allows(Permissions.AppAssetsRead, context.App.Name))
if (context.UserPermissions.Allows(PermissionIds.AppAssetsRead, context.App.Name))
{
var filter = ClrFilter.Contains("fileName", query);

6
backend/src/Squidex.Domain.Apps.Entities/Assets/DomainObject/AssetsBulkUpdateCommandMiddleware.cs

@ -180,7 +180,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
{
var command = new AnnotateAsset();
EnrichAndCheckPermission(task, command, Permissions.AppAssetsUpdate);
EnrichAndCheckPermission(task, command, PermissionIds.AppAssetsUpdate);
return command;
}
@ -188,7 +188,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
{
var command = new MoveAsset();
EnrichAndCheckPermission(task, command, Permissions.AppAssetsUpdate);
EnrichAndCheckPermission(task, command, PermissionIds.AppAssetsUpdate);
return command;
}
@ -196,7 +196,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
{
var command = new DeleteAsset();
EnrichAndCheckPermission(task, command, Permissions.AppAssetsDelete);
EnrichAndCheckPermission(task, command, PermissionIds.AppAssetsDelete);
return command;
}

2
backend/src/Squidex.Domain.Apps.Entities/Contents/ContentsSearchSource.cs

@ -88,7 +88,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
private static bool HasPermission(Context context, string schemaName)
{
return context.UserPermissions.Allows(Permissions.AppContentsReadOwn, context.App.Name, schemaName);
return context.UserPermissions.Allows(PermissionIds.AppContentsReadOwn, context.App.Name, schemaName);
}
private static string FormatName(IEnrichedContentEntity content, string masterLanguage)

16
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs

@ -257,7 +257,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private async Task ChangeCore(ChangeContentStatus c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsChangeStatus);
operation.MustHavePermission(PermissionIds.AppContentsChangeStatus);
operation.MustNotChangeSingleton(c.Status);
if (c.Status == Snapshot.EditingStatus())
@ -310,7 +310,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private async Task UpdateCore(UpdateContent c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsUpdate);
operation.MustHavePermission(PermissionIds.AppContentsUpdate);
operation.MustHaveData(c.Data);
if (!c.DoNotValidate)
@ -345,7 +345,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private async Task PatchCore(UpdateContent c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsUpdate);
operation.MustHavePermission(PermissionIds.AppContentsUpdate);
operation.MustHaveData(c.Data);
if (!c.DoNotValidate)
@ -380,7 +380,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private void CancelChangeCore(CancelContentSchedule c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsChangeStatusCancel);
operation.MustHavePermission(PermissionIds.AppContentsChangeStatusCancel);
if (Snapshot.ScheduleJob != null)
{
@ -390,14 +390,14 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private async Task ValidateCore(ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsRead);
operation.MustHavePermission(PermissionIds.AppContentsRead);
await operation.ValidateContentAndInputAsync(Snapshot.Data, false, Snapshot.IsPublished());
}
private async Task CreateDraftCore(CreateContentDraft c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsVersionCreate);
operation.MustHavePermission(PermissionIds.AppContentsVersionCreate);
operation.MustCreateDraft();
var status = await operation.GetInitialStatusAsync();
@ -407,7 +407,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private void DeleteDraftCore(DeleteContentDraft c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsVersionDelete);
operation.MustHavePermission(PermissionIds.AppContentsVersionDelete);
operation.MustDeleteDraft();
DeleteDraft(c);
@ -415,7 +415,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
private async Task DeleteCore(DeleteContent c, ContentOperation operation)
{
operation.MustHavePermission(Permissions.AppContentsDelete);
operation.MustHavePermission(PermissionIds.AppContentsDelete);
operation.MustNotDeleteSingleton();
if (!c.DoNotScript)

14
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentsBulkUpdateCommandMiddleware.cs

@ -207,7 +207,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new CreateContent();
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsCreate);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsCreate);
return command;
}
@ -215,7 +215,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new UpdateContent();
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsUpdateOwn);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsUpdateOwn);
return command;
}
@ -223,7 +223,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new UpsertContent();
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsUpsert);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsUpsert);
return command;
}
@ -231,7 +231,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new PatchContent();
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsUpdateOwn);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsUpdateOwn);
return command;
}
@ -239,7 +239,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new ValidateContent();
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsReadOwn);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsReadOwn);
return command;
}
@ -247,7 +247,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new ChangeContentStatus { Status = job.Status ?? Status.Draft };
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsChangeStatusOwn);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsChangeStatusOwn);
return command;
}
@ -255,7 +255,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var command = new DeleteContent();
await EnrichAndCheckPermissionAsync(task, command, Permissions.AppContentsDeleteOwn);
await EnrichAndCheckPermissionAsync(task, command, PermissionIds.AppContentsDeleteOwn);
return command;
}

2
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/SecurityExtensions.cs

@ -30,7 +30,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
throw new DomainForbiddenException(T.Get("common.errorNoPermission"));
}
var permission = Permissions.ForApp(permissionId, context.App.Name, context.Schema.SchemaDef.Name);
var permission = PermissionIds.ForApp(permissionId, context.App.Name, context.Schema.SchemaDef.Name);
if (!permissions.Allows(permission))
{

12
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentActions.cs

@ -226,7 +226,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents
};
}
public static readonly IFieldResolver Resolver = ResolveAsync(Permissions.AppContentsCreate, c =>
public static readonly IFieldResolver Resolver = ResolveAsync(PermissionIds.AppContentsCreate, c =>
{
var contentId = c.GetArgument<string?>("id");
var contentData = c.GetArgument<ContentData>("data")!;
@ -297,7 +297,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents
};
}
public static readonly IFieldResolver Resolver = ResolveAsync(Permissions.AppContentsUpsert, c =>
public static readonly IFieldResolver Resolver = ResolveAsync(PermissionIds.AppContentsUpsert, c =>
{
var contentId = c.GetArgument<DomainId>("id");
var contentData = c.GetArgument<ContentData>("data")!;
@ -346,7 +346,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents
};
}
public static readonly IFieldResolver Resolver = ResolveAsync(Permissions.AppContentsUpdateOwn, c =>
public static readonly IFieldResolver Resolver = ResolveAsync(PermissionIds.AppContentsUpdateOwn, c =>
{
var contentId = c.GetArgument<DomainId>("id");
var contentData = c.GetArgument<ContentData>("data")!;
@ -382,7 +382,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents
};
}
public static readonly IFieldResolver Resolver = ResolveAsync(Permissions.AppContentsUpdateOwn, c =>
public static readonly IFieldResolver Resolver = ResolveAsync(PermissionIds.AppContentsUpdateOwn, c =>
{
var contentId = c.GetArgument<DomainId>("id");
var contentData = c.GetArgument<ContentData>("data")!;
@ -421,7 +421,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents
}
};
public static readonly IFieldResolver Resolver = ResolveAsync(Permissions.AppContentsChangeStatusOwn, c =>
public static readonly IFieldResolver Resolver = ResolveAsync(PermissionIds.AppContentsChangeStatusOwn, c =>
{
var contentId = c.GetArgument<DomainId>("id");
var contentStatus = c.GetArgument<Status>("status");
@ -449,7 +449,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents
}
};
public static readonly IFieldResolver Resolver = ResolveAsync(Permissions.AppContentsDeleteOwn, c =>
public static readonly IFieldResolver Resolver = ResolveAsync(PermissionIds.AppContentsDeleteOwn, c =>
{
var contentId = c.GetArgument<DomainId>("id");

6
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs

@ -89,7 +89,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
var schema = await GetSchemaOrThrowAsync(context, schemaIdOrName, ct);
if (!HasPermission(context, schema, Permissions.AppContentsRead))
if (!HasPermission(context, schema, PermissionIds.AppContentsRead))
{
q = q with { CreatedBy = context.User.Token() };
}
@ -199,7 +199,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
schema = await appProvider.GetSchemaAsync(context.App.Id, schemaIdOrName, canCache, ct);
}
if (schema != null && !HasPermission(context, schema, Permissions.AppContentsReadOwn))
if (schema != null && !HasPermission(context, schema, PermissionIds.AppContentsReadOwn))
{
throw new DomainForbiddenException(T.Get("schemas.noPermission"));
}
@ -212,7 +212,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var schemas = await appProvider.GetSchemasAsync(context.App.Id, ct);
return schemas.Where(x => IsAccessible(x) && HasPermission(context, x, Permissions.AppContentsReadOwn)).ToList();
return schemas.Where(x => IsAccessible(x) && HasPermission(context, x, PermissionIds.AppContentsReadOwn)).ToList();
}
private async Task<IResultList<IContentEntity>> QueryCoreAsync(Context context, Q q, ISchemaEntity schema,

2
backend/src/Squidex.Domain.Apps.Entities/Context.cs

@ -60,7 +60,7 @@ namespace Squidex.Domain.Apps.Entities
var claimsIdentity = new ClaimsIdentity();
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
claimsIdentity.AddClaim(new Claim(SquidexClaimTypes.Permissions, Permissions.All));
claimsIdentity.AddClaim(new Claim(SquidexClaimTypes.Permissions, PermissionIds.All));
return new Context(claimsPrincipal, app);
}

2
backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemasSearchSource.cs

@ -84,7 +84,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
private static bool HasPermission(Context context, NamedId<DomainId> schemaId)
{
return context.Allows(Permissions.AppContentsReadOwn, schemaId.Name);
return context.Allows(PermissionIds.AppContentsReadOwn, schemaId.Name);
}
}
}

2
backend/src/Squidex.Domain.Users/DefaultUserService.cs

@ -179,7 +179,7 @@ namespace Squidex.Domain.Users
{
var permissions = values.Permissions?.ToIds().ToList() ?? new List<string>();
permissions.Add(Permissions.Admin);
permissions.Add(PermissionIds.Admin);
values.Permissions = new PermissionSet(permissions);
}

2
backend/src/Squidex.Domain.Users/UserClaimsPrincipalFactoryWithEmail.cs

@ -33,7 +33,7 @@ namespace Squidex.Domain.Users
if (await UserManager.IsInRoleAsync(user, AdministratorRole))
{
identity.AddClaim(new Claim(SquidexClaimTypes.Permissions, Permissions.Admin));
identity.AddClaim(new Claim(SquidexClaimTypes.Permissions, PermissionIds.Admin));
}
return principal;

2
backend/src/Squidex.Shared/Identity/SquidexClaimTypes.cs

@ -32,5 +32,7 @@ namespace Squidex.Shared.Identity
public const string PictureUrlStore = "store";
public const string TotalApps = "urn:squidex:internal:totalApps";
public const string UIPrefix = "urn:squidex:custom";
}
}

23
backend/src/Squidex.Shared/Identity/SquidexClaimsExtensions.cs

@ -106,13 +106,32 @@ namespace Squidex.Shared.Identity
public static IEnumerable<(string Name, string Value)> GetCustomProperties(this IEnumerable<Claim> user)
{
var prefix = SquidexClaimTypes.CustomPrefix;
foreach (var claim in user)
{
var type = GetType(claim);
if (type.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
var name = type[(prefix.Length + 1)..].ToString();
yield return (name, claim.Value);
}
}
}
public static IEnumerable<(string Name, string Value)> GetUIProperties(this IEnumerable<Claim> user, string app)
{
var prefix = $"{SquidexClaimTypes.UIPrefix}:{app}";
foreach (var claim in user)
{
var type = GetType(claim);
if (type.StartsWith(SquidexClaimTypes.CustomPrefix, StringComparison.OrdinalIgnoreCase))
if (type.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
var name = type[(SquidexClaimTypes.CustomPrefix.Length + 1)..].ToString();
var name = type[(prefix.Length + 1)..].ToString();
yield return (name, claim.Value);
}

2
backend/src/Squidex.Shared/PermissionExtensions.cs

@ -14,7 +14,7 @@ namespace Squidex.Shared
{
public static bool Allows(this PermissionSet permissions, string id, string app = Permission.Any, string schema = Permission.Any)
{
var permission = Permissions.ForApp(id, app, schema);
var permission = PermissionIds.ForApp(id, app, schema);
return permissions.Allows(permission);
}

9
backend/src/Squidex.Shared/Permissions.cs → backend/src/Squidex.Shared/PermissionIds.cs

@ -11,7 +11,7 @@ using Squidex.Infrastructure.Security;
namespace Squidex.Shared
{
public static class Permissions
public static class PermissionIds
{
public const string All = "squidex.*";
@ -173,9 +173,10 @@ namespace Squidex.Shared
{
Guard.NotNull(id);
return new Permission(id
.Replace("{app}", app ?? Permission.Any, StringComparison.Ordinal)
.Replace("{schema}", schema ?? Permission.Any, StringComparison.Ordinal));
id = id.Replace("{app}", app ?? Permission.Any, StringComparison.Ordinal);
id = id.Replace("{schema}", schema ?? Permission.Any, StringComparison.Ordinal);
return new Permission(id);
}
}
}

2
backend/src/Squidex.Web/Pipeline/ApiPermissionUnifier.cs

@ -22,7 +22,7 @@ namespace Squidex.Web.Pipeline
if (string.Equals(identity.FindFirst(identity.RoleClaimType)?.Value, AdministratorRole, StringComparison.OrdinalIgnoreCase))
{
identity.AddClaim(new Claim(SquidexClaimTypes.Permissions, Permissions.Admin));
identity.AddClaim(new Claim(SquidexClaimTypes.Permissions, PermissionIds.Admin));
}
return Task.FromResult(principal);

14
backend/src/Squidex.Web/Pipeline/AppResolver.cs

@ -145,7 +145,7 @@ namespace Squidex.Web.Pipeline
private static bool HasPermission(string appName, Context requestContext)
{
return requestContext.UserPermissions.Includes(Permissions.ForApp(Permissions.App, appName));
return requestContext.UserPermissions.Includes(PermissionIds.ForApp(PermissionIds.App, appName));
}
private static bool AllowAnonymous(ActionExecutingContext context)
@ -162,9 +162,9 @@ namespace Squidex.Web.Pipeline
return default;
}
if (app.Clients.TryGetValue(clientId, out var client) && app.Roles.TryGet(app.Name, client.Role, isFrontend, out var role))
if (app.TryGetClientRole(clientId, isFrontend, out var role))
{
return (clientId, client.Role, role.Permissions);
return (clientId, role.Name, role.Permissions);
}
return default;
@ -179,9 +179,9 @@ namespace Squidex.Web.Pipeline
return default;
}
if (app.Roles.TryGet(app.Name, client.Value.Role, isFrontend, out var role))
if (app.TryGetRole(client.Value.Role, isFrontend, out var role))
{
return (client.Key, client.Value.Role, role.Permissions);
return (client.Key, role.Name, role.Permissions);
}
return default;
@ -196,9 +196,9 @@ namespace Squidex.Web.Pipeline
return default;
}
if (app.Contributors.TryGetValue(subjectId, out var roleName) && app.Roles.TryGet(app.Name, roleName, isFrontend, out var role))
if (app.TryGetContributorRole(subjectId, isFrontend, out var role))
{
return (roleName, role.Permissions);
return (role.Name, role.Permissions);
}
return default;

108
backend/src/Squidex.Web/Resources.cs

@ -17,123 +17,123 @@ namespace Squidex.Web
private readonly Dictionary<(string Id, string Schema), bool> permissions = new Dictionary<(string, string), bool>();
// Contents
public bool CanReadContent(string schema) => Can(Permissions.AppContentsReadOwn, schema);
public bool CanReadContent(string schema) => Can(PermissionIds.AppContentsReadOwn, schema);
public bool CanCreateContent(string schema) => Can(Permissions.AppContentsCreate, schema);
public bool CanCreateContent(string schema) => Can(PermissionIds.AppContentsCreate, schema);
public bool CanCreateContentVersion(string schema) => Can(Permissions.AppContentsVersionCreateOwn, schema);
public bool CanCreateContentVersion(string schema) => Can(PermissionIds.AppContentsVersionCreateOwn, schema);
public bool CanDeleteContent(string schema) => Can(Permissions.AppContentsDeleteOwn, schema);
public bool CanDeleteContent(string schema) => Can(PermissionIds.AppContentsDeleteOwn, schema);
public bool CanDeleteContentVersion(string schema) => Can(Permissions.AppContentsVersionDeleteOwn, schema);
public bool CanDeleteContentVersion(string schema) => Can(PermissionIds.AppContentsVersionDeleteOwn, schema);
public bool CanChangeStatus(string schema) => Can(Permissions.AppContentsChangeStatus, schema);
public bool CanChangeStatus(string schema) => Can(PermissionIds.AppContentsChangeStatus, schema);
public bool CanCancelContentStatus(string schema) => Can(Permissions.AppContentsChangeStatusCancelOwn, schema);
public bool CanCancelContentStatus(string schema) => Can(PermissionIds.AppContentsChangeStatusCancelOwn, schema);
public bool CanUpdateContent(string schema) => Can(Permissions.AppContentsUpdateOwn, schema);
public bool CanUpdateContent(string schema) => Can(PermissionIds.AppContentsUpdateOwn, schema);
// Schemas
public bool CanUpdateSchema(string schema) => Can(Permissions.AppSchemasDelete, schema);
public bool CanUpdateSchema(string schema) => Can(PermissionIds.AppSchemasDelete, schema);
public bool CanUpdateSchemaScripts(string schema) => Can(Permissions.AppSchemasScripts, schema);
public bool CanUpdateSchemaScripts(string schema) => Can(PermissionIds.AppSchemasScripts, schema);
public bool CanPublishSchema(string schema) => Can(Permissions.AppSchemasPublish, schema);
public bool CanPublishSchema(string schema) => Can(PermissionIds.AppSchemasPublish, schema);
public bool CanDeleteSchema(string schema) => Can(Permissions.AppSchemasDelete, schema);
public bool CanDeleteSchema(string schema) => Can(PermissionIds.AppSchemasDelete, schema);
public bool CanCreateSchema => Can(Permissions.AppSchemasCreate);
public bool CanCreateSchema => Can(PermissionIds.AppSchemasCreate);
public bool CanUpdateSettings => Can(Permissions.AppUpdateSettings);
public bool CanUpdateSettings => Can(PermissionIds.AppUpdateSettings);
// Asset Scripts
public bool CanUpdateAssetsScripts => Can(Permissions.AppAssetsScriptsUpdate);
public bool CanUpdateAssetsScripts => Can(PermissionIds.AppAssetsScriptsUpdate);
// Contributors
public bool CanAssignContributor => Can(Permissions.AppContributorsAssign);
public bool CanAssignContributor => Can(PermissionIds.AppContributorsAssign);
public bool CanRevokeContributor => Can(Permissions.AppContributorsRevoke);
public bool CanRevokeContributor => Can(PermissionIds.AppContributorsRevoke);
// Workflows
public bool CanCreateWorkflow => Can(Permissions.AppWorkflowsCreate);
public bool CanCreateWorkflow => Can(PermissionIds.AppWorkflowsCreate);
public bool CanUpdateWorkflow => Can(Permissions.AppWorkflowsUpdate);
public bool CanUpdateWorkflow => Can(PermissionIds.AppWorkflowsUpdate);
public bool CanDeleteWorkflow => Can(Permissions.AppWorkflowsDelete);
public bool CanDeleteWorkflow => Can(PermissionIds.AppWorkflowsDelete);
// Roles
public bool CanCreateRole => Can(Permissions.AppRolesCreate);
public bool CanCreateRole => Can(PermissionIds.AppRolesCreate);
public bool CanUpdateRole => Can(Permissions.AppRolesUpdate);
public bool CanUpdateRole => Can(PermissionIds.AppRolesUpdate);
public bool CanDeleteRole => Can(Permissions.AppRolesDelete);
public bool CanDeleteRole => Can(PermissionIds.AppRolesDelete);
// Languages
public bool CanCreateLanguage => Can(Permissions.AppLanguagesCreate);
public bool CanCreateLanguage => Can(PermissionIds.AppLanguagesCreate);
public bool CanUpdateLanguage => Can(Permissions.AppLanguagesUpdate);
public bool CanUpdateLanguage => Can(PermissionIds.AppLanguagesUpdate);
public bool CanDeleteLanguage => Can(Permissions.AppLanguagesDelete);
public bool CanDeleteLanguage => Can(PermissionIds.AppLanguagesDelete);
// Clients
public bool CanCreateClient => Can(Permissions.AppClientsCreate);
public bool CanCreateClient => Can(PermissionIds.AppClientsCreate);
public bool CanUpdateClient => Can(Permissions.AppClientsUpdate);
public bool CanUpdateClient => Can(PermissionIds.AppClientsUpdate);
public bool CanDeleteClient => Can(Permissions.AppClientsDelete);
public bool CanDeleteClient => Can(PermissionIds.AppClientsDelete);
// Rules
public bool CanDisableRule => Can(Permissions.AppRulesDisable);
public bool CanDisableRule => Can(PermissionIds.AppRulesDisable);
public bool CanCreateRule => Can(Permissions.AppRulesCreate);
public bool CanCreateRule => Can(PermissionIds.AppRulesCreate);
public bool CanUpdateRule => Can(Permissions.AppRulesUpdate);
public bool CanUpdateRule => Can(PermissionIds.AppRulesUpdate);
public bool CanDeleteRule => Can(Permissions.AppRulesDelete);
public bool CanDeleteRule => Can(PermissionIds.AppRulesDelete);
public bool CanReadRuleEvents => Can(Permissions.AppRulesEventsRead);
public bool CanReadRuleEvents => Can(PermissionIds.AppRulesEventsRead);
public bool CanUpdateRuleEvents => Can(Permissions.AppRulesEventsUpdate);
public bool CanUpdateRuleEvents => Can(PermissionIds.AppRulesEventsUpdate);
public bool CanRunRuleEvents => Can(Permissions.AppRulesEventsRun);
public bool CanRunRuleEvents => Can(PermissionIds.AppRulesEventsRun);
public bool CanDeleteRuleEvents => Can(Permissions.AppRulesEventsDelete);
public bool CanDeleteRuleEvents => Can(PermissionIds.AppRulesEventsDelete);
// Users
public bool CanReadUsers => Can(Permissions.AdminUsersRead);
public bool CanReadUsers => Can(PermissionIds.AdminUsersRead);
public bool CanCreateUser => Can(Permissions.AdminUsersCreate);
public bool CanCreateUser => Can(PermissionIds.AdminUsersCreate);
public bool CanLockUser => Can(Permissions.AdminUsersLock);
public bool CanLockUser => Can(PermissionIds.AdminUsersLock);
public bool CanUnlockUser => Can(Permissions.AdminUsersUnlock);
public bool CanUnlockUser => Can(PermissionIds.AdminUsersUnlock);
public bool CanUpdateUser => Can(Permissions.AdminUsersUpdate);
public bool CanUpdateUser => Can(PermissionIds.AdminUsersUpdate);
// Assets
public bool CanUploadAsset => Can(Permissions.AppAssetsUpload);
public bool CanUploadAsset => Can(PermissionIds.AppAssetsUpload);
public bool CanCreateAsset => Can(Permissions.AppAssetsCreate);
public bool CanCreateAsset => Can(PermissionIds.AppAssetsCreate);
public bool CanDeleteAsset => Can(Permissions.AppAssetsDelete);
public bool CanDeleteAsset => Can(PermissionIds.AppAssetsDelete);
public bool CanUpdateAsset => Can(Permissions.AppAssetsUpdate);
public bool CanUpdateAsset => Can(PermissionIds.AppAssetsUpdate);
public bool CanReadAssets => Can(Permissions.AppAssetsRead);
public bool CanReadAssets => Can(PermissionIds.AppAssetsRead);
// Events
public bool CanReadEvents => Can(Permissions.AdminEventsRead);
public bool CanReadEvents => Can(PermissionIds.AdminEventsRead);
public bool CanManageEvents => Can(Permissions.AdminEventsManage);
public bool CanManageEvents => Can(PermissionIds.AdminEventsManage);
// Backups
public bool CanRestoreBackup => Can(Permissions.AdminRestore);
public bool CanRestoreBackup => Can(PermissionIds.AdminRestore);
public bool CanCreateBackup => Can(Permissions.AppBackupsCreate);
public bool CanCreateBackup => Can(PermissionIds.AppBackupsCreate);
public bool CanDeleteBackup => Can(Permissions.AppBackupsDelete);
public bool CanDeleteBackup => Can(PermissionIds.AppBackupsDelete);
public bool CanDownloadBackup => Can(Permissions.AppBackupsDownload);
public bool CanDownloadBackup => Can(PermissionIds.AppBackupsDownload);
public Context Context { get; set; }
@ -209,7 +209,7 @@ namespace Squidex.Web
}
}
var permission = Permissions.ForApp(id, app, schema);
var permission = PermissionIds.ForApp(id, app, schema);
return Context.UserPermissions.Allows(permission) || additional?.Allows(permission) == true;
}

4
backend/src/Squidex/Areas/Api/Controllers/Apps/AppAssetsController.cs

@ -36,7 +36,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/assets/scripts")]
[ProducesResponseType(typeof(AssetScriptsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetSScriptsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetSScriptsRead)]
[ApiCosts(0)]
public IActionResult GetAssetScripts(string app)
{
@ -61,7 +61,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/assets/scripts")]
[ProducesResponseType(typeof(AssetScriptsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsScriptsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsScriptsUpdate)]
[ApiCosts(0)]
public async Task<IActionResult> PutAssetScripts(string app, [FromBody] UpdateAssetScriptsDto request)
{

8
backend/src/Squidex/Areas/Api/Controllers/Apps/AppClientsController.cs

@ -41,7 +41,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/clients/")]
[ProducesResponseType(typeof(ClientsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppClientsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppClientsRead)]
[ApiCosts(0)]
public IActionResult GetClients(string app)
{
@ -72,7 +72,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPost]
[Route("apps/{app}/clients/")]
[ProducesResponseType(typeof(ClientsDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppClientsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppClientsCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostClient(string app, [FromBody] CreateClientDto request)
{
@ -100,7 +100,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/clients/{id}/")]
[ProducesResponseType(typeof(ClientsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppClientsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppClientsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutClient(string app, string id, [FromBody] UpdateClientDto request)
{
@ -126,7 +126,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpDelete]
[Route("apps/{app}/clients/{id}/")]
[ProducesResponseType(typeof(ClientsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppClientsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppClientsDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteClient(string app, string id)
{

6
backend/src/Squidex/Areas/Api/Controllers/Apps/AppContributorsController.cs

@ -50,7 +50,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/contributors/")]
[ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContributorsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppContributorsRead)]
[ApiCosts(0)]
public IActionResult GetContributors(string app)
{
@ -77,7 +77,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPost]
[Route("apps/{app}/contributors/")]
[ProducesResponseType(typeof(ContributorsDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppContributorsAssign)]
[ApiPermissionOrAnonymous(PermissionIds.AppContributorsAssign)]
[ApiCosts(1)]
public async Task<IActionResult> PostContributor(string app, [FromBody] AssignContributorDto request)
{
@ -122,7 +122,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpDelete]
[Route("apps/{app}/contributors/{id}/")]
[ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContributorsRevoke)]
[ApiPermissionOrAnonymous(PermissionIds.AppContributorsRevoke)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteContributor(string app, string id)
{

8
backend/src/Squidex/Areas/Api/Controllers/Apps/AppLanguagesController.cs

@ -39,7 +39,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/languages/")]
[ProducesResponseType(typeof(AppLanguagesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppLanguagesRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppLanguagesRead)]
[ApiCosts(0)]
public IActionResult GetLanguages(string app)
{
@ -66,7 +66,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPost]
[Route("apps/{app}/languages/")]
[ProducesResponseType(typeof(AppLanguagesDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppLanguagesCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppLanguagesCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostLanguage(string app, [FromBody] AddLanguageDto request)
{
@ -91,7 +91,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/languages/{language}/")]
[ProducesResponseType(typeof(AppLanguagesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppLanguagesUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppLanguagesUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutLanguage(string app, string language, [FromBody] UpdateLanguageDto request)
{
@ -115,7 +115,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpDelete]
[Route("apps/{app}/languages/{language}/")]
[ProducesResponseType(typeof(AppLanguagesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppLanguagesDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppLanguagesDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteLanguage(string app, string language)
{

10
backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs

@ -42,7 +42,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/roles/")]
[ProducesResponseType(typeof(RolesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRolesRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppRolesRead)]
[ApiCosts(0)]
public IActionResult GetRoles(string app)
{
@ -67,7 +67,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/roles/permissions")]
[ProducesResponseType(typeof(string[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRolesRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppRolesRead)]
[ApiCosts(0)]
public IActionResult GetPermissions(string app)
{
@ -94,7 +94,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPost]
[Route("apps/{app}/roles/")]
[ProducesResponseType(typeof(RolesDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppRolesCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppRolesCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostRole(string app, [FromBody] AddRoleDto request)
{
@ -119,7 +119,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/roles/{roleName}/")]
[ProducesResponseType(typeof(RolesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRolesUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppRolesUpdate)]
[ApiCosts(1)]
[UrlDecodeRouteParams]
public async Task<IActionResult> PutRole(string app, string roleName, [FromBody] UpdateRoleDto request)
@ -144,7 +144,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpDelete]
[Route("apps/{app}/roles/{roleName}/")]
[ProducesResponseType(typeof(RolesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRolesDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppRolesDelete)]
[ApiCosts(1)]
[UrlDecodeRouteParams]
public async Task<IActionResult> DeleteRole(string app, string roleName)

2
backend/src/Squidex/Areas/Api/Controllers/Apps/AppSettingsController.cs

@ -61,7 +61,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/settings")]
[ProducesResponseType(typeof(AppSettingsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppUpdateSettings)]
[ApiPermissionOrAnonymous(PermissionIds.AppUpdateSettings)]
[ApiCosts(0)]
public async Task<IActionResult> PutSettings(string app, [FromBody] UpdateAppSettingsDto request)
{

8
backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs

@ -43,7 +43,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpGet]
[Route("apps/{app}/workflows/")]
[ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppWorkflowsRead)]
[ApiCosts(0)]
public IActionResult GetWorkflows(string app)
{
@ -70,7 +70,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPost]
[Route("apps/{app}/workflows/")]
[ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppWorkflowsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PostWorkflow(string app, [FromBody] AddWorkflowDto request)
{
@ -95,7 +95,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/workflows/{id}")]
[ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppWorkflowsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutWorkflow(string app, DomainId id, [FromBody] UpdateWorkflowDto request)
{
@ -118,7 +118,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpDelete]
[Route("apps/{app}/workflows/{id}")]
[ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppWorkflowsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteWorkflow(string app, DomainId id)
{

8
backend/src/Squidex/Areas/Api/Controllers/Apps/AppsController.cs

@ -135,7 +135,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPut]
[Route("apps/{app}/")]
[ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppUpdate)]
[ApiCosts(0)]
public async Task<IActionResult> PutApp(string app, [FromBody] UpdateAppDto request)
{
@ -157,7 +157,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpPost]
[Route("apps/{app}/image")]
[ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppImageUpload)]
[ApiPermissionOrAnonymous(PermissionIds.AppImageUpload)]
[ApiCosts(0)]
public async Task<IActionResult> UploadImage(string app, IFormFile file)
{
@ -177,7 +177,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[HttpDelete]
[Route("apps/{app}/image")]
[ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppImageDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppImageDelete)]
[ApiCosts(0)]
public async Task<IActionResult> DeleteImage(string app)
{
@ -196,7 +196,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
/// </returns>
[HttpDelete]
[Route("apps/{app}/")]
[ApiPermission(Permissions.AppDelete)]
[ApiPermission(PermissionIds.AppDelete)]
[ApiCosts(0)]
public async Task<IActionResult> DeleteApp(string app)
{

53
backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs

@ -18,6 +18,8 @@ using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Security;
using Squidex.Infrastructure.Validation;
using Squidex.Shared;
using Squidex.Shared.Identity;
using Squidex.Web;
#pragma warning disable RECS0033 // Convert 'if' to '||' expression
@ -88,7 +90,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
/// The properties from the role.
/// </summary>
[LocalizedRequired]
public JsonValue RoleProperties { get; set; }
public JsonObject RoleProperties { get; set; }
public static AppDto FromDomain(IAppEntity app, string userId, bool isFrontend, Resources resources)
{
@ -98,19 +100,19 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
var isContributor = false;
if (app.Contributors.TryGetValue(userId, out var roleName) && app.Roles.TryGet(app.Name, roleName, isFrontend, out var role))
if (app.TryGetContributorRole(userId, isFrontend, out var role))
{
isContributor = true;
result.RoleName = roleName;
result.RoleName = role.Name;
result.RoleProperties = role.Properties;
result.Permissions = permissions.ToIds();
permissions = role.Permissions;
}
else if (app.Clients.TryGetValue(userId, out var client) && app.Roles.TryGet(app.Name, client.Role, isFrontend, out role))
else if (app.TryGetClientRole(userId, isFrontend, out role))
{
result.RoleName = roleName;
result.RoleName = role.Name;
result.RoleProperties = role.Properties;
result.Permissions = permissions.ToIds();
@ -121,7 +123,12 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
result.RoleProperties = new JsonObject();
}
if (resources.Includes(Shared.Permissions.ForApp(Shared.Permissions.AppContents, app.Name), permissions))
foreach (var (key, value) in resources.Context.User.Claims.GetUIProperties(app.Name))
{
result.RoleProperties[key] = JsonValue.Create(value);
}
if (resources.Includes(PermissionIds.ForApp(PermissionIds.AppContents, app.Name), permissions))
{
result.CanAccessContent = true;
}
@ -148,103 +155,103 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
resources.Url<AppContributorsController>(x => nameof(x.DeleteMyself), values));
}
if (resources.IsAllowed(Shared.Permissions.AppDelete, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppDelete, Name, additional: permissions))
{
AddDeleteLink("delete",
resources.Url<AppsController>(x => nameof(x.DeleteApp), values));
}
if (resources.IsAllowed(Shared.Permissions.AppUpdate, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppUpdate, Name, additional: permissions))
{
AddPutLink("update",
resources.Url<AppsController>(x => nameof(x.PutApp), values));
}
if (resources.IsAllowed(Shared.Permissions.AppAssetsRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppAssetsRead, Name, additional: permissions))
{
AddGetLink("assets",
resources.Url<AssetsController>(x => nameof(x.GetAssets), values));
}
if (resources.IsAllowed(Shared.Permissions.AppBackupsRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppBackupsRead, Name, additional: permissions))
{
AddGetLink("backups",
resources.Url<BackupsController>(x => nameof(x.GetBackups), values));
}
if (resources.IsAllowed(Shared.Permissions.AppClientsRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppClientsRead, Name, additional: permissions))
{
AddGetLink("clients",
resources.Url<AppClientsController>(x => nameof(x.GetClients), values));
}
if (resources.IsAllowed(Shared.Permissions.AppContributorsRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppContributorsRead, Name, additional: permissions))
{
AddGetLink("contributors",
resources.Url<AppContributorsController>(x => nameof(x.GetContributors), values));
}
if (resources.IsAllowed(Shared.Permissions.AppLanguagesRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppLanguagesRead, Name, additional: permissions))
{
AddGetLink("languages",
resources.Url<AppLanguagesController>(x => nameof(x.GetLanguages), values));
}
if (resources.IsAllowed(Shared.Permissions.AppPlansRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppPlansRead, Name, additional: permissions))
{
AddGetLink("plans",
resources.Url<AppPlansController>(x => nameof(x.GetPlans), values));
}
if (resources.IsAllowed(Shared.Permissions.AppRolesRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppRolesRead, Name, additional: permissions))
{
AddGetLink("roles",
resources.Url<AppRolesController>(x => nameof(x.GetRoles), values));
}
if (resources.IsAllowed(Shared.Permissions.AppRulesRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppRulesRead, Name, additional: permissions))
{
AddGetLink("rules",
resources.Url<RulesController>(x => nameof(x.GetRules), values));
}
if (resources.IsAllowed(Shared.Permissions.AppSchemasRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppSchemasRead, Name, additional: permissions))
{
AddGetLink("schemas",
resources.Url<SchemasController>(x => nameof(x.GetSchemas), values));
}
if (resources.IsAllowed(Shared.Permissions.AppWorkflowsRead, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppWorkflowsRead, Name, additional: permissions))
{
AddGetLink("workflows",
resources.Url<AppWorkflowsController>(x => nameof(x.GetWorkflows), values));
}
if (resources.IsAllowed(Shared.Permissions.AppSchemasCreate, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppSchemasCreate, Name, additional: permissions))
{
AddPostLink("schemas/create",
resources.Url<SchemasController>(x => nameof(x.PostSchema), values));
}
if (resources.IsAllowed(Shared.Permissions.AppAssetsCreate, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppAssetsCreate, Name, additional: permissions))
{
AddPostLink("assets/create",
resources.Url<SchemasController>(x => nameof(x.PostSchema), values));
}
if (resources.IsAllowed(Shared.Permissions.AppImageUpload, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppImageUpload, Name, additional: permissions))
{
AddPostLink("image/upload",
resources.Url<AppsController>(x => nameof(x.UploadImage), values));
}
if (resources.IsAllowed(Shared.Permissions.AppImageDelete, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppImageDelete, Name, additional: permissions))
{
AddDeleteLink("image/delete",
resources.Url<AppsController>(x => nameof(x.DeleteImage), values));
}
if (resources.IsAllowed(Shared.Permissions.AppAssetsScriptsUpdate, Name, additional: permissions))
if (resources.IsAllowed(PermissionIds.AppAssetsScriptsUpdate, Name, additional: permissions))
{
AddDeleteLink("assets/scripts",
resources.Url<AppAssetsController>(x => nameof(x.GetAssetScripts), values));

10
backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs

@ -49,7 +49,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpGet]
[Route("apps/{app}/assets/folders", Order = -1)]
[ProducesResponseType(typeof(AssetFoldersDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)]
[ApiCosts(1)]
public async Task<IActionResult> GetAssetFolders(string app, [FromQuery] DomainId parentId, [FromQuery] AssetFolderScope scope = AssetFolderScope.PathAndItems)
{
@ -81,7 +81,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/folders", Order = -1)]
[ProducesResponseType(typeof(AssetFolderDto), 201)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PostAssetFolder(string app, [FromBody] CreateAssetFolderDto request)
{
@ -107,7 +107,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/folders/{id}/", Order = -1)]
[ProducesResponseType(typeof(AssetFolderDto), StatusCodes.Status200OK)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutAssetFolder(string app, DomainId id, [FromBody] RenameAssetFolderDto request)
{
@ -133,7 +133,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/folders/{id}/parent", Order = -1)]
[ProducesResponseType(typeof(AssetFolderDto), StatusCodes.Status200OK)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutAssetFolderParent(string app, DomainId id, [FromBody] MoveAssetFolderDto request)
{
@ -155,7 +155,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
/// </returns>
[HttpDelete]
[Route("apps/{app}/assets/folders/{id}/", Order = -1)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteAssetFolder(string app, DomainId id)
{

26
backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs

@ -68,7 +68,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpGet]
[Route("apps/{app}/assets/tags")]
[ProducesResponseType(typeof(Dictionary<string, int>), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)]
[ApiCosts(1)]
public async Task<IActionResult> GetTags(string app)
{
@ -92,7 +92,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpPut]
[Route("apps/{app}/assets/tags/{name}")]
[ProducesResponseType(typeof(Dictionary<string, int>), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutTag(string app, string name, [FromBody] RenameTagDto request)
{
@ -118,7 +118,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpGet]
[Route("apps/{app}/assets/")]
[ProducesResponseType(typeof(AssetsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)]
[ApiCosts(1)]
public async Task<IActionResult> GetAssets(string app, [FromQuery] DomainId? parentId, [FromQuery] string? ids = null, [FromQuery] string? q = null)
{
@ -147,7 +147,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpPost]
[Route("apps/{app}/assets/query")]
[ProducesResponseType(typeof(AssetsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)]
[ApiCosts(1)]
public async Task<IActionResult> GetAssetsPost(string app, [FromBody] QueryDto query)
{
@ -173,7 +173,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpGet]
[Route("apps/{app}/assets/{id}/")]
[ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)]
[ApiCosts(1)]
public async Task<IActionResult> GetAsset(string app, DomainId id)
{
@ -210,7 +210,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/")]
[ProducesResponseType(typeof(AssetDto), 201)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostAsset(string app, CreateAssetDto request)
{
@ -238,7 +238,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/tus/{**fileId}")]
[ProducesResponseType(typeof(AssetDto), 201)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostAssetTus(string app)
{
@ -271,7 +271,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[HttpPost]
[Route("apps/{app}/assets/bulk")]
[ProducesResponseType(typeof(BulkResultDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)]
[ApiCosts(5)]
public async Task<IActionResult> BulkUpdateAssets(string app, [FromBody] BulkUpdateAssetsDto request)
{
@ -304,7 +304,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/{id}")]
[ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostUpsertAsset(string app, DomainId id, UpsertAssetDto request)
{
@ -334,7 +334,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/{id}/content/")]
[ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpload)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpload)]
[ApiCosts(1)]
public async Task<IActionResult> PutAssetContent(string app, DomainId id, IFormFile file)
{
@ -360,7 +360,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/{id}/")]
[ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutAsset(string app, DomainId id, [FromBody] AnnotateAssetDto request)
{
@ -386,7 +386,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/{id}/parent")]
[ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)]
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutAssetParent(string app, DomainId id, [FromBody] MoveAssetDto request)
{
@ -409,7 +409,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
/// </returns>
[HttpDelete]
[Route("apps/{app}/assets/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppAssetsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppAssetsDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteAsset(string app, DomainId id, DeleteAssetDto request)
{

6
backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs

@ -41,7 +41,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[HttpGet]
[Route("apps/{app}/backups/")]
[ProducesResponseType(typeof(BackupJobsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppBackupsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppBackupsRead)]
[ApiCosts(0)]
public async Task<IActionResult> GetBackups(string app)
{
@ -64,7 +64,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[HttpPost]
[Route("apps/{app}/backups/")]
[ProducesResponseType(typeof(BackupJobDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppBackupsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppBackupsCreate)]
[ApiCosts(0)]
public async Task<IActionResult> PostBackup(string app)
{
@ -85,7 +85,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[HttpDelete]
[Route("apps/{app}/backups/{id}")]
[ProducesResponseType(typeof(BackupJobDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppBackupsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppBackupsDelete)]
[ApiCosts(0)]
public async Task<IActionResult> DeleteBackup(string app, DomainId id)
{

4
backend/src/Squidex/Areas/Api/Controllers/Backups/RestoreController.cs

@ -39,7 +39,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[HttpGet]
[Route("apps/restore/")]
[ProducesResponseType(typeof(RestoreJobDto), StatusCodes.Status200OK)]
[ApiPermission(Permissions.AdminRestore)]
[ApiPermission(PermissionIds.AdminRestore)]
public async Task<IActionResult> GetRestoreJob()
{
var job = await backupService.GetRestoreAsync(HttpContext.RequestAborted);
@ -63,7 +63,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
/// </returns>
[HttpPost]
[Route("apps/restore/")]
[ApiPermission(Permissions.AdminRestore)]
[ApiPermission(PermissionIds.AdminRestore)]
public async Task<IActionResult> PostRestoreJob([FromBody] RestoreRequestDto request)
{
await backupService.StartRestoreAsync(User.Token()!, request.Url, request.Name);

8
backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs

@ -75,7 +75,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
[HttpGet]
[Route("apps/{app}/comments/{commentsId}")]
[ProducesResponseType(typeof(CommentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppCommentsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppCommentsRead)]
[ApiCosts(0)]
public async Task<IActionResult> GetComments(string app, DomainId commentsId, [FromQuery] long version = EtagVersion.Any)
{
@ -105,7 +105,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
[HttpPost]
[Route("apps/{app}/comments/{commentsId}")]
[ProducesResponseType(typeof(CommentDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppCommentsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppCommentsCreate)]
[ApiCosts(0)]
public async Task<IActionResult> PostComment(string app, DomainId commentsId, [FromBody] UpsertCommentDto request)
{
@ -132,7 +132,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
/// </returns>
[HttpPut]
[Route("apps/{app}/comments/{commentsId}/{commentId}")]
[ApiPermissionOrAnonymous(Permissions.AppCommentsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppCommentsUpdate)]
[ApiCosts(0)]
public async Task<IActionResult> PutComment(string app, DomainId commentsId, DomainId commentId, [FromBody] UpsertCommentDto request)
{
@ -155,7 +155,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
/// </returns>
[HttpDelete]
[Route("apps/{app}/comments/{commentsId}/{commentId}")]
[ApiPermissionOrAnonymous(Permissions.AppCommentsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppCommentsDelete)]
[ApiCosts(0)]
public async Task<IActionResult> DeleteComment(string app, DomainId commentsId, DomainId commentId)
{

24
backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs

@ -319,7 +319,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
/// </remarks>
[HttpGet]
[Route("content/{app}/{schema}/{id}/{version}/")]
[ApiPermissionOrAnonymous(Permissions.AppContentsReadOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsReadOwn)]
[ApiCosts(1)]
public async Task<IActionResult> GetContentVersion(string app, string schema, DomainId id, int version)
{
@ -352,7 +352,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPost]
[Route("content/{app}/{schema}/")]
[ProducesResponseType(typeof(ContentsDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppContentsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostContent(string app, string schema, CreateContentDto request)
{
@ -380,7 +380,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPost]
[Route("content/{app}/{schema}/import")]
[ProducesResponseType(typeof(BulkResultDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsCreate)]
[ApiCosts(5)]
[Obsolete("Use bulk endpoint now.")]
public async Task<IActionResult> PostContents(string app, string schema, [FromBody] ImportContentsDto request)
@ -412,7 +412,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPost]
[Route("content/{app}/{schema}/bulk")]
[ProducesResponseType(typeof(BulkResultDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsReadOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsReadOwn)]
[ApiCosts(5)]
public async Task<IActionResult> BulkUpdateContents(string app, string schema, [FromBody] BulkUpdateContentsDto request)
{
@ -444,7 +444,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPost]
[Route("content/{app}/{schema}/{id}/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpsert)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsUpsert)]
[ApiCosts(1)]
public async Task<IActionResult> PostUpsertContent(string app, string schema, DomainId id, UpsertContentDto request)
{
@ -473,7 +473,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPut]
[Route("content/{app}/{schema}/{id}/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdateOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsUpdateOwn)]
[ApiCosts(1)]
public async Task<IActionResult> PutContent(string app, string schema, DomainId id, [FromBody] ContentData request)
{
@ -502,7 +502,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPatch]
[Route("content/{app}/{schema}/{id}/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdateOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsUpdateOwn)]
[ApiCosts(1)]
public async Task<IActionResult> PatchContent(string app, string schema, DomainId id, [FromBody] ContentData request)
{
@ -531,7 +531,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPut]
[Route("content/{app}/{schema}/{id}/status/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsChangeStatusOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsChangeStatusOwn)]
[ApiCosts(1)]
public async Task<IActionResult> PutContentStatus(string app, string schema, DomainId id, [FromBody] ChangeStatusDto request)
{
@ -559,7 +559,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpDelete]
[Route("content/{app}/{schema}/{id}/status/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsChangeStatusOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsChangeStatusOwn)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteContentStatus(string app, string schema, DomainId id)
{
@ -586,7 +586,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpPost]
[Route("content/{app}/{schema}/{id}/draft/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsVersionCreateOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsVersionCreateOwn)]
[ApiCosts(1)]
public async Task<IActionResult> CreateDraft(string app, string schema, DomainId id)
{
@ -613,7 +613,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[HttpDelete]
[Route("content/{app}/{schema}/{id}/draft/")]
[ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppContentsVersionDeleteOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsVersionDeleteOwn)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteVersion(string app, string schema, DomainId id)
{
@ -641,7 +641,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
/// </remarks>
[HttpDelete]
[Route("content/{app}/{schema}/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppContentsDeleteOwn)]
[ApiPermissionOrAnonymous(PermissionIds.AppContentsDeleteOwn)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteContent(string app, string schema, DomainId id, DeleteContentDto request)
{

2
backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/OperationBuilder.cs

@ -121,7 +121,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
{
[Constants.SecurityDefinition] = new[]
{
Permissions.ForApp(permissionId, operations.Parent.AppName, operations.SchemaName).Id
PermissionIds.ForApp(permissionId, operations.Parent.AppName, operations.SchemaName).Id
}
}
};

22
backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs

@ -94,7 +94,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
private static void GenerateSharedOperations(OperationsBuilder builder)
{
builder.AddOperation(OpenApiOperationMethod.Get, "/")
.RequirePermission(Permissions.AppContentsReadOwn)
.RequirePermission(PermissionIds.AppContentsReadOwn)
.Operation("Query")
.OperationSummary("Query contents across all schemas.")
.HasQuery("ids", JsonObjectType.String, "Comma-separated list of content IDs.")
@ -105,7 +105,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
private static void GenerateSchemaOperations(OperationsBuilder builder)
{
builder.AddOperation(OpenApiOperationMethod.Get, "/")
.RequirePermission(Permissions.AppContentsReadOwn)
.RequirePermission(PermissionIds.AppContentsReadOwn)
.Operation("Query")
.OperationSummary("Query [schema] contents items.")
.Describe(Resources.OpenApiSchemaQuery)
@ -114,14 +114,14 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content query not valid.");
builder.AddOperation(OpenApiOperationMethod.Get, "/{id}")
.RequirePermission(Permissions.AppContentsReadOwn)
.RequirePermission(PermissionIds.AppContentsReadOwn)
.Operation("Get")
.OperationSummary("Get a [schema] content item.")
.HasId()
.Responds(200, "Content item returned.", builder.ContentSchema);
builder.AddOperation(OpenApiOperationMethod.Get, "/{id}/{version}")
.RequirePermission(Permissions.AppContentsReadOwn)
.RequirePermission(PermissionIds.AppContentsReadOwn)
.Operation("GetVersioned")
.OperationSummary("Get a [schema] content item by id and version.")
.HasPath("version", JsonObjectType.Number, FieldDescriptions.EntityVersion)
@ -129,7 +129,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(200, "Content item returned.", builder.ContentSchema);
builder.AddOperation(OpenApiOperationMethod.Get, "/{id}/validity")
.RequirePermission(Permissions.AppContentsReadOwn)
.RequirePermission(PermissionIds.AppContentsReadOwn)
.Operation("Validate")
.OperationSummary("Validates a [schema] content item.")
.HasId()
@ -137,7 +137,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content item is not valid.");
builder.AddOperation(OpenApiOperationMethod.Post, "/")
.RequirePermission(Permissions.AppContentsCreate)
.RequirePermission(PermissionIds.AppContentsCreate)
.Operation("Create")
.OperationSummary("Create a [schema] content item.")
.HasQuery("publish", JsonObjectType.Boolean, FieldDescriptions.ContentRequestPublish)
@ -147,7 +147,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content data not valid.");
builder.AddOperation(OpenApiOperationMethod.Post, "/{id}")
.RequirePermission(Permissions.AppContentsUpsert)
.RequirePermission(PermissionIds.AppContentsUpsert)
.Operation("Upsert")
.OperationSummary("Upsert a [schema] content item.")
.HasQuery("patch", JsonObjectType.Boolean, FieldDescriptions.ContentRequestPatch)
@ -158,7 +158,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content data not valid.");
builder.AddOperation(OpenApiOperationMethod.Put, "/{id}")
.RequirePermission(Permissions.AppContentsUpdateOwn)
.RequirePermission(PermissionIds.AppContentsUpdateOwn)
.Operation("Update")
.OperationSummary("Update a [schema] content item.")
.HasId()
@ -167,7 +167,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content data not valid.");
builder.AddOperation(OpenApiOperationMethod.Patch, "/{id}")
.RequirePermission(Permissions.AppContentsUpdateOwn)
.RequirePermission(PermissionIds.AppContentsUpdateOwn)
.Operation("Patch")
.OperationSummary("Patch a [schema] content item.")
.HasId()
@ -176,7 +176,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content data not valid.");
builder.AddOperation(OpenApiOperationMethod.Put, "/{id}/status")
.RequirePermission(Permissions.AppContentsChangeStatusOwn)
.RequirePermission(PermissionIds.AppContentsChangeStatusOwn)
.Operation("Change")
.OperationSummary("Change the status of a [schema] content item.")
.HasId()
@ -185,7 +185,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
.Responds(400, "Content status not valid.");
builder.AddOperation(OpenApiOperationMethod.Delete, "/{id}")
.RequirePermission(Permissions.AppContentsDeleteOwn)
.RequirePermission(PermissionIds.AppContentsDeleteOwn)
.Operation("Delete")
.OperationSummary("Delete a [schema] content item.")
.HasId()

4
backend/src/Squidex/Areas/Api/Controllers/Diagnostics/DiagnosticsController.cs

@ -36,7 +36,7 @@ namespace Squidex.Areas.Api.Controllers.Diagnostics
/// </returns>
[HttpGet]
[Route("diagnostics/dump")]
[ApiPermissionOrAnonymous(Permissions.Admin)]
[ApiPermissionOrAnonymous(PermissionIds.Admin)]
public async Task<IActionResult> GetDump()
{
var success = await dumper.CreateDumpAsync(HttpContext.RequestAborted);
@ -58,7 +58,7 @@ namespace Squidex.Areas.Api.Controllers.Diagnostics
/// </returns>
[HttpGet]
[Route("diagnostics/gcdump")]
[ApiPermissionOrAnonymous(Permissions.Admin)]
[ApiPermissionOrAnonymous(PermissionIds.Admin)]
public async Task<IActionResult> GetGCDump()
{
var success = await dumper.CreateGCDumpAsync(HttpContext.RequestAborted);

8
backend/src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs

@ -27,7 +27,7 @@ namespace Squidex.Areas.Api.Controllers.EventConsumers
[HttpGet]
[Route("event-consumers/")]
[ProducesResponseType(typeof(EventConsumersDto), StatusCodes.Status200OK)]
[ApiPermission(Permissions.AdminEventsRead)]
[ApiPermission(PermissionIds.AdminEventsRead)]
public async Task<IActionResult> GetEventConsumers()
{
var eventConsumers = await eventConsumerManager.GetConsumersAsync(HttpContext.RequestAborted);
@ -40,7 +40,7 @@ namespace Squidex.Areas.Api.Controllers.EventConsumers
[HttpPut]
[Route("event-consumers/{consumerName}/start/")]
[ProducesResponseType(typeof(EventConsumerDto), StatusCodes.Status200OK)]
[ApiPermission(Permissions.AdminEventsManage)]
[ApiPermission(PermissionIds.AdminEventsManage)]
public async Task<IActionResult> StartEventConsumer(string consumerName)
{
var eventConsumer = await eventConsumerManager.StartAsync(consumerName, HttpContext.RequestAborted);
@ -53,7 +53,7 @@ namespace Squidex.Areas.Api.Controllers.EventConsumers
[HttpPut]
[Route("event-consumers/{consumerName}/stop/")]
[ProducesResponseType(typeof(EventConsumerDto), StatusCodes.Status200OK)]
[ApiPermission(Permissions.AdminEventsManage)]
[ApiPermission(PermissionIds.AdminEventsManage)]
public async Task<IActionResult> StopEventConsumer(string consumerName)
{
var eventConsumer = await eventConsumerManager.StopAsync(consumerName, HttpContext.RequestAborted);
@ -66,7 +66,7 @@ namespace Squidex.Areas.Api.Controllers.EventConsumers
[HttpPut]
[Route("event-consumers/{consumerName}/reset/")]
[ProducesResponseType(typeof(EventConsumerDto), StatusCodes.Status200OK)]
[ApiPermission(Permissions.AdminEventsManage)]
[ApiPermission(PermissionIds.AdminEventsManage)]
public async Task<IActionResult> ResetEventConsumer(string consumerName)
{
var eventConsumer = await eventConsumerManager.ResetAsync(consumerName, HttpContext.RequestAborted);

2
backend/src/Squidex/Areas/Api/Controllers/History/HistoryController.cs

@ -40,7 +40,7 @@ namespace Squidex.Areas.Api.Controllers.History
[HttpGet]
[Route("apps/{app}/history/")]
[ProducesResponseType(typeof(HistoryEventDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppHistory)]
[ApiPermissionOrAnonymous(PermissionIds.AppHistory)]
[ApiCosts(0.1)]
public async Task<IActionResult> GetHistory(string app, string channel)
{

2
backend/src/Squidex/Areas/Api/Controllers/Ping/PingController.cs

@ -68,7 +68,7 @@ namespace Squidex.Areas.Api.Controllers.Ping
/// </remarks>
[HttpGet]
[Route("ping/{app}/")]
[ApiPermissionOrAnonymous(Permissions.AppPing)]
[ApiPermissionOrAnonymous(PermissionIds.AppPing)]
[ApiCosts(0)]
public IActionResult GetAppPing(string app)
{

4
backend/src/Squidex/Areas/Api/Controllers/Plans/AppPlansController.cs

@ -44,7 +44,7 @@ namespace Squidex.Areas.Api.Controllers.Plans
[HttpGet]
[Route("apps/{app}/plans/")]
[ProducesResponseType(typeof(AppPlansDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppPlansRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppPlansRead)]
[ApiCosts(0)]
public IActionResult GetPlans(string app)
{
@ -73,7 +73,7 @@ namespace Squidex.Areas.Api.Controllers.Plans
[HttpPut]
[Route("apps/{app}/plan/")]
[ProducesResponseType(typeof(PlanChangedDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppPlansChange)]
[ApiPermissionOrAnonymous(PermissionIds.AppPlansChange)]
[ApiCosts(0)]
public async Task<IActionResult> PutPlan(string app, [FromBody] ChangePlanDto request)
{

32
backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs

@ -92,7 +92,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpGet]
[Route("apps/{app}/rules/")]
[ProducesResponseType(typeof(RulesDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesRead)]
[ApiCosts(1)]
public async Task<IActionResult> GetRules(string app)
{
@ -119,7 +119,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpPost]
[Route("apps/{app}/rules/")]
[ProducesResponseType(typeof(RuleDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppRulesCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostRule(string app, [FromBody] CreateRuleDto request)
{
@ -140,7 +140,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpDelete]
[Route("apps/{app}/rules/run")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteRuleRun(string app)
{
@ -163,7 +163,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpPut]
[Route("apps/{app}/rules/{id}/")]
[ProducesResponseType(typeof(RuleDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutRule(string app, DomainId id, [FromBody] UpdateRuleDto request)
{
@ -186,7 +186,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpPut]
[Route("apps/{app}/rules/{id}/enable/")]
[ProducesResponseType(typeof(RuleDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesDisable)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesDisable)]
[ApiCosts(1)]
public async Task<IActionResult> EnableRule(string app, DomainId id)
{
@ -209,7 +209,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpPut]
[Route("apps/{app}/rules/{id}/disable/")]
[ProducesResponseType(typeof(RuleDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesDisable)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesDisable)]
[ApiCosts(1)]
public async Task<IActionResult> DisableRule(string app, DomainId id)
{
@ -231,7 +231,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
/// </returns>
[HttpPut]
[Route("apps/{app}/rules/{id}/trigger/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsRun)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsRun)]
[ApiCosts(1)]
public async Task<IActionResult> TriggerRule(string app, DomainId id)
{
@ -254,7 +254,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpPut]
[Route("apps/{app}/rules/{id}/run")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsRun)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsRun)]
[ApiCosts(1)]
public async Task<IActionResult> PutRuleRun(string app, DomainId id, [FromQuery] bool fromSnapshots = false)
{
@ -274,7 +274,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpDelete]
[Route("apps/{app}/rules/{id}/events/")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteRuleEvents(string app, DomainId id)
{
@ -295,7 +295,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpPost]
[Route("apps/{app}/rules/simulate/")]
[ProducesResponseType(typeof(SimulatedRuleEventsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsRead)]
[ApiCosts(5)]
public async Task<IActionResult> Simulate(string app, [FromBody] CreateRuleDto request)
{
@ -320,7 +320,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpGet]
[Route("apps/{app}/rules/{id}/simulate/")]
[ProducesResponseType(typeof(SimulatedRuleEventsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsRead)]
[ApiCosts(5)]
public async Task<IActionResult> Simulate(string app, DomainId id)
{
@ -349,7 +349,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
/// </returns>
[HttpDelete]
[Route("apps/{app}/rules/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteRule(string app, DomainId id)
{
@ -374,7 +374,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpGet]
[Route("apps/{app}/rules/events/")]
[ProducesResponseType(typeof(RuleEventsDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsRead)]
[ApiCosts(0)]
public async Task<IActionResult> GetEvents(string app, [FromQuery] DomainId? ruleId = null, [FromQuery] int skip = 0, [FromQuery] int take = 20)
{
@ -396,7 +396,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
/// </returns>
[HttpPut]
[Route("apps/{app}/rules/events/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsUpdate)]
[ApiCosts(0)]
public async Task<IActionResult> PutEvent(string app, DomainId id)
{
@ -422,7 +422,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[HttpDelete]
[Route("apps/{app}/rules/events/")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteEvents(string app)
{
@ -442,7 +442,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
/// </returns>
[HttpDelete]
[Route("apps/{app}/rules/events/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEventsDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppRulesEventsDelete)]
[ApiCosts(0)]
public async Task<IActionResult> DeleteEvent(string app, DomainId id)
{

38
backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs

@ -41,7 +41,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPost]
[Route("apps/{app}/schemas/{schema}/fields/")]
[ProducesResponseType(typeof(SchemaDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PostField(string app, string schema, [FromBody] AddFieldDto request)
{
@ -68,7 +68,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPost]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/")]
[ProducesResponseType(typeof(SchemaDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PostNestedField(string app, string schema, long parentId, [FromBody] AddFieldDto request)
{
@ -93,7 +93,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/ui/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutSchemaUIFields(string app, string schema, [FromBody] ConfigureUIFieldsDto request)
{
@ -118,7 +118,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/ordering/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutSchemaFieldOrdering(string app, string schema, [FromBody] ReorderFieldsDto request)
{
@ -144,7 +144,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/ordering/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutNestedFieldOrdering(string app, string schema, long parentId, [FromBody] ReorderFieldsDto request)
{
@ -170,7 +170,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutField(string app, string schema, long id, [FromBody] UpdateFieldDto request)
{
@ -197,7 +197,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutNestedField(string app, string schema, long parentId, long id, [FromBody] UpdateFieldDto request)
{
@ -225,7 +225,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/lock/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> LockField(string app, string schema, long id)
{
@ -254,7 +254,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/lock/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> LockNestedField(string app, string schema, long parentId, long id)
{
@ -282,7 +282,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/hide/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> HideField(string app, string schema, long id)
{
@ -311,7 +311,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/hide/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> HideNestedField(string app, string schema, long parentId, long id)
{
@ -339,7 +339,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/show/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> ShowField(string app, string schema, long id)
{
@ -368,7 +368,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/show/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> ShowNestedField(string app, string schema, long parentId, long id)
{
@ -396,7 +396,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/enable/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> EnableField(string app, string schema, long id)
{
@ -425,7 +425,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/enable/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> EnableNestedField(string app, string schema, long parentId, long id)
{
@ -453,7 +453,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/disable/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DisableField(string app, string schema, long id)
{
@ -482,7 +482,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/disable/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DisableNestedField(string app, string schema, long parentId, long id)
{
@ -507,7 +507,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpDelete]
[Route("apps/{app}/schemas/{schema}/fields/{id:long}/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteField(string app, string schema, long id)
{
@ -533,7 +533,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpDelete]
[Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteNestedField(string app, string schema, long parentId, long id)
{

24
backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs

@ -48,7 +48,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpGet]
[Route("apps/{app}/schemas/")]
[ProducesResponseType(typeof(SchemasDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasRead)]
[ApiCosts(0)]
public async Task<IActionResult> GetSchemas(string app)
{
@ -76,7 +76,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpGet]
[Route("apps/{app}/schemas/{schema}/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasRead)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasRead)]
[ApiCosts(0)]
public IActionResult GetSchema(string app, string schema)
{
@ -103,7 +103,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPost]
[Route("apps/{app}/schemas/")]
[ProducesResponseType(typeof(SchemaDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasCreate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasCreate)]
[ApiCosts(1)]
public async Task<IActionResult> PostSchema(string app, [FromBody] CreateSchemaDto request)
{
@ -128,7 +128,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutSchema(string app, string schema, [FromBody] UpdateSchemaDto request)
{
@ -153,7 +153,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/sync")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutSchemaSync(string app, string schema, [FromBody] SynchronizeSchemaDto request)
{
@ -178,7 +178,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/category")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutCategory(string app, string schema, [FromBody] ChangeCategoryDto request)
{
@ -203,7 +203,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/preview-urls")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutPreviewUrls(string app, string schema, [FromBody] ConfigurePreviewUrlsDto request)
{
@ -228,7 +228,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/scripts/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasScripts)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasScripts)]
[ApiCosts(1)]
public async Task<IActionResult> PutScripts(string app, string schema, [FromBody] SchemaScriptsDto request)
{
@ -253,7 +253,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/rules/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutRules(string app, string schema, [FromBody] ConfigureFieldRulesDto request)
{
@ -276,7 +276,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/publish/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasPublish)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasPublish)]
[ApiCosts(1)]
public async Task<IActionResult> PublishSchema(string app, string schema)
{
@ -299,7 +299,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[HttpPut]
[Route("apps/{app}/schemas/{schema}/unpublish/")]
[ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSchemasPublish)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasPublish)]
[ApiCosts(1)]
public async Task<IActionResult> UnpublishSchema(string app, string schema)
{
@ -321,7 +321,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// </returns>
[HttpDelete]
[Route("apps/{app}/schemas/{schema}/")]
[ApiPermissionOrAnonymous(Permissions.AppSchemasDelete)]
[ApiPermissionOrAnonymous(PermissionIds.AppSchemasDelete)]
[ApiCosts(1)]
public async Task<IActionResult> DeleteSchema(string app, string schema)
{

2
backend/src/Squidex/Areas/Api/Controllers/Search/SearchController.cs

@ -40,7 +40,7 @@ namespace Squidex.Areas.Api.Controllers.Search
[HttpGet]
[Route("apps/{app}/search/")]
[ProducesResponseType(typeof(SearchResultDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppSearch)]
[ApiPermissionOrAnonymous(PermissionIds.AppSearch)]
[ApiCosts(0)]
public async Task<IActionResult> GetSearchResults(string app, [FromQuery] string? query = null)
{

8
backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs

@ -64,7 +64,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[HttpGet]
[Route("apps/{app}/usages/log/")]
[ProducesResponseType(typeof(LogDownloadDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppUsage)]
[ApiPermissionOrAnonymous(PermissionIds.AppUsage)]
[ApiCosts(0)]
public IActionResult GetLog(string app)
{
@ -92,7 +92,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[HttpGet]
[Route("apps/{app}/usages/calls/{fromDate}/{toDate}/")]
[ProducesResponseType(typeof(CallsUsageDtoDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppUsage)]
[ApiPermissionOrAnonymous(PermissionIds.AppUsage)]
[ApiCosts(0)]
public async Task<IActionResult> GetUsages(string app, DateTime fromDate, DateTime toDate)
{
@ -123,7 +123,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[HttpGet]
[Route("apps/{app}/usages/storage/today/")]
[ProducesResponseType(typeof(CurrentStorageDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppUsage)]
[ApiPermissionOrAnonymous(PermissionIds.AppUsage)]
[ApiCosts(0)]
public async Task<IActionResult> GetCurrentStorageSize(string app)
{
@ -151,7 +151,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[HttpGet]
[Route("apps/{app}/usages/storage/{fromDate}/{toDate}/")]
[ProducesResponseType(typeof(StorageUsagePerDateDto[]), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppUsage)]
[ApiPermissionOrAnonymous(PermissionIds.AppUsage)]
[ApiCosts(0)]
public async Task<IActionResult> GetStorageSizes(string app, DateTime fromDate, DateTime toDate)
{

2
backend/src/Squidex/Areas/Api/Controllers/Translations/TranslationsController.cs

@ -39,7 +39,7 @@ namespace Squidex.Areas.Api.Controllers.Translations
[HttpPost]
[Route("apps/{app}/translations/")]
[ProducesResponseType(typeof(TranslationDto), StatusCodes.Status200OK)]
[ApiPermissionOrAnonymous(Permissions.AppTranslate)]
[ApiPermissionOrAnonymous(PermissionIds.AppTranslate)]
[ApiCosts(0)]
public async Task<IActionResult> PostTranslation(string app, [FromBody] TranslateDto request)
{

2
backend/src/Squidex/Areas/Api/Controllers/UI/UIController.cs

@ -20,7 +20,7 @@ namespace Squidex.Areas.Api.Controllers.UI
{
public sealed class UIController : ApiController
{
private static readonly Permission CreateAppPermission = new Permission(Permissions.AdminAppCreate);
private static readonly Permission CreateAppPermission = new Permission(PermissionIds.AdminAppCreate);
private readonly MyUIOptions uiOptions;
private readonly IAppUISettings appUISettings;

14
backend/src/Squidex/Areas/Api/Controllers/Users/UserManagementController.cs

@ -30,7 +30,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpGet]
[Route("user-management/")]
[ProducesResponseType(typeof(UsersDto), StatusCodes.Status200OK)]
[ApiPermission(Permissions.AdminUsersRead)]
[ApiPermission(PermissionIds.AdminUsersRead)]
public async Task<IActionResult> GetUsers([FromQuery] string? query = null, [FromQuery] int skip = 0, [FromQuery] int take = 10)
{
var users = await userService.QueryAsync(query, take, skip, HttpContext.RequestAborted);
@ -43,7 +43,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpGet]
[Route("user-management/{id}/")]
[ProducesResponseType(typeof(UserDto), 201)]
[ApiPermission(Permissions.AdminUsersRead)]
[ApiPermission(PermissionIds.AdminUsersRead)]
public async Task<IActionResult> GetUser(string id)
{
var user = await userService.FindByIdAsync(id, HttpContext.RequestAborted);
@ -61,7 +61,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpPost]
[Route("user-management/")]
[ProducesResponseType(typeof(UserDto), 201)]
[ApiPermission(Permissions.AdminUsersCreate)]
[ApiPermission(PermissionIds.AdminUsersCreate)]
public async Task<IActionResult> PostUser([FromBody] CreateUserDto request)
{
var user = await userService.CreateAsync(request.Email, request.ToValues(), ct: HttpContext.RequestAborted);
@ -74,7 +74,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpPut]
[Route("user-management/{id}/")]
[ProducesResponseType(typeof(UserDto), 201)]
[ApiPermission(Permissions.AdminUsersUpdate)]
[ApiPermission(PermissionIds.AdminUsersUpdate)]
public async Task<IActionResult> PutUser(string id, [FromBody] UpdateUserDto request)
{
var user = await userService.UpdateAsync(id, request.ToValues(), ct: HttpContext.RequestAborted);
@ -87,7 +87,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpPut]
[Route("user-management/{id}/lock/")]
[ProducesResponseType(typeof(UserDto), 201)]
[ApiPermission(Permissions.AdminUsersLock)]
[ApiPermission(PermissionIds.AdminUsersLock)]
public async Task<IActionResult> LockUser(string id)
{
if (this.IsUser(id))
@ -105,7 +105,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpPut]
[Route("user-management/{id}/unlock/")]
[ProducesResponseType(typeof(UserDto), 201)]
[ApiPermission(Permissions.AdminUsersUnlock)]
[ApiPermission(PermissionIds.AdminUsersUnlock)]
public async Task<IActionResult> UnlockUser(string id)
{
if (this.IsUser(id))
@ -123,7 +123,7 @@ namespace Squidex.Areas.Api.Controllers.Users
[HttpDelete]
[Route("user-management/{id}/")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ApiPermission(Permissions.AdminUsersUnlock)]
[ApiPermission(PermissionIds.AdminUsersUnlock)]
public async Task<IActionResult> DeleteUser(string id)
{
if (this.IsUser(id))

2
backend/src/Squidex/Areas/IdentityServer/Config/ApplicationExtensions.cs

@ -19,7 +19,7 @@ namespace Squidex.Areas.IdentityServer.Config
{
public static OpenIddictApplicationDescriptor SetAdmin(this OpenIddictApplicationDescriptor application)
{
application.Properties[SquidexClaimTypes.Permissions] = CreateParameter(Enumerable.Repeat(Permissions.All, 1));
application.Properties[SquidexClaimTypes.Permissions] = CreateParameter(Enumerable.Repeat(PermissionIds.All, 1));
return application;
}

4
backend/src/Squidex/Areas/IdentityServer/Config/CreateAdminInitializer.cs

@ -95,11 +95,11 @@ namespace Squidex.Areas.IdentityServer.Config
private PermissionSet CreatePermissions(PermissionSet permissions)
{
permissions = permissions.Add(Permissions.Admin);
permissions = permissions.Add(PermissionIds.Admin);
foreach (var app in identityOptions.AdminApps.OrEmpty())
{
permissions = permissions.Add(Permissions.ForApp(Permissions.AppAdmin, app));
permissions = permissions.Add(PermissionIds.ForApp(PermissionIds.AppAdmin, app));
}
return permissions;

22
backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppSettingsSearchSourceTests.cs

@ -42,7 +42,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_dashboard_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppUsage, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppUsage, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -69,7 +69,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_languages_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppLanguagesRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppLanguagesRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -106,7 +106,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_schemas_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppSchemasRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppSchemasRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -133,7 +133,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_assets_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppAssetsRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppAssetsRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -160,7 +160,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_backups_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppBackupsRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppBackupsRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -187,7 +187,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_clients_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppClientsRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppClientsRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -214,7 +214,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_contributors_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppContributorsRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppContributorsRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -241,7 +241,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_subscription_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppPlansRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppPlansRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -268,7 +268,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_roles_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppRolesRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppRolesRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -295,7 +295,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_rules_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppRulesRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppRulesRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);
@ -322,7 +322,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
[Fact]
public async Task Should_return_workflows_result_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppWorkflowsRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppWorkflowsRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsSearchSourceTests.cs

@ -46,7 +46,7 @@ namespace Squidex.Domain.Apps.Entities.Assets
[Fact]
public async Task Should_return_assets_results_if_found()
{
var permission = Permissions.ForApp(Permissions.AppAssetsRead, appId.Name);
var permission = PermissionIds.ForApp(PermissionIds.AppAssetsRead, appId.Name);
var ctx = ContextWithPermission(permission.Id);

14
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/DomainObject/AssetsBulkUpdateCommandMiddlewareTests.cs

@ -59,7 +59,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_annotate_asset()
{
SetupContext(Permissions.AppAssetsUpdate);
SetupContext(PermissionIds.AppAssetsUpdate);
var id = DomainId.NewGuid();
@ -77,7 +77,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_annotating()
{
SetupContext(Permissions.AppAssetsRead);
SetupContext(PermissionIds.AppAssetsRead);
var id = DomainId.NewGuid();
@ -95,7 +95,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_move_asset()
{
SetupContext(Permissions.AppAssetsUpdate);
SetupContext(PermissionIds.AppAssetsUpdate);
var id = DomainId.NewGuid();
@ -113,7 +113,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_moving()
{
SetupContext(Permissions.AppAssetsRead);
SetupContext(PermissionIds.AppAssetsRead);
var id = DomainId.NewGuid();
@ -131,7 +131,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_delete_asset()
{
SetupContext(Permissions.AppAssetsDelete);
SetupContext(PermissionIds.AppAssetsDelete);
var id = DomainId.NewGuid();
@ -150,7 +150,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_deletion()
{
SetupContext(Permissions.AppAssetsRead);
SetupContext(PermissionIds.AppAssetsRead);
var id = DomainId.NewGuid();
@ -193,7 +193,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
private Context SetupContext(string id)
{
var permission = Permissions.ForApp(id, appId.Name).Id;
var permission = PermissionIds.ForApp(id, appId.Name).Id;
var claimsIdentity = new ClaimsIdentity();
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentsSearchSourceTests.cs

@ -212,7 +212,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
foreach (var schemaId in allowedSchemas)
{
var permission = Permissions.ForApp(Permissions.AppContentsReadOwn, appId.Name, schemaId.Name).Id;
var permission = PermissionIds.ForApp(PermissionIds.AppContentsReadOwn, appId.Name, schemaId.Name).Id;
claimsIdentity.AddClaim(new Claim(SquidexClaimTypes.Permissions, permission));
}

48
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/ContentsBulkUpdateCommandMiddlewareTests.cs

@ -67,7 +67,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_exception_if_content_cannot_be_resolved()
{
SetupContext(Permissions.AppContentsUpdateOwn);
SetupContext(PermissionIds.AppContentsUpdateOwn);
CreateTestData(true);
@ -85,7 +85,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_exception_if_query_resolves_multiple_contents()
{
var requestContext = SetupContext(Permissions.AppContentsUpdateOwn);
var requestContext = SetupContext(PermissionIds.AppContentsUpdateOwn);
var (id, _, query) = CreateTestData(true);
@ -111,7 +111,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_upsert_content_with_resolved_id()
{
var requestContext = SetupContext(Permissions.AppContentsUpsert);
var requestContext = SetupContext(PermissionIds.AppContentsUpsert);
var (id, data, query) = CreateTestData(true);
@ -138,7 +138,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_upsert_content_with_resolved_ids()
{
var requestContext = SetupContext(Permissions.AppContentsUpsert);
var requestContext = SetupContext(PermissionIds.AppContentsUpsert);
var (_, data, query) = CreateTestData(true);
@ -177,7 +177,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_upsert_content_with_random_id_if_no_query_and_id_defined()
{
SetupContext(Permissions.AppContentsUpsert);
SetupContext(PermissionIds.AppContentsUpsert);
var (_, data, _) = CreateTestData(false);
@ -196,7 +196,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_upsert_content_with_random_id_if_query_returns_no_result()
{
SetupContext(Permissions.AppContentsUpsert);
SetupContext(PermissionIds.AppContentsUpsert);
var (_, data, query) = CreateTestData(true);
@ -215,7 +215,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_upsert_content_if_id_defined()
{
SetupContext(Permissions.AppContentsUpsert);
SetupContext(PermissionIds.AppContentsUpsert);
var (id, data, _) = CreateTestData(false);
@ -234,7 +234,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_upsert_content_with_custom_id()
{
SetupContext(Permissions.AppContentsUpsert);
SetupContext(PermissionIds.AppContentsUpsert);
var (id, data, _) = CreateTestData(true);
@ -253,7 +253,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_create_content()
{
SetupContext(Permissions.AppContentsCreate);
SetupContext(PermissionIds.AppContentsCreate);
var (id, data, _) = CreateTestData(false);
@ -272,7 +272,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_creating()
{
SetupContext(Permissions.AppContentsReadOwn);
SetupContext(PermissionIds.AppContentsReadOwn);
var (id, data, _) = CreateTestData(false);
@ -290,7 +290,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_update_content()
{
SetupContext(Permissions.AppContentsUpdateOwn);
SetupContext(PermissionIds.AppContentsUpdateOwn);
var (id, data, _) = CreateTestData(false);
@ -309,7 +309,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_updating()
{
SetupContext(Permissions.AppContentsReadOwn);
SetupContext(PermissionIds.AppContentsReadOwn);
var (id, data, _) = CreateTestData(false);
@ -327,7 +327,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_patch_content()
{
SetupContext(Permissions.AppContentsUpdateOwn);
SetupContext(PermissionIds.AppContentsUpdateOwn);
var (id, data, _) = CreateTestData(false);
@ -346,7 +346,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_patching()
{
SetupContext(Permissions.AppContentsReadOwn);
SetupContext(PermissionIds.AppContentsReadOwn);
var (id, data, _) = CreateTestData(false);
@ -364,7 +364,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_change_content_status()
{
SetupContext(Permissions.AppContentsChangeStatusOwn);
SetupContext(PermissionIds.AppContentsChangeStatusOwn);
var (id, _, _) = CreateTestData(false);
@ -383,7 +383,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_change_content_status_with_due_time()
{
SetupContext(Permissions.AppContentsChangeStatusOwn);
SetupContext(PermissionIds.AppContentsChangeStatusOwn);
var (id, _, _) = CreateTestData(false);
@ -402,7 +402,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_changing_status()
{
SetupContext(Permissions.AppContentsReadOwn);
SetupContext(PermissionIds.AppContentsReadOwn);
var (id, _, _) = CreateTestData(false);
@ -420,7 +420,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_validate_content()
{
SetupContext(Permissions.AppContentsReadOwn);
SetupContext(PermissionIds.AppContentsReadOwn);
var (id, _, _) = CreateTestData(false);
@ -439,7 +439,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_validation()
{
SetupContext(Permissions.AppContentsDeleteOwn);
SetupContext(PermissionIds.AppContentsDeleteOwn);
var (id, _, _) = CreateTestData(false);
@ -457,7 +457,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_delete_content()
{
SetupContext(Permissions.AppContentsDeleteOwn);
SetupContext(PermissionIds.AppContentsDeleteOwn);
var (id, _, _) = CreateTestData(false);
@ -476,7 +476,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_throw_security_exception_if_user_has_no_permission_for_deletion()
{
SetupContext(Permissions.AppContentsReadOwn);
SetupContext(PermissionIds.AppContentsReadOwn);
var (id, _, _) = CreateTestData(false);
@ -494,7 +494,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_override_schema_name()
{
SetupContext(Permissions.AppContentsDeleteOwn);
SetupContext(PermissionIds.AppContentsDeleteOwn);
A.CallTo(() => contentQuery.GetSchemaOrThrowAsync(A<Context>._, schemaCustomId.Name, ct))
.Returns(Mocks.Schema(appId, schemaCustomId));
@ -546,11 +546,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
claimsIdentity.AddClaim(
new Claim(SquidexClaimTypes.Permissions,
Permissions.ForApp(id, appId.Name, schemaId.Name).Id));
PermissionIds.ForApp(id, appId.Name, schemaId.Name).Id));
claimsIdentity.AddClaim(
new Claim(SquidexClaimTypes.Permissions,
Permissions.ForApp(id, appId.Name, schemaCustomId.Name).Id));
PermissionIds.ForApp(id, appId.Name, schemaCustomId.Name).Id));
var requestContext = new Context(claimsPrincipal, Mocks.App(appId));

10
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs

@ -317,14 +317,14 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
[Fact]
public void Should_not_throw_exception_if_content_is_from_another_user_but_user_has_permission()
{
var userPermission = Permissions.ForApp(Permissions.AppContentsDelete, appId.Name, schemaId.Name).Id;
var userPermission = PermissionIds.ForApp(PermissionIds.AppContentsDelete, appId.Name, schemaId.Name).Id;
var userObject = Mocks.FrontendUser(permission: userPermission);
var operation = Operation(CreateContent(Status.Draft), normalSchema, userObject);
((ContentEntity)operation.Snapshot).CreatedBy = RefToken.User("456");
operation.MustHavePermission(Permissions.AppContentsDelete);
operation.MustHavePermission(PermissionIds.AppContentsDelete);
}
[Fact]
@ -334,7 +334,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
((ContentEntity)operation.Snapshot).CreatedBy = actor;
operation.MustHavePermission(Permissions.AppContentsDelete);
operation.MustHavePermission(PermissionIds.AppContentsDelete);
}
[Fact]
@ -344,7 +344,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
((ContentEntity)operation.Snapshot).CreatedBy = RefToken.User("456");
operation.MustHavePermission(Permissions.AppContentsDelete);
operation.MustHavePermission(PermissionIds.AppContentsDelete);
}
[Fact]
@ -354,7 +354,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
((ContentEntity)operation.Snapshot).CreatedBy = RefToken.User("456");
Assert.Throws<DomainForbiddenException>(() => operation.MustHavePermission(Permissions.AppContentsDelete));
Assert.Throws<DomainForbiddenException>(() => operation.MustHavePermission(PermissionIds.AppContentsDelete));
}
[Fact]

38
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs

@ -44,7 +44,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
}
}";
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsReadOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsReadOwn);
var expected = new
{
@ -88,7 +88,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsCreate);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsCreate);
var expected = new
{
@ -122,7 +122,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsCreate);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsCreate);
var expected = new
{
@ -157,7 +157,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, Permissions.AppContentsCreate);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, PermissionIds.AppContentsCreate);
var expected = new
{
@ -189,7 +189,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
}
}");
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsReadOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsReadOwn);
var expected = new
{
@ -233,7 +233,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsUpdateOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsUpdateOwn);
var expected = new
{
@ -267,7 +267,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, Permissions.AppContentsUpdateOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, PermissionIds.AppContentsUpdateOwn);
var expected = new
{
@ -299,7 +299,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
}
}");
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsReadOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsReadOwn);
var expected = new
{
@ -343,7 +343,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsUpsert);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsUpsert);
var expected = new
{
@ -378,7 +378,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, Permissions.AppContentsUpsert);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, PermissionIds.AppContentsUpsert);
var expected = new
{
@ -411,7 +411,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
}
}");
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsReadOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsReadOwn);
var expected = new
{
@ -455,7 +455,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsUpdateOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsUpdateOwn);
var expected = new
{
@ -489,7 +489,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, Permissions.AppContentsUpdateOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query, Variables = GetInput() }, PermissionIds.AppContentsUpdateOwn);
var expected = new
{
@ -521,7 +521,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
}
}");
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsReadOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsReadOwn);
var expected = new
{
@ -567,7 +567,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsChangeStatusOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsChangeStatusOwn);
var expected = new
{
@ -602,7 +602,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsChangeStatusOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsChangeStatusOwn);
var expected = new
{
@ -637,7 +637,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(content);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsChangeStatusOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsChangeStatusOwn);
var expected = new
{
@ -670,7 +670,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
}
}");
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsReadOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsReadOwn);
var expected = new
{
@ -714,7 +714,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
commandContext.Complete(CommandResult.Empty(contentId, 13, 12));
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, Permissions.AppContentsDeleteOwn);
var result = await ExecuteAsync(new ExecutionOptions { Query = query }, PermissionIds.AppContentsDeleteOwn);
var expected = new
{

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs

@ -71,7 +71,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
if (permissionId != null)
{
var permission = Permissions.ForApp(permissionId, TestApp.Default.Name, TestSchemas.DefaultId.Name).Id;
var permission = PermissionIds.ForApp(permissionId, TestApp.Default.Name, TestSchemas.DefaultId.Name).Id;
context = new Context(Mocks.FrontendUser(permission: permission), TestApp.Default);
}

8
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ContentQueryServiceTests.cs

@ -273,7 +273,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
[Fact]
public async Task Should_query_contents_from_user_if_user_has_only_own_permission()
{
var requestContext = CreateContext(permissionId: Permissions.AppContentsReadOwn);
var requestContext = CreateContext(permissionId: PermissionIds.AppContentsReadOwn);
await sut.QueryAsync(requestContext, schemaId.Name, Q.Empty, ct);
@ -286,7 +286,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
[Fact]
public async Task Should_query_all_contents_if_user_has_read_permission()
{
var requestContext = CreateContext(permissionId: Permissions.AppContentsRead);
var requestContext = CreateContext(permissionId: PermissionIds.AppContentsRead);
await sut.QueryAsync(requestContext, schemaId.Name, Q.Empty, ct);
@ -311,7 +311,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
int isFrontend = 0,
int isUnpublished = 0,
bool allowSchema = true,
string permissionId = Permissions.AppContentsRead)
string permissionId = PermissionIds.AppContentsRead)
{
var claimsIdentity = new ClaimsIdentity();
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
@ -325,7 +325,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
if (allowSchema)
{
var concretePermission = Permissions.ForApp(permissionId, appId.Name, schemaId.Name).Id;
var concretePermission = PermissionIds.ForApp(permissionId, appId.Name, schemaId.Name).Id;
claimsIdentity.AddClaim(new Claim(SquidexClaimTypes.Permissions, concretePermission));
}

6
backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemasSearchSourceTests.cs

@ -55,7 +55,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
[Fact]
public async Task Should_not_add_result_to_contents_if_schema_is_component()
{
var permission = Permissions.ForApp(Permissions.AppContentsReadOwn, appId.Name, "schemaA1");
var permission = PermissionIds.ForApp(PermissionIds.AppContentsReadOwn, appId.Name, "schemaA1");
var ctx = ContextWithPermission();
@ -77,7 +77,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
[Fact]
public async Task Should_return_result_to_schema_and_contents_if_matching_and_permission_given()
{
var permission = Permissions.ForApp(Permissions.AppContentsReadOwn, appId.Name, "schemaA2");
var permission = PermissionIds.ForApp(PermissionIds.AppContentsReadOwn, appId.Name, "schemaA2");
var ctx = ContextWithPermission(permission.Id);
@ -109,7 +109,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
[Fact]
public async Task Should_return_result_to_schema_and_contents_if_schema_is_singleton()
{
var permission = Permissions.ForApp(Permissions.AppContentsReadOwn, appId.Name, "schemaA1");
var permission = PermissionIds.ForApp(PermissionIds.AppContentsReadOwn, appId.Name, "schemaA1");
var ctx = ContextWithPermission(permission.Id);

2
backend/tests/Squidex.Domain.Users.Tests/DefaultUserServiceTests.cs

@ -226,7 +226,7 @@ namespace Squidex.Domain.Users
await sut.CreateAsync(identity.Email, values);
A.CallTo(() => userManager.AddClaimsAsync(identity, HasClaim(SquidexClaimTypes.Permissions, Permissions.Admin)))
A.CallTo(() => userManager.AddClaimsAsync(identity, HasClaim(SquidexClaimTypes.Permissions, PermissionIds.Admin)))
.MustHaveHappened();
}

10
backend/tests/Squidex.Web.Tests/ApiPermissionAttributeTests.cs

@ -69,7 +69,7 @@ namespace Squidex.Web
SetContext();
var sut = new ApiPermissionAttribute(Permissions.AppSchemasCreate);
var sut = new ApiPermissionAttribute(PermissionIds.AppSchemasCreate);
await sut.OnActionExecutionAsync(actionExecutingContext, next);
@ -87,7 +87,7 @@ namespace Squidex.Web
SetContext();
var sut = new ApiPermissionAttribute(Permissions.AppSchemasUpdate);
var sut = new ApiPermissionAttribute(PermissionIds.AppSchemasUpdate);
await sut.OnActionExecutionAsync(actionExecutingContext, next);
@ -104,7 +104,7 @@ namespace Squidex.Web
SetContext();
var sut = new ApiPermissionAttribute(Permissions.AppSchemasCreate);
var sut = new ApiPermissionAttribute(PermissionIds.AppSchemasCreate);
await sut.OnActionExecutionAsync(actionExecutingContext, next);
@ -119,7 +119,7 @@ namespace Squidex.Web
SetContext();
var sut = new ApiPermissionAttribute(Permissions.AppSchemasCreate);
var sut = new ApiPermissionAttribute(PermissionIds.AppSchemasCreate);
await sut.OnActionExecutionAsync(actionExecutingContext, next);
@ -132,7 +132,7 @@ namespace Squidex.Web
{
SetContext();
var sut = new ApiPermissionAttribute(Permissions.AppSchemasCreate);
var sut = new ApiPermissionAttribute(PermissionIds.AppSchemasCreate);
await sut.OnActionExecutionAsync(actionExecutingContext, next);

2
backend/tests/Squidex.Web.Tests/Pipeline/ApiPermissionUnifierTests.cs

@ -28,7 +28,7 @@ namespace Squidex.Web.Pipeline
var result = await sut.TransformAsync(userPrincipal);
Assert.Equal(Permissions.Admin, result.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.Permissions)?.Value);
Assert.Equal(PermissionIds.Admin, result.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.Permissions)?.Value);
Assert.Equal(role, result.Claims.FirstOrDefault(x => x.Type == userIdentity.RoleClaimType)?.Value);
}

Loading…
Cancel
Save