diff --git a/src/WebExpress.WebCore.Test/Manager/UnitTestIdentityManager.cs b/src/WebExpress.WebCore.Test/Manager/UnitTestIdentityManager.cs index 6e1b337..51c97c2 100644 --- a/src/WebExpress.WebCore.Test/Manager/UnitTestIdentityManager.cs +++ b/src/WebExpress.WebCore.Test/Manager/UnitTestIdentityManager.cs @@ -207,5 +207,73 @@ public void GetCurrentIdentity(string identityName, string password) Assert.Equal(identity, res); } + + /// + /// Test that the AllGroup is not null and has the expected default properties. + /// + [Fact] + public void AllGroupExists() + { + // arrange + var componentHub = UnitTestFixture.CreateAndRegisterComponentHubMock(); + var identityManager = componentHub.IdentityManager; + + // act & assert + Assert.NotNull(identityManager.AllGroup); + Assert.Equal("All", identityManager.AllGroup.Name); + Assert.Equal(Guid.Empty, identityManager.AllGroup.Id); + } + + /// + /// Test that the AllGroup has the PublicAccess policy. + /// + [Fact] + public void AllGroupHasPublicAccessPolicy() + { + // arrange + var componentHub = UnitTestFixture.CreateAndRegisterComponentHubMock(); + var identityManager = componentHub.IdentityManager; + + // act + var policies = identityManager.AllGroup.Policies; + + // assert + Assert.Contains(typeof(PublicAccess).FullName.ToLower(), policies); + } + + /// + /// Test that the IIdentityGroup interface has the Id and Name properties. + /// + [Fact] + public void IIdentityGroupHasIdAndName() + { + // arrange + var group = MockIdentityFactory.GetIdentityGroup("Admins"); + + // act & assert + Assert.NotNull(group); + Assert.IsAssignableFrom(group); + Assert.NotEqual(Guid.Empty, group.Id); + Assert.Equal("Admins", group.Name); + } + + /// + /// Test that the AllGroup has the expected name and contains the PublicAccess policy. + /// + [Fact] + public void AllGroupHasExpectedProperties() + { + // arrange + var componentHub = UnitTestFixture.CreateAndRegisterComponentHubMock(); + var identityManager = componentHub.IdentityManager as IdentityManager; + + // act + var allGroup = identityManager.AllGroup; + + // assert + Assert.NotNull(allGroup); + Assert.Equal("All", allGroup.Name); + Assert.Contains(typeof(PublicAccess).FullName.ToLower(), allGroup.Policies); + } } } diff --git a/src/WebExpress.WebCore/Internationalization/de b/src/WebExpress.WebCore/Internationalization/de index cb7a647..4c59fea 100644 --- a/src/WebExpress.WebCore/Internationalization/de +++ b/src/WebExpress.WebCore/Internationalization/de @@ -165,6 +165,12 @@ identitymanager.registerpermission=Die Berechtigung '{0}' wurde der Anwendung '{ identitymanager.duplicatepermission=Die Berechtigung '{0}' wurde bereits in der Anwendung '{1}' registriert. identitymanager.registerpolicy=Die Policy '{0}' wurde der Anwendung '{1}' zugewiesen und im Identitymanager registriert. identitymanager.duplicatepolicy=Die Policy '{0}' wurde bereits in der Anwendung '{1}' registriert. +identitymanager.policy.publicaccess.name=Öffentlicher Zugang +identitymanager.policy.publicaccess.description=Policy für den Zugriff auf öffentliche Ressourcen ohne Authentifizierung. +identitymanager.policy.authenticatedaccess.name=Authentifizierter Zugang +identitymanager.policy.authenticatedaccess.description=Policy für den allgemeinen Zugriff durch authentifizierte Benutzer. +identitymanager.policy.systemaccess.name=Systemzugang +identitymanager.policy.systemaccess.description=Policy für Operationen auf Systemebene wie Installation, Aktualisierung und Wartung der Anwendung. includemanager.initialization=Der Includemanager wurde initialisiert. includemanager.addinclude=Die Client-Ressource '{0}' wurde in der Anwendung '{1}' registiert. diff --git a/src/WebExpress.WebCore/Internationalization/en b/src/WebExpress.WebCore/Internationalization/en index 155cdbf..376d2d9 100644 --- a/src/WebExpress.WebCore/Internationalization/en +++ b/src/WebExpress.WebCore/Internationalization/en @@ -165,6 +165,12 @@ identitymanager.registerpermission=The permission '{0}' has been assigned to the identitymanager.duplicatepermission=The permission '{0}' has already been registered in the application '{1}'. identitymanager.registerpolicy=The policy '{0}' has been assigned to the application '{1}' and registered in the identity manager. identitymanager.duplicatepolicy=The policy '{0}' has already been registered in the application '{1}'. +identitymanager.policy.publicaccess.name=Public Access +identitymanager.policy.publicaccess.description=Policy for accessing public resources without authentication. +identitymanager.policy.authenticatedaccess.name=Authenticated Access +identitymanager.policy.authenticatedaccess.description=Policy for general access by authenticated users. +identitymanager.policy.systemaccess.name=System Access +identitymanager.policy.systemaccess.description=Policy for system-level operations such as installing, updating, and maintaining the application. includemanager.initialization=The include manager has been initialized. includemanager.addinclude=The client resource '{0}' has been registered in the application '{1}'. diff --git a/src/WebExpress.WebCore/WebIdentity/AuthenticatedAccess.cs b/src/WebExpress.WebCore/WebIdentity/AuthenticatedAccess.cs new file mode 100644 index 0000000..a40bf65 --- /dev/null +++ b/src/WebExpress.WebCore/WebIdentity/AuthenticatedAccess.cs @@ -0,0 +1,19 @@ +using WebExpress.WebCore.WebAttribute; + +namespace WebExpress.WebCore.WebIdentity +{ + /// + /// Standard policy for general access by authenticated users. + /// + [Name("webexpress.webcore:identitymanager.policy.authenticatedaccess.name")] + [Description("webexpress.webcore:identitymanager.policy.authenticatedaccess.description")] + public sealed class AuthenticatedAccess : IIdentityPolicy + { + /// + /// Releases all resources used by the current instance of the class. + /// + public void Dispose() + { + } + } +} diff --git a/src/WebExpress.WebCore/WebIdentity/IIdentityGroup.cs b/src/WebExpress.WebCore/WebIdentity/IIdentityGroup.cs index 72fea02..30bd39f 100644 --- a/src/WebExpress.WebCore/WebIdentity/IIdentityGroup.cs +++ b/src/WebExpress.WebCore/WebIdentity/IIdentityGroup.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace WebExpress.WebCore.WebIdentity { @@ -7,6 +8,16 @@ namespace WebExpress.WebCore.WebIdentity /// public interface IIdentityGroup { + /// + /// Returns the id of the group. + /// + Guid Id { get; } + + /// + /// Returns the name of the group. + /// + string Name { get; } + /// /// Returns the policies associated with the group. /// diff --git a/src/WebExpress.WebCore/WebIdentity/IIdentityManager.cs b/src/WebExpress.WebCore/WebIdentity/IIdentityManager.cs index 7e924ed..96f3540 100644 --- a/src/WebExpress.WebCore/WebIdentity/IIdentityManager.cs +++ b/src/WebExpress.WebCore/WebIdentity/IIdentityManager.cs @@ -27,6 +27,11 @@ public interface IIdentityManager : IComponentManager /// IEnumerable Identities { get; } + /// + /// Returns the default "All" group to which every identity automatically belongs. + /// + IdentityGroupAll AllGroup { get; } + /// /// Returns the current signed-in identity. /// diff --git a/src/WebExpress.WebCore/WebIdentity/IIdentityPolicyContext.cs b/src/WebExpress.WebCore/WebIdentity/IIdentityPolicyContext.cs index d6e9fdb..0244b18 100644 --- a/src/WebExpress.WebCore/WebIdentity/IIdentityPolicyContext.cs +++ b/src/WebExpress.WebCore/WebIdentity/IIdentityPolicyContext.cs @@ -1,4 +1,5 @@ -using WebExpress.WebCore.WebApplication; +using System; +using WebExpress.WebCore.WebApplication; using WebExpress.WebCore.WebComponent; using WebExpress.WebCore.WebPlugin; @@ -14,6 +15,11 @@ public interface IIdentityPolicyContext : IContext /// IComponentId PolicyId { get; } + /// + /// Returns the policy type. + /// + Type Policy { get; } + /// /// Returns the associated plugin context. /// diff --git a/src/WebExpress.WebCore/WebIdentity/IdentityGroupAll.cs b/src/WebExpress.WebCore/WebIdentity/IdentityGroupAll.cs new file mode 100644 index 0000000..74c9f1c --- /dev/null +++ b/src/WebExpress.WebCore/WebIdentity/IdentityGroupAll.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace WebExpress.WebCore.WebIdentity +{ + /// + /// Represents the default "All" group to which every identity automatically belongs. + /// + public class IdentityGroupAll : IIdentityGroup + { + /// + /// Returns the id of the group. + /// + public Guid Id { get; } = Guid.Empty; + + /// + /// Returns the name of the group. + /// + public string Name => "All"; + + /// + /// Returns the policies associated with the group. + /// + public IEnumerable Policies { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The policies to associate with the group. + internal IdentityGroupAll(IEnumerable policies) + { + Policies = policies?.ToList() ?? []; + } + } +} diff --git a/src/WebExpress.WebCore/WebIdentity/IdentityManager.cs b/src/WebExpress.WebCore/WebIdentity/IdentityManager.cs index c368881..18dc42d 100644 --- a/src/WebExpress.WebCore/WebIdentity/IdentityManager.cs +++ b/src/WebExpress.WebCore/WebIdentity/IdentityManager.cs @@ -27,6 +27,11 @@ public class IdentityManager : IIdentityManager private readonly IdentityPermissionDictionary _permissionDictionary = []; private readonly IdentityPolicyDictionary _policyDictionary = []; + /// + /// Returns the default "All" group to which every identity automatically belongs. + /// + public IdentityGroupAll AllGroup { get; } = new IdentityGroupAll([typeof(PublicAccess).FullName.ToLower()]); + /// /// Returns all permissions. /// @@ -229,7 +234,8 @@ private void Register(IPluginContext pluginContext, IEnumerable(IApplicationContext applicationContext, IIdentity ide } /// - /// Checks whether the given identity has the specified permission by evaluating all associated groups. + /// Checks whether the given identity has the specified permission by evaluating all associated groups, + /// including the default "All" group to which every identity automatically belongs. /// /// The context of the application. /// The identity to check. @@ -445,7 +452,9 @@ public bool CheckAccess(IApplicationContext applicationContext, IIdentity ide /// True if any group grants the permission, false otherwise. public bool CheckAccess(IApplicationContext applicationContext, IIdentity identity, Type permission) { - return (identity?.Groups ?? []).Any(group => CheckAccess(applicationContext, group, permission)); + var groups = (identity?.Groups ?? []).Append(AllGroup); + + return groups.Any(group => CheckAccess(applicationContext, group, permission)); } /// diff --git a/src/WebExpress.WebCore/WebIdentity/IdentityPolicyContext.cs b/src/WebExpress.WebCore/WebIdentity/IdentityPolicyContext.cs index fb54336..80d535e 100644 --- a/src/WebExpress.WebCore/WebIdentity/IdentityPolicyContext.cs +++ b/src/WebExpress.WebCore/WebIdentity/IdentityPolicyContext.cs @@ -1,4 +1,5 @@ -using WebExpress.WebCore.WebApplication; +using System; +using WebExpress.WebCore.WebApplication; using WebExpress.WebCore.WebComponent; using WebExpress.WebCore.WebPlugin; @@ -14,6 +15,11 @@ public class IdentityPolicyContext : IIdentityPolicyContext /// public IComponentId PolicyId { get; internal set; } + /// + /// Returns the policy type. + /// + public Type Policy { get; internal set; } + /// /// Returns the associated plugin context. /// diff --git a/src/WebExpress.WebCore/WebIdentity/PublicAccess.cs b/src/WebExpress.WebCore/WebIdentity/PublicAccess.cs new file mode 100644 index 0000000..08286ad --- /dev/null +++ b/src/WebExpress.WebCore/WebIdentity/PublicAccess.cs @@ -0,0 +1,19 @@ +using WebExpress.WebCore.WebAttribute; + +namespace WebExpress.WebCore.WebIdentity +{ + /// + /// Standard policy for accessing public resources without authentication. + /// + [Name("webexpress.webcore:identitymanager.policy.publicaccess.name")] + [Description("webexpress.webcore:identitymanager.policy.publicaccess.description")] + public sealed class PublicAccess : IIdentityPolicy + { + /// + /// Releases all resources used by the current instance of the class. + /// + public void Dispose() + { + } + } +} diff --git a/src/WebExpress.WebCore/WebIdentity/SystemAccess.cs b/src/WebExpress.WebCore/WebIdentity/SystemAccess.cs new file mode 100644 index 0000000..bb3de07 --- /dev/null +++ b/src/WebExpress.WebCore/WebIdentity/SystemAccess.cs @@ -0,0 +1,19 @@ +using WebExpress.WebCore.WebAttribute; + +namespace WebExpress.WebCore.WebIdentity +{ + /// + /// Standard policy for system-level operations such as installing, updating, and maintaining the application. + /// + [Name("webexpress.webcore:identitymanager.policy.systemaccess.name")] + [Description("webexpress.webcore:identitymanager.policy.systemaccess.description")] + public sealed class SystemAccess : IIdentityPolicy + { + /// + /// Releases all resources used by the current instance of the class. + /// + public void Dispose() + { + } + } +}