diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs new file mode 100644 index 000000000..b33285923 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs @@ -0,0 +1,39 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Newtonsoft.Json; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Security; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Squidex.Domain.Apps.Core.Apps.Json +{ + public sealed class RolesConverter : JsonClassConverter + { + protected override void WriteValue(JsonWriter writer, Roles value, JsonSerializer serializer) + { + var json = new Dictionary(value.Count); + + foreach (var role in value) + { + json.Add(role.Key, role.Value.Permissions.ToIds().ToArray()); + } + + serializer.Serialize(writer, json); + } + + protected override Roles ReadValue(JsonReader reader, Type objectType, JsonSerializer serializer) + { + var json = serializer.Deserialize>(reader); + + return new Roles(json.ToImmutableDictionary(x => x.Key, x => new Role(x.Key, new PermissionSet(x.Value)))); + } + } +} diff --git a/src/Squidex.Infrastructure/Security/Permission.cs b/src/Squidex.Infrastructure/Security/Permission.cs index 57477dd29..409a19bce 100644 --- a/src/Squidex.Infrastructure/Security/Permission.cs +++ b/src/Squidex.Infrastructure/Security/Permission.cs @@ -16,7 +16,6 @@ namespace Squidex.Infrastructure.Security private const string Any = "*"; private static readonly char[] MainSeparators = { '.' }; private static readonly char[] AlternativeSeparators = { '|' }; - private readonly string description; private readonly string id; private readonly Lazy[]> idParts; @@ -25,17 +24,10 @@ namespace Squidex.Infrastructure.Security get { return id; } } - public string Description - { - get { return description; } - } - - public Permission(string id, string description = null) + public Permission(string id) { Guard.NotNullOrEmpty(id, nameof(id)); - this.description = description; - this.id = id; idParts = new Lazy[]>(() => id diff --git a/src/Squidex.Infrastructure/Security/PermissionSet.cs b/src/Squidex.Infrastructure/Security/PermissionSet.cs index db32707d8..c9a9eff69 100644 --- a/src/Squidex.Infrastructure/Security/PermissionSet.cs +++ b/src/Squidex.Infrastructure/Security/PermissionSet.cs @@ -29,6 +29,11 @@ namespace Squidex.Infrastructure.Security { } + public PermissionSet(IEnumerable permissions) + : this(permissions?.Select(x => new Permission(x))) + { + } + public PermissionSet(IEnumerable permissions) { Guard.NotNull(permissions, nameof(permissions)); diff --git a/src/Squidex/Config/Domain/SerializationServices.cs b/src/Squidex/Config/Domain/SerializationServices.cs index 5c06f94a3..c52abca55 100644 --- a/src/Squidex/Config/Domain/SerializationServices.cs +++ b/src/Squidex/Config/Domain/SerializationServices.cs @@ -57,6 +57,7 @@ namespace Squidex.Config.Domain new PropertiesBagConverter(), new PropertiesBagConverter(), new RefTokenConverter(), + new RolesConverter(), new RuleConverter(), new SchemaConverter(FieldRegistry), new StringEnumConverter()); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs new file mode 100644 index 000000000..82b47099a --- /dev/null +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs @@ -0,0 +1,30 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using FluentAssertions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Squidex.Domain.Apps.Core.Apps; +using Xunit; + +namespace Squidex.Domain.Apps.Core.Model.Apps +{ + public class RolesJsonTests + { + private readonly JsonSerializer serializer = TestData.DefaultSerializer(); + + [Fact] + public void Should_serialize_and_deserialize() + { + var sut = Roles.CreateDefaults("my-app"); + + var serialized = JToken.FromObject(sut, serializer).ToObject(serializer); + + serialized.Should().BeEquivalentTo(sut); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs new file mode 100644 index 000000000..003fe0502 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesTests.cs @@ -0,0 +1,31 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Domain.Apps.Core.Apps; +using Xunit; + +namespace Squidex.Domain.Apps.Core.Model.Apps +{ + public class RolesTests + { + [Fact] + public void Should_create_defaults() + { + var sut = Roles.CreateDefaults("my-app"); + + Assert.Equal(4, sut.Count); + + foreach (var role in sut) + { + foreach (var permission in role.Value.Permissions) + { + Assert.StartsWith("squidex.apps.my-app", permission.Id); + } + } + } + } +} diff --git a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs index 6434b9bee..354dfa971 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs @@ -42,6 +42,7 @@ namespace Squidex.Domain.Apps.Core new NamedLongIdConverter(), new NamedStringIdConverter(), new RefTokenConverter(), + new RolesConverter(), new RuleConverter(), new SchemaConverter(new FieldRegistry(typeNameRegistry)), new StringEnumConverter()), diff --git a/tests/Squidex.Infrastructure.Tests/Security/PermissionTests.cs b/tests/Squidex.Infrastructure.Tests/Security/PermissionTests.cs index e04fbe623..ca0aff6c2 100644 --- a/tests/Squidex.Infrastructure.Tests/Security/PermissionTests.cs +++ b/tests/Squidex.Infrastructure.Tests/Security/PermissionTests.cs @@ -16,11 +16,10 @@ namespace Squidex.Infrastructure.Security [Fact] public void Should_generate_permissions() { - var sut = new Permission("app.contents", "App Contents"); + var sut = new Permission("app.contents"); Assert.Equal("app.contents", sut.ToString()); Assert.Equal("app.contents", sut.Id); - Assert.Equal("App Contents", sut.Description); } [Fact]