diff --git a/.gitignore b/.gitignore
index 44011104..8400ee83 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
*.user
*.userosscache
*.sln.docstates
+*MagFlux/MjkControlledCodeRef*
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
diff --git a/Common/CommonCore.Configuration/ServiceUrls.cs b/Common/CommonCore.Configuration/ServiceUrls.cs
index 2d5bb901..ac5c7236 100644
--- a/Common/CommonCore.Configuration/ServiceUrls.cs
+++ b/Common/CommonCore.Configuration/ServiceUrls.cs
@@ -199,6 +199,13 @@ namespace Xylem.Common.CommonCore.Configuration
private const String PressureSensorTestURL_GetTestResults
= "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestResults/{0}";
+ public const string LaaProductionAPI
+#if DEBUG
+ = "http://localhost:54448";
+#else
+ = "http://sla12iis01.emea.sensus.net";
+#endif
+
///
/// GET: test specification for water meter with pressure sensor.
diff --git a/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache b/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache
index 0028f628..f98f081f 100644
--- a/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache
+++ b/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-f64d563def603c89cafafa61a3219ba97e1e344c
+57a46bdf07e306281dc4ae72a3747ed460385fe7
diff --git a/Common/Ui/GenesisToolBox/Ctls/LoginForm.Designer.cs b/Common/Ui/GenesisToolBox/Ctls/LoginForm.Designer.cs
new file mode 100644
index 00000000..c18c0208
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Ctls/LoginForm.Designer.cs
@@ -0,0 +1,160 @@
+namespace Xylem.Common.Ui.GenesisToolBox.Ctls
+{
+ partial class LoginForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.LoginFormPanel = new System.Windows.Forms.Panel();
+ this.ErrorMessage = new System.Windows.Forms.Label();
+ this.LoginButton = new System.Windows.Forms.Button();
+ this.Password = new System.Windows.Forms.TextBox();
+ this.UsernameLabel = new System.Windows.Forms.Label();
+ this.Username = new System.Windows.Forms.TextBox();
+ this.PasswordLabel = new System.Windows.Forms.Label();
+ this.LoginErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+ this.LoginFormPanel.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.LoginErrorProvider)).BeginInit();
+ this.SuspendLayout();
+ //
+ // LoginFormPanel
+ //
+ this.LoginFormPanel.Controls.Add(this.ErrorMessage);
+ this.LoginFormPanel.Controls.Add(this.LoginButton);
+ this.LoginFormPanel.Controls.Add(this.Password);
+ this.LoginFormPanel.Controls.Add(this.UsernameLabel);
+ this.LoginFormPanel.Controls.Add(this.Username);
+ this.LoginFormPanel.Controls.Add(this.PasswordLabel);
+ this.LoginFormPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.LoginFormPanel.Location = new System.Drawing.Point(0, 0);
+ this.LoginFormPanel.Name = "LoginFormPanel";
+ this.LoginFormPanel.Size = new System.Drawing.Size(458, 439);
+ this.LoginFormPanel.TabIndex = 0;
+ //
+ // ErrorMessage
+ //
+ this.ErrorMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ErrorMessage.AutoSize = true;
+ this.ErrorMessage.ForeColor = System.Drawing.Color.Red;
+ this.ErrorMessage.Location = new System.Drawing.Point(96, 251);
+ this.ErrorMessage.Name = "ErrorMessage";
+ this.ErrorMessage.Size = new System.Drawing.Size(0, 13);
+ this.ErrorMessage.TabIndex = 5;
+ //
+ // LoginButton
+ //
+ this.LoginButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.LoginButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.LoginButton.Location = new System.Drawing.Point(97, 221);
+ this.LoginButton.Name = "LoginButton";
+ this.LoginButton.Size = new System.Drawing.Size(266, 23);
+ this.LoginButton.TabIndex = 4;
+ this.LoginButton.Text = "Login";
+ this.LoginButton.UseVisualStyleBackColor = true;
+ this.LoginButton.Click += new System.EventHandler(this.LoginButtonClick);
+ //
+ // Password
+ //
+ this.Password.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.Password.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.Password.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.Password.Location = new System.Drawing.Point(97, 195);
+ this.Password.Name = "Password";
+ this.Password.PasswordChar = '*';
+ this.Password.Size = new System.Drawing.Size(266, 20);
+ this.Password.TabIndex = 3;
+ this.Password.UseSystemPasswordChar = true;
+ //
+ // UsernameLabel
+ //
+ this.UsernameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.UsernameLabel.AutoSize = true;
+ this.UsernameLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.UsernameLabel.Location = new System.Drawing.Point(94, 140);
+ this.UsernameLabel.Name = "UsernameLabel";
+ this.UsernameLabel.Size = new System.Drawing.Size(63, 13);
+ this.UsernameLabel.TabIndex = 0;
+ this.UsernameLabel.Text = "Username";
+ //
+ // Username
+ //
+ this.Username.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.Username.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.Username.Location = new System.Drawing.Point(97, 156);
+ this.Username.Name = "Username";
+ this.Username.Size = new System.Drawing.Size(266, 20);
+ this.Username.TabIndex = 2;
+ //
+ // PasswordLabel
+ //
+ this.PasswordLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.PasswordLabel.AutoSize = true;
+ this.PasswordLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.PasswordLabel.Location = new System.Drawing.Point(94, 179);
+ this.PasswordLabel.Name = "PasswordLabel";
+ this.PasswordLabel.Size = new System.Drawing.Size(61, 13);
+ this.PasswordLabel.TabIndex = 1;
+ this.PasswordLabel.Text = "Password";
+ //
+ // LoginErrorProvider
+ //
+ this.LoginErrorProvider.BlinkRate = 0;
+ this.LoginErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+ this.LoginErrorProvider.ContainerControl = this;
+ //
+ // LoginForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.LoginFormPanel);
+ this.Name = "LoginForm";
+ this.Size = new System.Drawing.Size(458, 439);
+ this.LoginFormPanel.ResumeLayout(false);
+ this.LoginFormPanel.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.LoginErrorProvider)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel LoginFormPanel;
+ private System.Windows.Forms.Button LoginButton;
+ private System.Windows.Forms.TextBox Password;
+ private System.Windows.Forms.Label UsernameLabel;
+ private System.Windows.Forms.TextBox Username;
+ private System.Windows.Forms.Label PasswordLabel;
+ private System.Windows.Forms.ErrorProvider LoginErrorProvider;
+ private System.Windows.Forms.Label ErrorMessage;
+ }
+}
diff --git a/Common/Ui/GenesisToolBox/Ctls/LoginForm.cs b/Common/Ui/GenesisToolBox/Ctls/LoginForm.cs
new file mode 100644
index 00000000..4a327012
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Ctls/LoginForm.cs
@@ -0,0 +1,68 @@
+namespace Xylem.Common.Ui.GenesisToolBox.Ctls
+{
+ using System;
+ using System.Security.Cryptography;
+ using System.Text;
+ using System.Windows.Forms;
+
+ public partial class LoginForm : UserControl
+ {
+ private readonly Action submittedCallback;
+
+ public LoginForm()
+ {
+ this.InitializeComponent();
+
+ this.Dock = DockStyle.Fill;
+ }
+
+ public LoginForm(Action submittedCallback) : this()
+ => this.submittedCallback = submittedCallback;
+
+ private void LoginButtonClick(object sender, EventArgs e)
+ {
+ this.ErrorMessage.Text = default(string);
+ this.LoginErrorProvider.Clear();
+
+ var isValid = true;
+
+ if (string.IsNullOrWhiteSpace(this.Username.Text))
+ {
+ isValid = false;
+
+ this.LoginErrorProvider.SetError(this.Username, "Username is required.");
+ }
+
+ if (string.IsNullOrWhiteSpace(this.Password.Text))
+ {
+ isValid = false;
+
+ this.LoginErrorProvider.SetError(this.Password, "Password is required.");
+ }
+
+ if (isValid)
+ {
+ this.submittedCallback?.Invoke(this.Username.Text, this.Password.Text.ComputeBase64Hash(), this);
+ }
+ }
+
+ internal void ShowError(string errorMessage)
+ => this.ErrorMessage.Text = errorMessage;
+ }
+
+ internal static class PasswordExtensions
+ {
+ internal static string ComputeBase64Hash(this string plainText)
+ {
+ if (string.IsNullOrWhiteSpace(plainText))
+ {
+ return plainText;
+ }
+
+ var buffer = Encoding.UTF8.GetBytes(plainText);
+ var hash = SHA256.Create().ComputeHash(buffer);
+
+ return Convert.ToBase64String(hash);
+ }
+ }
+}
diff --git a/Common/Ui/GenesisToolBox/Ctls/LoginForm.resx b/Common/Ui/GenesisToolBox/Ctls/LoginForm.resx
new file mode 100644
index 00000000..4995eff7
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Ctls/LoginForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Common/Ui/GenesisToolBox/GenesisToolBox.csproj b/Common/Ui/GenesisToolBox/GenesisToolBox.csproj
index 00fb9b10..a6cf4710 100644
--- a/Common/Ui/GenesisToolBox/GenesisToolBox.csproj
+++ b/Common/Ui/GenesisToolBox/GenesisToolBox.csproj
@@ -43,6 +43,7 @@
7.0
false
bin\Debug\Xylem.Common.Ui.GenesisToolBox.xml
+ 1591
AnyCPU
@@ -170,6 +171,7 @@
+
@@ -196,6 +198,12 @@
ctlConnectInterface.cs
+
+ UserControl
+
+
+ LoginForm.cs
+
Component
@@ -404,6 +412,10 @@
FrmTempMeter.cs
+
+
+
+
@@ -422,6 +434,9 @@
TextFileMatchControl.cs
+
+ LoginForm.cs
+
FrmCalibrationResults.cs
diff --git a/Common/Ui/GenesisToolBox/GenesisToolBox.csproj.user b/Common/Ui/GenesisToolBox/GenesisToolBox.csproj.user
index 54b1889f..888ca413 100644
--- a/Common/Ui/GenesisToolBox/GenesisToolBox.csproj.user
+++ b/Common/Ui/GenesisToolBox/GenesisToolBox.csproj.user
@@ -10,5 +10,6 @@
de-DE
false
+ ProjectFiles
\ No newline at end of file
diff --git a/Common/Ui/GenesisToolBox/Infrastructure/ApplicationHttp.cs b/Common/Ui/GenesisToolBox/Infrastructure/ApplicationHttp.cs
new file mode 100644
index 00000000..9e606a66
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Infrastructure/ApplicationHttp.cs
@@ -0,0 +1,105 @@
+namespace Xylem.Common.Ui.GenesisToolBox.Infrastructure
+{
+ using Newtonsoft.Json;
+
+ using System;
+ using System.Collections.Generic;
+ using System.Net.Http;
+ using System.Text;
+ using System.Threading.Tasks;
+
+ using Xylem.Common.CommonCore.Configuration;
+
+ internal class ApplicationHttp
+ {
+ const string APPLICATION_JSON = "application/json";
+
+ private static readonly HttpClient httpClient = new HttpClient()
+ {
+ BaseAddress = new Uri(ServiceUrls.LaaProductionAPI)
+ };
+
+ internal static int ApplicationId(string software, params string[] functions)
+ => Task
+ .Run(async () =>
+ {
+ var applicationId = default(int);
+
+ try
+ {
+ using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "api/software/appid"))
+ {
+ httpRequestMessage.Content = new StringContent(
+ mediaType: APPLICATION_JSON,
+ encoding: Encoding.UTF8,
+ content: JsonConvert.SerializeObject(new
+ {
+ software,
+ functions
+ }));
+
+ using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
+ {
+ if (httpResponseMessage.Content != null)
+ {
+ var httpResponseContent = await httpResponseMessage.Content.ReadAsStringAsync();
+
+ _ = int.TryParse(httpResponseContent, out applicationId);
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ // TODO: Log the error message.
+ }
+
+ return applicationId;
+ })
+ .ConfigureAwait(true)
+ .GetAwaiter()
+ .GetResult();
+
+ internal static IEnumerable GetSoftwareFunction(int appId, string username, string password)
+ => Task
+ .Run(async () =>
+ {
+ var functions = default(IEnumerable);
+
+ try
+ {
+ using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "api/software/functions"))
+ {
+ httpRequestMessage.Content = new StringContent(
+ mediaType: APPLICATION_JSON,
+ encoding: Encoding.UTF8,
+ content: JsonConvert.SerializeObject(new
+ {
+ appId,
+ username,
+ password,
+ }));
+
+ using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
+ {
+ if (httpResponseMessage.IsSuccessStatusCode && httpResponseMessage.Content != null)
+ {
+ var httpResponseContent = await httpResponseMessage.Content.ReadAsStringAsync();
+
+ functions = JsonConvert.DeserializeObject(httpResponseContent);
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ // TODO: Log the error message.
+ }
+
+ return functions;
+ })
+ .ConfigureAwait(true)
+ .GetAwaiter()
+ .GetResult();
+ }
+}
diff --git a/Common/Ui/GenesisToolBox/Infrastructure/ApplicationState.cs b/Common/Ui/GenesisToolBox/Infrastructure/ApplicationState.cs
new file mode 100644
index 00000000..779a9200
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Infrastructure/ApplicationState.cs
@@ -0,0 +1,57 @@
+namespace Xylem.Common.Ui.GenesisToolBox.Infrastructure
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ internal class ApplicationState
+ {
+ internal const string UNAVAILABLE = "Genesis Toolbox is currently not available.";
+
+
+ private static IEnumerable softwareFunctions;
+
+ internal static int Id { get; private set; }
+
+ internal static bool IsAuthorized { get; private set; }
+
+ internal static bool Initialized { get; private set; }
+
+ internal static ApplicationVersion Version { get; private set; }
+ = ApplicationVersion.Current;
+
+ internal static void Initialize()
+ {
+ Id = ApplicationHttp.ApplicationId(
+ software: Version.Assembly.Name,
+ functions: Enum.GetNames(typeof(SoftwareFunctions)));
+ Initialized = Id > 0;
+ }
+
+ internal static bool Authorize(string username, string password, out string error)
+ {
+ error = default(string);
+
+ if (Id <= 0)
+ {
+ error = "Genesis Toolbox is currently not available.";
+ }
+ else
+ {
+ softwareFunctions = ApplicationHttp.GetSoftwareFunction(Id, username, password);
+ IsAuthorized = softwareFunctions != null;
+
+ if (!IsAuthorized)
+ {
+ error = "Genesis Toolbox is currently not available.";
+ softwareFunctions = Array.Empty();
+ }
+ }
+
+ return IsAuthorized;
+ }
+
+ internal static Boolean IsEnabled(SoftwareFunctions softwareFunction)
+ => softwareFunctions.Contains(softwareFunction);
+ }
+}
diff --git a/Common/Ui/GenesisToolBox/Infrastructure/ApplicationVersion.cs b/Common/Ui/GenesisToolBox/Infrastructure/ApplicationVersion.cs
new file mode 100644
index 00000000..2f511562
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Infrastructure/ApplicationVersion.cs
@@ -0,0 +1,44 @@
+namespace Xylem.Common.Ui.GenesisToolBox.Infrastructure
+{
+ using System;
+ using System.Reflection;
+
+ internal struct ApplicationVersion
+ {
+ private ApplicationVersion(bool initialize)
+ {
+ if (initialize)
+ {
+ this.Assembly = System.Reflection.Assembly
+ .GetExecutingAssembly()
+ .GetName();
+ this.Major = this.Assembly.Version.Major;
+ this.Minor = this.Assembly.Version.Minor;
+ this.Build = this.Assembly.Version.Build;
+ }
+ else
+ {
+ this.Major = default(int);
+ this.Minor = default(int);
+ this.Build = default(int);
+ this.Assembly = default(AssemblyName);
+ }
+ }
+
+ public int Major { get; }
+
+ public int Minor { get; }
+
+ public int Build { get; }
+
+ public AssemblyName Assembly { get; }
+
+ public override string ToString()
+ => $"{nameof(Version)}: {this.Major}.{this.Minor}.{this.Build}";
+
+ public static ApplicationVersion Current => new ApplicationVersion(true);
+
+ public static implicit operator string(ApplicationVersion assemblyVersion)
+ => assemblyVersion.ToString();
+ }
+}
diff --git a/Common/Ui/GenesisToolBox/Infrastructure/SoftwareFunctions.cs b/Common/Ui/GenesisToolBox/Infrastructure/SoftwareFunctions.cs
new file mode 100644
index 00000000..aa6514b7
--- /dev/null
+++ b/Common/Ui/GenesisToolBox/Infrastructure/SoftwareFunctions.cs
@@ -0,0 +1,27 @@
+namespace Xylem.Common.Ui.GenesisToolBox.Infrastructure
+{
+ internal enum SoftwareFunctions
+ {
+ DEV_FILE_CONTROL,
+ DEV_FILE_SPLIT,
+ DEV_LEGACY_TEST_APP,
+ DEV_LOW_LEVEL_TOOLS,
+
+ GENERAL_ALARM,
+ GENERAL_FIRMWARE_UPDATE,
+ GENERAL_LUT_MANAGEMENT,
+ GENERAL_LUT_UPDATE,
+ GENERAL_PRESSURE_LOG,
+ GENERAL_PULS_CONFIG,
+ GENERAL_REGISTER_STORE,
+ GENERAL_SETUP,
+ GENERAL_STREAM_QUALITY,
+ GENERAL_TEMP_METER,
+
+ LAA_MAPPING_NA,
+ LAA_PASSWORD,
+ LAA_PARAMETERIZATION,
+ LAA_PROCESS_PARAMETER,
+ LAA_REGISTER_HISTORY,
+ }
+}
diff --git a/Common/Ui/GenesisToolBox/Program.cs b/Common/Ui/GenesisToolBox/Program.cs
index d6623317..d88ebca5 100644
--- a/Common/Ui/GenesisToolBox/Program.cs
+++ b/Common/Ui/GenesisToolBox/Program.cs
@@ -1,16 +1,19 @@
-using System;
-using System.Windows.Forms;
-
-namespace Xylem.Common.Ui.GenesisToolBox
+namespace Xylem.Common.Ui.GenesisToolBox
{
+ using System;
+ using System.Windows.Forms;
+
+ using Xylem.Common.Ui.GenesisToolBox.Infrastructure;
+
internal static class Program
{
///
/// The main entry point for the application.
///
[STAThread]
- static void Main()
+ internal static void Main()
{
+ ApplicationState.Initialize();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMainForm());
diff --git a/Common/Ui/GenesisToolBox/frmMainForm.cs b/Common/Ui/GenesisToolBox/frmMainForm.cs
index e694bdf5..6ae037dc 100644
--- a/Common/Ui/GenesisToolBox/frmMainForm.cs
+++ b/Common/Ui/GenesisToolBox/frmMainForm.cs
@@ -1,9 +1,14 @@
using GenesisToolBox;
+
using System;
+using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
+
using Xylem.Common.CommonCore.Consts;
+using Xylem.Common.Ui.GenesisToolBox.Ctls;
+using Xylem.Common.Ui.GenesisToolBox.Infrastructure;
using Xylem.Common.Utils.Logging;
namespace Xylem.Common.Ui.GenesisToolBox
@@ -19,7 +24,9 @@ namespace Xylem.Common.Ui.GenesisToolBox
///
public FrmMainForm()
{
- InitializeComponent();
+ this.InitializeComponent();
+ this.InitializeFormState();
+
var logger = NLogHelper.CreateOrGetLogger("GenesisToolBox");
var version = Assembly.GetExecutingAssembly().GetName().Version;
logger.Info($"GenesisToolBox Version: {version.Major}.{version.Minor}.{version.Build}");
@@ -34,6 +41,95 @@ namespace Xylem.Common.Ui.GenesisToolBox
lblVersionNumber.Text = $@"Version: {version.Major}.{version.Minor}.{version.Build}";
}
+ private void InitializeFormState()
+ {
+ foreach (var control in this.Controls)
+ {
+ if (control is GroupBox groupBox)
+ {
+ groupBox.Hide();
+ }
+ }
+
+ this.btnSetup.Tag = SoftwareFunctions.GENERAL_SETUP;
+ this.btnAlarm.Tag = SoftwareFunctions.GENERAL_ALARM;
+ this.btnRegisterStore.Tag = SoftwareFunctions.GENERAL_REGISTER_STORE;
+ this.btnTempLogger.Tag = SoftwareFunctions.GENERAL_TEMP_METER;
+ this.btnStreamingQuality.Tag = SoftwareFunctions.GENERAL_STREAM_QUALITY;
+ this.btnFwUpdate.Tag = SoftwareFunctions.GENERAL_FIRMWARE_UPDATE;
+ this.btnLutUpdate.Tag = SoftwareFunctions.GENERAL_LUT_UPDATE;
+ this.button4.Tag = SoftwareFunctions.GENERAL_LUT_MANAGEMENT;
+ this.btnPressure.Tag = SoftwareFunctions.GENERAL_PRESSURE_LOG;
+ this.button1.Tag = SoftwareFunctions.GENERAL_PULS_CONFIG;
+
+ this.btnPassword.Tag = SoftwareFunctions.LAA_PASSWORD;
+ this.btnRegHistory.Tag = SoftwareFunctions.LAA_REGISTER_HISTORY;
+ this.btnPara.Tag = SoftwareFunctions.LAA_PARAMETERIZATION;
+ this.button2.Tag = SoftwareFunctions.LAA_PROCESS_PARAMETER;
+ this.button5.Tag = SoftwareFunctions.LAA_MAPPING_NA;
+
+ this.btnLegacyTestApp.Tag = SoftwareFunctions.DEV_LEGACY_TEST_APP;
+ this.btnFiles.Tag = SoftwareFunctions.DEV_FILE_CONTROL;
+ this.BtnFileSplit.Tag = SoftwareFunctions.DEV_FILE_SPLIT;
+ this.btnLowLevelTools.Tag = SoftwareFunctions.DEV_LOW_LEVEL_TOOLS;
+
+ if (!ApplicationState.Initialized)
+ {
+ this.Controls.Add(new Label()
+ {
+ Dock = DockStyle.Fill,
+ Text = ApplicationState.UNAVAILABLE,
+ TextAlign = ContentAlignment.MiddleCenter,
+ Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold),
+ ForeColor = Color.DarkRed,
+ Padding = new Padding(15)
+ });
+ }
+ else if (!ApplicationState.IsAuthorized)
+ {
+ this.Controls.Add(new LoginForm(this.LoginFormSubmitted));
+ }
+ else
+ {
+ this.ShowAvailableSoftwareFunctions();
+ }
+ }
+
+ private void LoginFormSubmitted(string username, string password, object sender)
+ {
+ if (sender is LoginForm loginForm)
+ {
+ var errorMessage = default(string);
+
+ if (ApplicationState.Authorize(username, password, out errorMessage))
+ {
+ this.Controls.Remove(loginForm);
+ this.ShowAvailableSoftwareFunctions();
+ }
+
+ loginForm.ShowError(errorMessage);
+ }
+ }
+
+ private void ShowAvailableSoftwareFunctions()
+ {
+ foreach (var control in this.Controls)
+ {
+ if (control is GroupBox groupBox)
+ {
+ foreach (var groupBoxControl in groupBox.Controls)
+ {
+ if (groupBoxControl is Button button && button.Tag is SoftwareFunctions softwareFunction)
+ {
+ button.Enabled = ApplicationState.IsEnabled(softwareFunction);
+ }
+ }
+
+ groupBox.Show();
+ }
+ }
+ }
+
private void btnSetup_Click(Object sender, EventArgs e)
{
var form = new FrmSetup();
diff --git a/LaaProductionWeb/LaaProductionWeb.Services/Interfaces/ISoftwareService.cs b/LaaProductionWeb/LaaProductionWeb.Services/Interfaces/ISoftwareService.cs
index 4ee9c6d9..dc151e7b 100644
--- a/LaaProductionWeb/LaaProductionWeb.Services/Interfaces/ISoftwareService.cs
+++ b/LaaProductionWeb/LaaProductionWeb.Services/Interfaces/ISoftwareService.cs
@@ -10,12 +10,14 @@
void DeleteFunction(int funcId);
- IEnumerable FindSoftwareForUser(short appId, string username, string password);
+ short FindAndUpdateSoftware(string name, IEnumerable functions);
IEnumerable GetAllSoftwareFunctions();
IEnumerable GetSoftwareFunctions(short appId);
+ IEnumerable GetSoftwareFunctions(short appId, short userId);
+
SoftwareOverview GetSoftwareOverview(short appId);
IEnumerable GetSoftwareVersions(short appId);
diff --git a/LaaProductionWeb/LaaProductionWeb.Services/SoftwareService.cs b/LaaProductionWeb/LaaProductionWeb.Services/SoftwareService.cs
index 1022c089..d66d11c9 100644
--- a/LaaProductionWeb/LaaProductionWeb.Services/SoftwareService.cs
+++ b/LaaProductionWeb/LaaProductionWeb.Services/SoftwareService.cs
@@ -6,7 +6,9 @@
using System;
using System.Collections.Generic;
+ using System.Linq;
using System.Security.Cryptography;
+ using System.Text.RegularExpressions;
public class SoftwareService : ISoftwareService
{
@@ -27,6 +29,15 @@
.AddParameter(nameof(name), name)
.ExecuteNonQuery();
+ public int ApplicationId(string name)
+ => this.sqlClient
+ .CreateCommand($@"
+ SELECT TOP 1 [AppId]
+ FROM [VersionSoftwareAccess]
+ WHERE [SoftwareAccess_Program] = @{nameof(name)}")
+ .AddParameter(nameof(name), name)
+ .FirstOrDefault(x => x.GetSmallint());
+
public void DeleteFunction(int funcId)
{
this.sqlClient
@@ -44,9 +55,30 @@
.ExecuteNonQuery();
}
- public IEnumerable FindSoftwareForUser(short appId, string username, string password)
+ public short FindAndUpdateSoftware(string name, IEnumerable functions)
{
- throw new NotImplementedException();
+ var appId = this.sqlClient
+ .CreateCommand($@"
+ SELECT TOP 1 [AppId]
+ , MAX([SoftwareAccess_VaildTo]) OVER (PARTITION BY [AppId])
+ FROM [VersionSoftwareAccess]
+ WHERE [SoftwareAccess_Program] = @{nameof(name)}
+ AND [SoftwareAccess_VaildTo] > GETDATE()")
+ .AddParameter(nameof(name), name)
+ .FirstOrDefault(x => x.GetSmallint());
+
+ if (appId > 0 && functions != null && functions.Any())
+ {
+ foreach (var function in functions)
+ {
+ if (Regex.IsMatch(function, "[a-zA-Z_]+"))
+ {
+ this.AddFunction(appId, function);
+ }
+ }
+ }
+
+ return appId;
}
public IEnumerable GetAllSoftwareFunctions()
@@ -79,6 +111,19 @@
Function = f.GetString()
});
+ public IEnumerable GetSoftwareFunctions(short appId, short userId)
+ => this.sqlClient
+ .CreateCommand($@"
+ SELECT [SF].[Function] AS [Function]
+ FROM [UsersFunctions] AS [UF]
+ JOIN [SoftwareFunctions] AS [SF]
+ ON [SF].[Id] = [UF].[SoftwareFunctionId]
+ WHERE [UF].[UserId] = @{nameof(userId)}
+ AND [SF].[AppId] = @{nameof(appId)}")
+ .AddParameter(nameof(appId), appId)
+ .AddParameter(nameof(userId), userId)
+ .ExecuteReader(x => x.GetString());
+
public SoftwareOverview GetSoftwareOverview(short appId)
=> this.sqlClient
.CreateCommand($@"
diff --git a/LaaProductionWeb/LaaProductionWeb/Areas/Account/Controllers/FunctionsController.cs b/LaaProductionWeb/LaaProductionWeb/Areas/Account/Controllers/FunctionsController.cs
deleted file mode 100644
index 33a1835e..00000000
--- a/LaaProductionWeb/LaaProductionWeb/Areas/Account/Controllers/FunctionsController.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-namespace LaaProductionWeb.Areas.Account.Controllers
-{
- using LaaProductionWeb.Services.Interfaces;
-
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Web.Http;
-
- [AllowAnonymous]
- public class FunctionsController : ApiController
- {
- private readonly IAccountService accountService;
-
- public FunctionsController()
- => this.accountService = ServiceProvider.Current.GetService();
-
- [HttpGet]
- public IHttpActionResult Get()
- {
- if (this.ActionContext.Request.Headers.TryGetValues("Authorization", out IEnumerable values) && values.Any())
- {
- var bearer = values
- .FirstOrDefault()
- .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
- .LastOrDefault();
-
- try
- {
- var tokens = Encoding.UTF8
- .GetString(Convert.FromBase64String(bearer))
- .Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
-
- if (tokens != null && tokens.Length == 3 && short.TryParse(tokens[0], out short appId))
- {
- var username = tokens[1];
- var password = tokens[2];
-
- var functions = this.accountService.FindUserFunctions(appId, username, password);
-
- return this.Ok(functions);
- }
- }
- catch (Exception)
- {
- // TODO: Log exception.
- }
- }
-
- return this.BadRequest("Endpoint expects bearer authorization header with appId:username:password base64 encoded.");
- }
- }
-}
\ No newline at end of file
diff --git a/LaaProductionWeb/LaaProductionWeb/Areas/Account/Controllers/PWDController.cs b/LaaProductionWeb/LaaProductionWeb/Areas/Account/Controllers/PWDController.cs
deleted file mode 100644
index d397bac5..00000000
--- a/LaaProductionWeb/LaaProductionWeb/Areas/Account/Controllers/PWDController.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-namespace LaaProductionWeb.Areas.Account.Controllers
-{
- using LaaProductionWeb.Services.Interfaces;
-
- using System.Web.Http;
-
- public class PWDController : ApiController
- {
- private readonly IAccountService accountService;
-
- public PWDController()
- => this.accountService = ServiceProvider.Current.GetService();
-
- [HttpPost]
- public IHttpActionResult Post(string username, string password)
- {
- if (string.IsNullOrWhiteSpace(password))
- {
- return this.BadRequest("Invalid password.");
- }
- else if (this.accountService.ResetPassword(username, password) == 1)
- {
- return this.Ok();
- }
-
- return this.BadRequest("Password was not reseted.");
- }
-
- [HttpDelete]
- public IHttpActionResult Delete(string username)
- {
- if (this.accountService.ResetPassword(username) == 1)
- {
- return this.Ok();
- }
-
- return this.BadRequest("Password was not reseted.");
- }
- }
-}
\ No newline at end of file
diff --git a/LaaProductionWeb/LaaProductionWeb/Areas/Software/Controllers/AppIdController.cs b/LaaProductionWeb/LaaProductionWeb/Areas/Software/Controllers/AppIdController.cs
new file mode 100644
index 00000000..881a902b
--- /dev/null
+++ b/LaaProductionWeb/LaaProductionWeb/Areas/Software/Controllers/AppIdController.cs
@@ -0,0 +1,26 @@
+namespace LaaProductionWeb.Areas.Software.Controllers
+{
+ using LaaProductionWeb.Services.Interfaces;
+
+ using System.Collections.Generic;
+ using System.Web.Http;
+
+ public class AppIdController : ApiController
+ {
+ private readonly ISoftwareService softwareService;
+
+ public AppIdController()
+ => this.softwareService = ServiceProvider.Current.GetService();
+
+ [HttpPost]
+ public int Post(AppIdPostInputModel model)
+ => this.softwareService.FindAndUpdateSoftware(model.Software, model.Functions);
+ }
+
+ public class AppIdPostInputModel
+ {
+ public string Software { get; set; }
+
+ public IEnumerable Functions { get; set; }
+ }
+}
diff --git a/LaaProductionWeb/LaaProductionWeb/Areas/Software/Controllers/FunctionsController.cs b/LaaProductionWeb/LaaProductionWeb/Areas/Software/Controllers/FunctionsController.cs
new file mode 100644
index 00000000..8492e02b
--- /dev/null
+++ b/LaaProductionWeb/LaaProductionWeb/Areas/Software/Controllers/FunctionsController.cs
@@ -0,0 +1,42 @@
+namespace LaaProductionWeb.Areas.Software.Controllers
+{
+ using LaaProductionWeb.Services.Interfaces;
+
+ using System.Web.Http;
+
+ public class FunctionsController : ApiController
+ {
+ private readonly IAccountService accountService;
+ private readonly ISoftwareService softwareService;
+
+ public FunctionsController()
+ {
+ this.accountService = ServiceProvider.Current.GetService();
+ this.softwareService = ServiceProvider.Current.GetService();
+ }
+
+ [HttpPost]
+ public IHttpActionResult Post(FunctionsPostInputModel model)
+ {
+ var userId = this.accountService.Login(model.Username, model.Password);
+
+ if (userId <= 0)
+ {
+ return this.Unauthorized();
+ }
+
+ var functions = this.softwareService.GetSoftwareFunctions(model.AppId, userId);
+
+ return this.Json(functions);
+ }
+ }
+
+ public class FunctionsPostInputModel
+ {
+ public short AppId { get; set; }
+
+ public string Username { get; set; }
+
+ public string Password { get; set; }
+ }
+}
diff --git a/LaaProductionWeb/LaaProductionWeb/Areas/Software/SoftwareAreaRegistration.cs b/LaaProductionWeb/LaaProductionWeb/Areas/Software/SoftwareAreaRegistration.cs
new file mode 100644
index 00000000..29775497
--- /dev/null
+++ b/LaaProductionWeb/LaaProductionWeb/Areas/Software/SoftwareAreaRegistration.cs
@@ -0,0 +1,17 @@
+namespace LaaProductionWeb.Areas.Software
+{
+ using System.Web.Mvc;
+
+ public class SoftwareAreaRegistration : AreaRegistration
+ {
+ public override string AreaName => "Software";
+
+ public override void RegisterArea(AreaRegistrationContext context)
+ {
+ //context.MapRoute(
+ // "Software_default",
+ // "api/Software/{controller}/{id}",
+ // new { action = "Index", id = UrlParameter.Optional });
+ }
+ }
+}
\ No newline at end of file
diff --git a/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj b/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj
index 4aaea828..fa9eee80 100644
--- a/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj
+++ b/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj
@@ -135,8 +135,6 @@
-
-
@@ -161,6 +159,9 @@
+
+
+
@@ -194,9 +195,7 @@
-
-
-
+