This commit is contained in:
Meik
2025-11-11 11:03:42 +01:00
commit dc3e8a2e4c
582 changed files with 191465 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
<Window x:Class="FasdDesktopUi.Pages.M42AuthenticationPage.F4sdM42FormsAuthentication"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
xmlns:local="clr-namespace:FasdDesktopUi.Pages.M42AuthenticationPage"
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
xmlns:WebView="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="M42FomsAuthetication"
ResizeMode="CanResizeWithGrip"
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
MinHeight="800"
MinWidth="800"
ShowInTaskbar="False"
Topmost="True"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen"
d:DesignHeight="450"
d:DesignWidth="800"
x:Name="F4sdM42FormsAuth"
>
<Window.Resources>
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
</Window.Resources>
<Border
CornerRadius="10"
Background="{DynamicResource BackgroundColor.Menu.Categories}"
Padding="10"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="TextHeader" x:FieldModifier="private" Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=M42Settings.FormsAuthentication.Header}" FontSize="18" VerticalAlignment="Center" Margin="10 0 0 0" FontWeight="Bold"/>
<ico:AdaptableIcon
x:Name="butRefresh"
Grid.Column="1"
SelectedInternIcon="menuBar_refresh"
Padding="0" Margin="4 2"
IconHeight="30" IconWidth="30"
Style="{DynamicResource SettingsPage.Close.Icon}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Background="#01000000"
MouseLeftButtonUp="butRefresh_MouseLeftButtonUp"
Cursor="Hand"
ToolTip="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=M42Settings.Header.RefreshForm}"
/>
<ico:AdaptableIcon
x:Name="butClearCookies"
Grid.Column="2"
SelectedMaterialIcon="ic_delete_forever"
Padding="0" Margin="4 2"
Style="{DynamicResource SettingsPage.Close.Icon}"
IconHeight="30" IconWidth="30"
HorizontalAlignment="Center" VerticalAlignment="Center"
Background="#01000000"
MouseLeftButtonUp="butClearCookies_MouseLeftButtonUp"
ToolTip="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=M42Settings.Header.ClearCookies}"
/>
<ico:AdaptableIcon Grid.Column="3"
SelectedInternIcon="window_close"
Padding="0" Margin="4 2"
Style="{DynamicResource SettingsPage.Close.Icon}"
IconHeight="30"
IconWidth="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="#01000000"
MouseLeftButtonUp="CloseIcon_MouseLeftButtonUp"
/>
</Grid>
<Border Grid.Row="1"
CornerRadius="7.5"
Background="{DynamicResource BackgroundColor.Menu.MainCategory}"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="249*"/>
<ColumnDefinition Width="11*"/>
</Grid.ColumnDefinitions>
<WebView:WebView2
x:Name="WebLogon" x:FieldModifier="private"
Loaded="WebLogon_Loaded"
NavigationStarting="WebLogon_NavigationStarting"
Margin="10,10,10,10"
Grid.ColumnSpan="2"
/>
<Border
x:Name="NoAccessTokenMessage" x:FieldModifier="private"
Margin="197,0,0,0"
HorizontalAlignment="Left" VerticalAlignment="Center"
Background="{DynamicResource BackgroundColor.Menu.Categories}"
CornerRadius="7.5"
>
<TextBlock
FontSize="20"
Foreground="Red"
TextWrapping="WrapWithOverflow"
Margin="10"
Text="Could not get a valid authorisation token."
/>
</Border>
</Grid>
</Border>
</Grid>
</Border>
</Window>

View File

@@ -0,0 +1,333 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using C4IT.FASD.Base;
using C4IT.FASD.Cockpit.Communication;
using C4IT.Logging;
using C4IT.Matrix42.WebClient;
using C4IT.MultiLanguage;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using FasdDesktopUi.Pages.SettingsPage;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Pages.M42AuthenticationPage
{
public partial class F4sdM42FormsAuthentication : Window
{
private string _M42Server = null;
private Uri _logonUrl = null;
private bool regainToken = false;
private cM42UserInfoResult userInfoM42 = null;
private bool Reauthenticate = false;
public cF4SdUserInfoChange UserInfoChange { get; private set; } = null;
public F4sdM42FormsAuthentication(bool Reauthenticate)
{
InitializeComponent();
NoAccessTokenMessage.Visibility = Visibility.Collapsed;
this.Reauthenticate = Reauthenticate;
}
private void CloseIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
DialogResult = false;
Close();
}
private void StartForm()
{
_logonUrl = new Uri($"https://{_M42Server}/m42Services/api/sts/authorize?client_id=ServiceStore.NewUX&scope=urn:matrix42NewUX&response_type=token&autoLogin=true");
WebLogon.Source = _logonUrl;
}
private async void WebLogon_Loaded(object sender, RoutedEventArgs e)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// set the data path for the WebView2 component
var _webViewConfigPath = cLogManagerFile.GetDefaultPath(false, SubFolder: "WebViewData");
_webViewConfigPath = System.IO.Path.GetDirectoryName(_webViewConfigPath);
CultureInfo culture = new CultureInfo(cMultiLanguageSupport.CurrentLanguage);
var webEnv = await CoreWebView2Environment.CreateAsync(userDataFolder: _webViewConfigPath, options: new CoreWebView2EnvironmentOptions() { Language = culture.TextInfo.CultureName, AllowSingleSignOnUsingOSPrimaryAccount = true });
var _co = webEnv.CreateCoreWebView2ControllerOptions();
await WebLogon.EnsureCoreWebView2Async(webEnv, _co);
// modify the header text
if (Reauthenticate)
{
TextHeader.Text = cMultiLanguageSupport.GetItem("M42Settings.FormsAuthentication.HeaderResign");
this.ShowInTaskbar = true;
}
// check if we have a correct M42 config
_M42Server = cCockpitConfiguration.Instance?.m42ServerConfiguration?.Server;
if (string.IsNullOrEmpty(_M42Server) || cFasdCockpitCommunicationBase.CockpitUserInfo == null)
{
Close();
return; ;
}
// start the logon page
StartForm();
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
private async void WebLogon_NavigationStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs e)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var _u = e.Uri;
Debug.WriteLine($"nav.start: {_u}");
var _uri = new Uri(_u);
var _host = _uri.Host.ToLowerInvariant();
var _path = _uri.LocalPath.ToLowerInvariant();
var _frag = _uri.Fragment;
var _query = _uri.Query;
string M42Code = null;
string M42State = null;
if (_frag == null)
_frag = "";
if (_host == _M42Server.ToLowerInvariant() && _path == "/wm/" && _query.Contains("code="))
{
var _tmpQuery = _query;
if (_tmpQuery.StartsWith("?"))
_tmpQuery = _tmpQuery.Remove(0, 1);
var _arrItems = _tmpQuery.Split('&');
foreach (var item in _arrItems)
{
var _props = item.Split('=');
if (_props.Length == 2)
{
switch (_props[0])
{
case "code":
M42Code = _props[1];
break;
case "state":
M42State = _props[1];
break;
}
}
}
WebLogon.Stop();
WebLogon.CoreWebView2.Navigate(_logonUrl.AbsoluteUri);
}
if (_host == _M42Server.ToLowerInvariant() && _path == "/wm/" && _frag.Contains("#access_token="))
{
if (regainToken)
{
regainToken = false;
return;
}
WebLogon.Stop();
WebLogon.Visibility = Visibility.Collapsed;
var _token = await ProcessAccessTokenAsync(_frag);
if (_token is null)
NoAccessTokenMessage.Visibility = Visibility.Visible;
else
{
cF4sdUserInfo userInfo;
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
{
userInfo = cFasdCockpitCommunicationBase.CockpitUserInfo;
}
var _TokenRegistration = new cF4SDTokenRegistration()
{
UserId = userInfo.Id,
TokenType = cF4SDTokenRegistration.enumTokenType.M42Bearer,
Secret = _token,
AutoCreatePermanent = true
};
var _userInfoChange = await cFasdCockpitCommunicationBase.Instance.RegisterExternalTokenAsync(_TokenRegistration);
if (_userInfoChange is null)
{
NoAccessTokenMessage.Visibility = Visibility.Visible;
}
else
{
UserInfoChange = _userInfoChange;
DialogResult = true;
Close();
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
private async Task<string> ProcessAccessTokenAsync(string Fragment)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var _arrParameters = Fragment.Split('&');
string _AccessToken = null;
foreach (var _arrParam in _arrParameters)
{
var _items = _arrParam.Split('=');
if (_items.Length == 2 && _items[0] == "#access_token")
_AccessToken = _items[1];
}
var _AccessPayload = cM42TokenPayload.GetAccessPayload(_AccessToken);
if (_AccessPayload != null && _AccessPayload.UserObjectId != Guid.Empty)
{
var M42WebClient = new cM42WebClient(_M42Server);
M42WebClient.SetBearerToken(_AccessToken);
var _res = await M42WebClient.Open();
if (_res == cM42WebClient.eReason.ok)
{
userInfoM42 = await M42WebClient.GetUserInfoAsync();
if (userInfoM42.Reason == cM42WebClient.eReason.ok)
{
return _AccessToken;
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public static cF4SdUserInfoChange M42FormBasedAuthenticationDelegate()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var logonPage = new F4sdM42FormsAuthentication(Reauthenticate: true);
var _ret = logonPage.ShowDialog();
if (_ret == true)
return logonPage.UserInfoChange;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
private void butRefresh_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
WebLogon.Stop();
WebLogon.Source = new Uri("about:blank");
_logonUrl = new Uri($"https://{_M42Server}/m42Services/api/sts/authorize?client_id=ServiceStore.NewUX&scope=urn:matrix42NewUX&response_type=token&autoLogin=true");
WebLogon.Source = _logonUrl;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
private void butClearCookies_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (WebLogon?.CoreWebView2?.CookieManager != null)
WebLogon.CoreWebView2.CookieManager.DeleteAllCookies();
butRefresh_MouseLeftButtonUp(sender, null);
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
}
public class cM42UserInfo
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Guid ObjectId { get; set; }
}
}