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 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; } } }