diff --git a/src/Moryx.ClientFramework.Kernel/HeartOfLead.cs b/src/Moryx.ClientFramework.Kernel/HeartOfLead.cs index b70d221..3358dbc 100644 --- a/src/Moryx.ClientFramework.Kernel/HeartOfLead.cs +++ b/src/Moryx.ClientFramework.Kernel/HeartOfLead.cs @@ -2,8 +2,10 @@ // Licensed under the Apache License, Version 2.0 using System; +using System.Configuration; using System.Diagnostics; using System.Globalization; +using System.IdentityModel.Configuration; using System.IO; using System.Linq; using System.Reflection; @@ -109,6 +111,9 @@ public void Initialize() // Will parse the exe arguments ParseCommandLineArguments(); + // Will prepare config for authorization + PrepareAuthorization(); + // Create global container and configure config manager CreateContainer(); @@ -190,6 +195,29 @@ private void ParseCommandLineArguments() Environment.Exit(1); } + /// + /// Initializes configuration for authorization + /// + private static void PrepareAuthorization() + { + var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + const string sectionName = "system.identityModel"; + try + { + if (config.Sections.Get(sectionName) == null) + { + config.Sections.Add(sectionName, new SystemIdentityModelSection()); + config.Save(); + ConfigurationManager.RefreshSection(sectionName); + } + } + catch + { + //Error during authorization preparation + throw; + } + } + /// /// Configures the thread context. /// diff --git a/src/Moryx.ClientFramework.Kernel/HeartOfLeadExtension.cs b/src/Moryx.ClientFramework.Kernel/HeartOfLeadExtension.cs index 68c4a0f..559b8a2 100644 --- a/src/Moryx.ClientFramework.Kernel/HeartOfLeadExtension.cs +++ b/src/Moryx.ClientFramework.Kernel/HeartOfLeadExtension.cs @@ -1,11 +1,11 @@ -using System; -using System.Configuration; -using System.IdentityModel.Configuration; -using System.IdentityModel.Services; +using System.IdentityModel.Services; using System.Security.Claims; namespace Moryx.ClientFramework.Kernel { + /// + /// Extensions for the + /// public static class HeartOfLeadExtension { /// @@ -13,32 +13,7 @@ public static class HeartOfLeadExtension /// public static void EnableAuthorization(this HeartOfLead hol, ClaimsAuthorizationManager authorizationManager) { - var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); - var sectionName = "system.identityModel"; - try - { - if (config.Sections.Get(sectionName) == null) - { - config.Sections.Add(sectionName, new SystemIdentityModelSection()); - config.Save(); - ConfigurationManager.RefreshSection(sectionName); - } - if (authorizationManager != null) - FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthorizationManager = authorizationManager; - } - catch (Exception e) - { - //Error during authorization preparation - throw; - } - } - - /// - /// Method to authorize the current principal to perform every action on any resource - /// - public static void AuthorizeEverything(this HeartOfLead hol) - { - hol.EnableAuthorization(null); + FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthorizationManager = authorizationManager; } } } diff --git a/src/Moryx.ClientFramework/Principals/BooleanPermissionExtension.cs b/src/Moryx.ClientFramework/Principals/BooleanPermissionExtension.cs index 332bb0c..d5b4471 100644 --- a/src/Moryx.ClientFramework/Principals/BooleanPermissionExtension.cs +++ b/src/Moryx.ClientFramework/Principals/BooleanPermissionExtension.cs @@ -8,7 +8,7 @@ namespace Moryx.ClientFramework.Principals /// /// Extension to determine the boolean result depends to the permission /// - public class BooleanPermissionExtension : PermissionExtension + public class BooleanPermissionExtension : PermissionExtensionBase { /// /// Flag to inverse the boolean result diff --git a/src/Moryx.ClientFramework/Principals/GridLengthPermissionExtension.cs b/src/Moryx.ClientFramework/Principals/GridLengthPermissionExtension.cs index 5faf487..9b284a5 100644 --- a/src/Moryx.ClientFramework/Principals/GridLengthPermissionExtension.cs +++ b/src/Moryx.ClientFramework/Principals/GridLengthPermissionExtension.cs @@ -8,7 +8,7 @@ namespace Moryx.ClientFramework.Principals /// /// Extension to determine the length of a grid depends to the permission /// - public class GridLengthPermissionExtension : PermissionExtension + public class GridLengthPermissionExtension : PermissionExtensionBase { /// protected override object ProvidePermissionBasedValue(bool hasPermission) diff --git a/src/Moryx.ClientFramework/Principals/PermissionExtension.cs b/src/Moryx.ClientFramework/Principals/PermissionExtensionBase.cs similarity index 84% rename from src/Moryx.ClientFramework/Principals/PermissionExtension.cs rename to src/Moryx.ClientFramework/Principals/PermissionExtensionBase.cs index a9d80a3..81774de 100644 --- a/src/Moryx.ClientFramework/Principals/PermissionExtension.cs +++ b/src/Moryx.ClientFramework/Principals/PermissionExtensionBase.cs @@ -6,7 +6,6 @@ using System.Reflection; using System.Text.RegularExpressions; using System.Windows; -using System.Windows.Controls; using System.Windows.Markup; using System.Xaml; @@ -15,7 +14,7 @@ namespace Moryx.ClientFramework.Principals /// /// Base class for permission based value determination /// - public abstract class PermissionExtension : MarkupExtension + public abstract class PermissionExtensionBase : MarkupExtension { #region Fields and Properties @@ -39,9 +38,9 @@ public abstract class PermissionExtension : MarkupExtension /// /// Constructor to prepare the extension to get information about changed principals /// - protected PermissionExtension() + protected PermissionExtensionBase() { - ClaimsPrincipalSync.PrincipalChanged += OnPrincipalChanged; + ClaimsPrincipalSync.PrincipalChanged += OnPrincipalChanged; } private void OnPrincipalChanged(object sender, EventArgs args) @@ -70,14 +69,17 @@ private void OnPrincipalChanged(object sender, EventArgs args) public override object ProvideValue(IServiceProvider serviceProvider) { // If resource was not specified, tried to determine from host control - if (Resource == null && serviceProvider.GetService(typeof(IRootObjectProvider)) is IRootObjectProvider root) + if (string.IsNullOrEmpty(Resource) && serviceProvider.GetService(typeof(IRootObjectProvider)) is IRootObjectProvider root) { - // Try to read from user control permissions - if (root.RootObject is UserControl control && control.Resources[UserControlPermissions.Key] is UserControlPermissions controlPermissions) + // Try to read from root attached property + var rootElement = root.RootObject as DependencyObject; + var defaultResource = rootElement?.GetValue(PermissionProvider.DefaultResourceProperty); + if (defaultResource != null) { - Resource = controlPermissions.Resource; + Resource = (string) defaultResource; } - else + + if (string.IsNullOrEmpty(Resource)) { var regex = new Regex(@"^\w+\.\w+"); Resource = regex.Match(root.RootObject?.GetType().Namespace ?? "Moryx").Value; diff --git a/src/Moryx.ClientFramework/Principals/PermissionProvider.cs b/src/Moryx.ClientFramework/Principals/PermissionProvider.cs new file mode 100644 index 0000000..13994ca --- /dev/null +++ b/src/Moryx.ClientFramework/Principals/PermissionProvider.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2021, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using System.Windows; + +namespace Moryx.ClientFramework.Principals +{ + /// + /// Class to provide attached dependency property for permission based authorization + /// + public class PermissionProvider : DependencyObject + { + /// + /// Property to handle the default resource for the + /// + public static readonly DependencyProperty DefaultResourceProperty = DependencyProperty.RegisterAttached( + "DefaultResource", typeof(string), typeof(PermissionProvider), new PropertyMetadata(default(string))); + + /// + /// Sets the default resource + /// + public static void SetDefaultResource(DependencyObject element, string value) + { + element.SetValue(DefaultResourceProperty, value); + } + + /// + /// Returns the default resource + /// + public static string GetDefaultResource(DependencyObject element) + { + return (string) element.GetValue(DefaultResourceProperty); + } + } +} \ No newline at end of file diff --git a/src/Moryx.ClientFramework/Principals/UserControlPermissions.cs b/src/Moryx.ClientFramework/Principals/UserControlPermissions.cs deleted file mode 100644 index 9b000c6..0000000 --- a/src/Moryx.ClientFramework/Principals/UserControlPermissions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Windows.Controls; - -namespace Moryx.ClientFramework.Principals -{ - /// - /// Class for the resource dictionary of a - /// - public class UserControlPermissions - { - /// - /// Standard key to be found by the markup extension - /// - public const string Key = "Permissions"; - - /// - /// Resource applied to all instances of unless specified - /// - public string Resource { get; set; } - } -} \ No newline at end of file diff --git a/src/Moryx.ClientFramework/Principals/VisibilityPermissionExtension.cs b/src/Moryx.ClientFramework/Principals/VisibilityPermissionExtension.cs index 63c17ee..90eb856 100644 --- a/src/Moryx.ClientFramework/Principals/VisibilityPermissionExtension.cs +++ b/src/Moryx.ClientFramework/Principals/VisibilityPermissionExtension.cs @@ -9,7 +9,7 @@ namespace Moryx.ClientFramework.Principals /// /// Extension to determine the visibility depends to the permission /// - public class VisibilityPermissionExtension : PermissionExtension + public class VisibilityPermissionExtension : PermissionExtensionBase { /// /// Flag to inverse the visibility result