mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
5.5 KiB
185 lines
5.5 KiB
// ==========================================================================
|
|
// Squidex Headless CMS
|
|
// ==========================================================================
|
|
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
// All rights reserved. Licensed under the MIT license.
|
|
// ==========================================================================
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Diagnostics.Contracts;
|
|
using System.Linq;
|
|
using Squidex.Infrastructure;
|
|
using Squidex.Infrastructure.Collections;
|
|
using Squidex.Infrastructure.Security;
|
|
using Squidex.Shared;
|
|
|
|
namespace Squidex.Domain.Apps.Core.Apps
|
|
{
|
|
public sealed class Roles
|
|
{
|
|
private readonly ImmutableDictionary<string, Role> inner;
|
|
|
|
public static readonly IReadOnlyDictionary<string, Role> Defaults = new Dictionary<string, Role>
|
|
{
|
|
[Role.Owner] =
|
|
new Role(Role.Owner, new PermissionSet(
|
|
Clean(Permissions.App))),
|
|
[Role.Reader] =
|
|
new Role(Role.Reader, new PermissionSet(
|
|
Clean(Permissions.AppAssetsRead),
|
|
Clean(Permissions.AppContentsRead))),
|
|
[Role.Editor] =
|
|
new Role(Role.Editor, new PermissionSet(
|
|
Clean(Permissions.AppAssets),
|
|
Clean(Permissions.AppContents),
|
|
Clean(Permissions.AppRolesRead),
|
|
Clean(Permissions.AppWorkflowsRead))),
|
|
[Role.Developer] =
|
|
new Role(Role.Developer, new PermissionSet(
|
|
Clean(Permissions.AppApi),
|
|
Clean(Permissions.AppAssets),
|
|
Clean(Permissions.AppContents),
|
|
Clean(Permissions.AppPatterns),
|
|
Clean(Permissions.AppRolesRead),
|
|
Clean(Permissions.AppRules),
|
|
Clean(Permissions.AppSchemas),
|
|
Clean(Permissions.AppWorkflows)))
|
|
};
|
|
|
|
public static readonly Roles Empty = new Roles(new ImmutableDictionary<string, Role>());
|
|
|
|
public int CustomCount
|
|
{
|
|
get { return inner.Count; }
|
|
}
|
|
|
|
public Role this[string name]
|
|
{
|
|
get { return inner[name]; }
|
|
}
|
|
|
|
public IEnumerable<Role> Custom
|
|
{
|
|
get { return inner.Values; }
|
|
}
|
|
|
|
public IEnumerable<Role> All
|
|
{
|
|
get { return inner.Values.Union(Defaults.Values); }
|
|
}
|
|
|
|
private Roles(ImmutableDictionary<string, Role> roles)
|
|
{
|
|
inner = roles;
|
|
}
|
|
|
|
public Roles(Dictionary<string, Role> roles)
|
|
{
|
|
inner = new ImmutableDictionary<string, Role>(Cleaned(roles));
|
|
}
|
|
|
|
[Pure]
|
|
public Roles Remove(string name)
|
|
{
|
|
return Create(inner.Without(name));
|
|
}
|
|
|
|
[Pure]
|
|
public Roles Add(string name)
|
|
{
|
|
var newRole = new Role(name);
|
|
|
|
if (inner.ContainsKey(name))
|
|
{
|
|
throw new ArgumentException("Name already exists.", nameof(name));
|
|
}
|
|
|
|
if (IsDefault(name))
|
|
{
|
|
return this;
|
|
}
|
|
|
|
return Create(inner.With(name, newRole));
|
|
}
|
|
|
|
[Pure]
|
|
public Roles Update(string name, params string[] permissions)
|
|
{
|
|
Guard.NotNullOrEmpty(name);
|
|
Guard.NotNull(permissions);
|
|
|
|
if (!inner.TryGetValue(name, out var role))
|
|
{
|
|
return this;
|
|
}
|
|
|
|
return Create(inner.With(name, role.Update(permissions), DeepComparer<Role>.Instance));
|
|
}
|
|
|
|
public static bool IsDefault(string role)
|
|
{
|
|
return role != null && Defaults.ContainsKey(role);
|
|
}
|
|
|
|
public static bool IsDefault(Role role)
|
|
{
|
|
return role != null && Defaults.ContainsKey(role.Name);
|
|
}
|
|
|
|
public bool ContainsCustom(string name)
|
|
{
|
|
return inner.ContainsKey(name);
|
|
}
|
|
|
|
public bool Contains(string name)
|
|
{
|
|
return inner.ContainsKey(name) || Defaults.ContainsKey(name);
|
|
}
|
|
|
|
public bool TryGet(string app, string name, [MaybeNullWhen(false)] out Role value)
|
|
{
|
|
Guard.NotNull(app);
|
|
|
|
if (Defaults.TryGetValue(name, out var role) || inner.TryGetValue(name, out role))
|
|
{
|
|
value = role.ForApp(app);
|
|
return true;
|
|
}
|
|
|
|
value = null!;
|
|
|
|
return false;
|
|
}
|
|
|
|
private static string Clean(string permission)
|
|
{
|
|
permission = Permissions.ForApp(permission).Id;
|
|
|
|
var prefix = Permissions.ForApp(Permissions.App);
|
|
|
|
if (permission.StartsWith(prefix.Id, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
permission = permission.Substring(prefix.Id.Length);
|
|
}
|
|
|
|
if (permission.Length == 0)
|
|
{
|
|
return Permission.Any;
|
|
}
|
|
|
|
return permission.Substring(1);
|
|
}
|
|
|
|
private static Dictionary<string, Role> Cleaned(Dictionary<string, Role> inner)
|
|
{
|
|
return inner.Where(x => !Defaults.ContainsKey(x.Key)).ToDictionary(x => x.Key, x => x.Value);
|
|
}
|
|
|
|
private Roles Create(ImmutableDictionary<string, Role> newRoles)
|
|
{
|
|
return ReferenceEquals(inner, newRoles) ? this : new Roles(newRoles);
|
|
}
|
|
}
|
|
}
|
|
|