Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
dbeuchler committed Oct 7, 2021
2 parents a5232c9 + 00b0204 commit 792be03
Show file tree
Hide file tree
Showing 18 changed files with 399 additions and 19 deletions.
4 changes: 2 additions & 2 deletions .build/BuildToolkit.ps1
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Tool Versions
$NunitVersion = "3.11.1";
$NunitVersion = "3.12.0";
$OpenCoverVersion = "4.7.922";
$DocFxVersion = "2.56.2";
$ReportGeneratorVersion = "4.6.7";
$ReportGeneratorVersion = "4.8.7";

# Folder Pathes
$RootPath = $MyInvocation.PSScriptRoot;
Expand Down
8 changes: 4 additions & 4 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project>

<PropertyGroup>
<MoryxPlatformVersion>3.0.0</MoryxPlatformVersion>
<MoryxCoreVersion>3.2.0</MoryxCoreVersion>
</PropertyGroup>

<Import Project=".build\Common.props" Condition="'$(CreatePackage)' == 'true'" />
Expand All @@ -24,9 +24,9 @@
<PackageReference Update="NUnit3TestAdapter" Version="3.17.0" />

<!--Platform dependencies-->
<PackageReference Update="Moryx" Version="$(MoryxPlatformVersion)" />
<PackageReference Update="Moryx.Tools.Wcf" Version="$(MoryxPlatformVersion)" />
<PackageReference Update="Moryx.Container" Version="$(MoryxPlatformVersion)" />
<PackageReference Update="Moryx" Version="$(MoryxCoreVersion)" />
<PackageReference Update="Moryx.Tools.Wcf" Version="$(MoryxCoreVersion)" />
<PackageReference Update="Moryx.Container" Version="$(MoryxCoreVersion)" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion Directory.build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.1
3.1.0
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public LocalConfigProvider(IConfigManager configManager, ModulesConfiguration mo
_configManager = configManager;
}

///
/// <inheritdoc />
public T GetModuleConfiguration<T>(string name) where T : class, IClientModuleConfig, new()
{
var config = GetConfiguration<T>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Moryx.Identity;

namespace Moryx.ClientFramework.Kernel
{
/// <summary>
/// Extensions for the <see cref="HeartOfLead"/>
/// </summary>
public static class ApplicationRuntimeExtensions
{
/// <summary>
/// Method to register a custom ClaimsAuthorizationManager
/// </summary>
public static void EnableAuthorization(this IApplicationRuntime hol, IAuthorizationContext authorizationContext)
{
IdentityConfiguration.CurrentContext = authorizationContext;
}
}
}
19 changes: 13 additions & 6 deletions src/Moryx.ClientFramework.Kernel/HeartOfLead.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Caliburn.Micro;
using CommandLine;
using Moryx.ClientFramework.Localization;
using Moryx.Configuration;
using Moryx.Container;
using Moryx.Logging;
using Moryx.Threading;
Expand All @@ -24,7 +25,7 @@
namespace Moryx.ClientFramework.Kernel
{
/// <summary>
/// Main class to create ClientFramwork UI's
/// Main class to create ClientFramework UIs
/// </summary>
public class HeartOfLead : HeartOfLead<DefaultCommandLineArguments>
{
Expand All @@ -35,16 +36,21 @@ public HeartOfLead(string[] args) : base(args)
}

/// <summary>
/// Main class to create ClientFramwork UI's
/// Main class to create ClientFramework UIs
/// </summary>
public class HeartOfLead<TCommandLineArguments> : ILoggingHost
public class HeartOfLead<TCommandLineArguments> : IApplicationRuntime, ILoggingHost
where TCommandLineArguments : DefaultCommandLineArguments
{
#region Fields and Properties

string ILoggingHost.Name => "ClientKernel";

/// <inheritdoc />
IModuleLogger ILoggingHost.Logger { get; set; }

/// <inheritdoc />
IContainer IApplicationRuntime.GlobalContainer => _container;

/// <summary>
/// Returns the current <see cref="AppConfig"/>
/// </summary>
Expand All @@ -58,7 +64,7 @@ public class HeartOfLead<TCommandLineArguments> : ILoggingHost
/// <summary>
/// Flag if the HeartOfLead is initialized
/// </summary>
public bool IsInitialied { get; private set; }
public bool IsInitialied { get; private set; } // TODO: Rename to IsInitialized in the next major

private GlobalContainer _container;
private IKernelConfigManager _configManager;
Expand Down Expand Up @@ -100,7 +106,7 @@ public void Initialize()
if (IsInitialied)
throw new InvalidOperationException("HeartOfLead is already initialized!");

// Initialize platfrom
// Initialize platform
WpfPlatform.SetProduct();

// Attach this Application to the console.
Expand Down Expand Up @@ -331,7 +337,8 @@ private void LoadConfiguration()

// Configure config manager
_configManager = new KernelConfigManager { ConfigDirectory = CommandLineOptions.ConfigFolder };
_container.SetInstance(_configManager);
_container.SetInstance<IKernelConfigManager>(_configManager, "KernelConfigManager");
_container.SetInstance<IConfigManager>(_configManager, "ConfigManager");

// Load global app config
AppConfig = _configManager.GetConfiguration<AppConfig>();
Expand Down
2 changes: 1 addition & 1 deletion src/Moryx.ClientFramework.Kernel/RunMode/LocalRunMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ protected override Predicate<Type> TypeLoadFilter
get { return type => type.GetCustomAttribute<ComponentForRunModeAttribute>() == null; }
}

/// <inheritdoc />
/// <inheritdoc />
public override void LoadModulesConfiguration()
{
var modulesConfig = ConfigManager.GetConfiguration<ModulesConfiguration>();
Expand Down
6 changes: 3 additions & 3 deletions src/Moryx.ClientFramework.Kernel/RunMode/LocalRunModeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Moryx.ClientFramework.Kernel
{
/// <summary>
/// Base class for local run modes.
/// Base class for local run modes.
/// Will load <see cref="IClientModule"/> and <see cref="IModuleShell"/> from the app domain
/// </summary>
public abstract class LocalRunModeBase : RunModeBase
Expand All @@ -21,7 +21,7 @@ public abstract class LocalRunModeBase : RunModeBase
/// <summary>
/// Config manager to load kernel configurations
/// </summary>
public IKernelConfigManager ConfigManager { get; set; }
public IKernelConfigManager ConfigManager { get; set; } // TODO: Change type to IConfigManager in future

#endregion

Expand Down Expand Up @@ -75,7 +75,7 @@ public override void Initialize()
///
public override void LoadModulesConfiguration()
{

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=module_005Cnewfolder1/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=module_005C_0023/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=module_005Cdummy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=principals_005Cmarkup/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=region/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=ScreenPlugin/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=shell_005Cabout/@EntryIndexedValue">True</s:Boolean>
Expand Down
25 changes: 25 additions & 0 deletions src/Moryx.ClientFramework/Principals/BooleanPermissionExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2021, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System.Windows.Markup;

namespace Moryx.ClientFramework.Principals
{
/// <summary>
/// Extension to determine the boolean result depends to the permission
/// </summary>
public class BooleanPermissionExtension : PermissionExtensionBase
{
/// <summary>
/// Flag to inverse the boolean result
/// </summary>
[ConstructorArgument("Inverse")]
public bool Inverse { get; set; }

/// <inheritdoc />
protected override object ProvidePermissionBasedValue(bool hasPermission)
{
return Inverse ? !hasPermission : hasPermission;
}
}
}
26 changes: 26 additions & 0 deletions src/Moryx.ClientFramework/Principals/ClaimsPrincipalSync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2021, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System;

namespace Moryx.ClientFramework.Principals
{
/// <summary>
/// Helper to inform the UI about an update of the ClaimsPrincipal
/// </summary>
public static class ClaimsPrincipalSync
{
/// <summary>
/// Event to get informed about an update of the ClaimsPrincipal
/// </summary>
public static event EventHandler PrincipalChanged;

/// <summary>
/// Method to invoke an event after an update of the ClaimsPrincipal
/// </summary>
public static void OnClaimsPrincipalChanged()
{
PrincipalChanged?.Invoke(typeof(ClaimsPrincipalSync), EventArgs.Empty);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2021, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System.Windows;

namespace Moryx.ClientFramework.Principals
{
/// <summary>
/// Extension to determine the length of a grid depends to the permission
/// </summary>
public class GridLengthPermissionExtension : PermissionExtensionBase
{
/// <inheritdoc />
protected override object ProvidePermissionBasedValue(bool hasPermission)
{
return hasPermission ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
}
}
}
112 changes: 112 additions & 0 deletions src/Moryx.ClientFramework/Principals/PermissionExtensionBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) 2021, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Markup;
using System.Xaml;
using Moryx.Identity;

namespace Moryx.ClientFramework.Principals
{
/// <summary>
/// Base class for permission based value determination
/// </summary>
public abstract class PermissionExtensionBase : MarkupExtension
{
#region Fields and Properties

private object _targetObject;

private object _targetProperty;

/// <summary>
/// Resource within the action requires permissions
/// </summary>
public string Resource { get; set; }

/// <summary>
/// The requested action which will be validated by the current permissions
/// </summary>
[ConstructorArgument("action")]
public string Action { get; set; }

#endregion

/// <summary>
/// Constructor to prepare the extension to get information about changed principals
/// </summary>
protected PermissionExtensionBase()
{
ClaimsPrincipalSync.PrincipalChanged += OnPrincipalChanged;
}

private void OnPrincipalChanged(object sender, EventArgs args)
{
if (!(_targetObject is DependencyObject targetObject))
return;

// Current determined value to update
var value = ProvidePermissionBasedValue(HasPermission());
if (_targetProperty is DependencyProperty targetProperty)
{
// Update directly if can be accessed otherwise invoke the dispatcher
if (targetObject.CheckAccess())
targetObject.SetValue(targetProperty, value);
else
targetObject.Dispatcher.Invoke(() => targetObject.SetValue(targetProperty, value));
}
else
{
var propertyInfo = _targetProperty as PropertyInfo;
propertyInfo?.SetValue(targetObject, value, null);
}
}

/// <inheritdoc />
public override object ProvideValue(IServiceProvider serviceProvider)
{
// If resource was not specified, tried to determine from host control
if (string.IsNullOrEmpty(Resource) && serviceProvider.GetService(typeof(IRootObjectProvider)) is IRootObjectProvider root)
{
// Try to read from root attached property
var rootElement = root.RootObject as DependencyObject;
var defaultResource = rootElement?.GetValue(PermissionProvider.DefaultResourceProperty);
if (defaultResource != null)
{
Resource = (string) defaultResource;
}

if (string.IsNullOrEmpty(Resource))
{
var regex = new Regex(@"^\w+\.\w+");
Resource = regex.Match(root.RootObject?.GetType().Namespace ?? "Moryx").Value;
}
}

if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target)
{
_targetObject = target.TargetObject;
_targetProperty = target.TargetProperty;
}

var hasPermission = HasPermission();
return ProvidePermissionBasedValue(hasPermission);
}

private bool HasPermission()
{
if (IdentityConfiguration.CurrentContext != null)
return IdentityConfiguration.CurrentContext.CheckAccess(Resource, Action);

return true;
}

/// <summary>
/// Get the permission based value
/// </summary>
protected abstract object ProvidePermissionBasedValue(bool hasPermission);
}
}
Loading

0 comments on commit 792be03

Please sign in to comment.