From b9c104e259ca24d2ae7ca82387209779fefddd34 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sun, 19 Jan 2020 00:30:23 +0200 Subject: Implemented machine studio connection via access token WORKING!. Implemented machine studio login method selection. --- .../ViewModels/LoginViewVM.cs | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs') diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs index cf34764d9..9c2367f93 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs @@ -102,6 +102,21 @@ namespace Tango.MachineStudio.UI.ViewModels set { _enableSlotSelection = value; RaisePropertyChangedAuto(); } } + private bool _isActiveDirectory; + public bool IsActiveDirectory + { + get { return _isActiveDirectory; } + set { _isActiveDirectory = value; RaisePropertyChangedAuto(); if (value) IsStandardUser = false; } + } + + private bool _isStandardUser; + public bool IsStandardUser + { + get { return _isStandardUser; } + set { _isStandardUser = value; RaisePropertyChangedAuto(); if (value) IsActiveDirectory = false; } + } + + /// /// Gets or sets the login command. @@ -131,6 +146,15 @@ namespace Tango.MachineStudio.UI.ViewModels Email = _settings.LastLoginEmail; DeploymentSlot = _settings.DeploymentSlot; RememberMe = _settings.RememberMe; + + if (_settings.LastLoginMethod == LoginMethod.ActiveDirectory) + { + IsActiveDirectory = true; + } + else + { + IsStandardUser = true; + } try { @@ -154,11 +178,13 @@ namespace Tango.MachineStudio.UI.ViewModels IsLogging = true; InvalidateRelayCommands(); + LoginMethod loginMethod = IsActiveDirectory ? LoginMethod.ActiveDirectory : LoginMethod.StandardUser; + await Task.Factory.StartNew(() => { _settings.DeploymentSlot = DeploymentSlot; - LoginResponse result = _authenticationProvider.Login(Email, Password, _settings.ByPassEnvironmentVersionCheck).Response; + LoginResponse result = _authenticationProvider.Login(Email, Password, loginMethod, _settings.ByPassEnvironmentVersionCheck).Response; if (result.VersionChangeRequired && !_settings.ByPassEnvironmentVersionCheck) { @@ -183,6 +209,7 @@ namespace Tango.MachineStudio.UI.ViewModels _settings.LastLoginEmail = Email; _settings.RememberMe = RememberMe; + _settings.LastLoginMethod = loginMethod; _settings.LastLoginPassword = RememberMe ? cryptographer.Encrypt(Password) : null; _settings.Save(); -- cgit v1.3.1 From 09d432566f696f0eeb3fce97d2c870cfd1c91f89 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 19 Jan 2020 12:05:37 +0200 Subject: Improved ms logging screen. Improved ObservableStaticCollection init speed. --- .../Views/MachineJobSelectionView.xaml | 2 +- .../Authentication/IAuthenticationProvider.cs | 2 +- .../DefaultAuthenticationProvider.cs | 12 +++++- .../Tango.MachineStudio.UI.csproj | 2 +- .../ViewModels/LoginViewVM.cs | 14 +++++-- .../Tango.MachineStudio.UI/Views/LoginView.xaml | 7 +++- .../Tango.BL/ObservablesStaticCollections.cs | 44 +++++++++++++++++----- 7 files changed, 63 insertions(+), 20 deletions(-) (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml index f8a10e7c4..bf626f462 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml @@ -64,7 +64,7 @@ - + MACHINE JOBS diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs index cb231fa05..2929ea405 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs @@ -29,7 +29,7 @@ namespace Tango.MachineStudio.Common.Authentication /// The email. /// The password. /// - AuthenticationLoginResult Login(String email, String password, LoginMethod method, bool bypassVersionCheck = false); + AuthenticationLoginResult Login(String email, String password, LoginMethod method, bool bypassVersionCheck = false, Action logAction = null); /// /// Logs-out the current logged-in user. diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs index 209b26505..0131cd209 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs @@ -90,7 +90,7 @@ namespace Tango.MachineStudio.UI.Authentication /// The password. /// /// Login failed for user " + email - public AuthenticationLoginResult Login(string email, string password, LoginMethod method, bool bypassVersionCheck = false) + public AuthenticationLoginResult Login(string email, string password, LoginMethod method, bool bypassVersionCheck = false, Action logAction = null) { _refreshTokenTimer.Stop(); @@ -112,6 +112,8 @@ namespace Tango.MachineStudio.UI.Authentication try { + logAction?.Invoke("Logging in to machine service..."); + response = _client.Login(new LoginRequest() { @@ -147,7 +149,10 @@ namespace Tango.MachineStudio.UI.Authentication try { - ObservablesStaticCollections.Instance.Initialize(); + ObservablesStaticCollections.Instance.Initialize((x) => + { + logAction.Invoke(x); + }); } catch (Exception ex) { @@ -156,6 +161,7 @@ namespace Tango.MachineStudio.UI.Authentication using (ObservablesContext db = ObservablesContext.CreateDefault()) { + logAction.Invoke("Loading user permissions..."); User user = new UserBuilder(db).Set(x => x.Email.ToLower() == email.ToLower()).WithRolesAndPermissions().WithOrganization().Build(); if (user == null) @@ -167,6 +173,8 @@ namespace Tango.MachineStudio.UI.Authentication _refreshTokenTimer.Start(); + logAction.Invoke("Starting application..."); + return new AuthenticationLoginResult() { User = user, diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index efe8fc6b1..13f22dfda 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -679,7 +679,7 @@ if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)Roslyn\" - + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs index 9c2367f93..dce469dbd 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs @@ -116,7 +116,12 @@ namespace Tango.MachineStudio.UI.ViewModels set { _isStandardUser = value; RaisePropertyChangedAuto(); if (value) IsActiveDirectory = false; } } - + private String _progressLog; + public String ProgressLog + { + get { return _progressLog; } + set { _progressLog = value; RaisePropertyChangedAuto(); } + } /// /// Gets or sets the login command. @@ -146,7 +151,7 @@ namespace Tango.MachineStudio.UI.ViewModels Email = _settings.LastLoginEmail; DeploymentSlot = _settings.DeploymentSlot; RememberMe = _settings.RememberMe; - + if (_settings.LastLoginMethod == LoginMethod.ActiveDirectory) { IsActiveDirectory = true; @@ -184,7 +189,10 @@ namespace Tango.MachineStudio.UI.ViewModels { _settings.DeploymentSlot = DeploymentSlot; - LoginResponse result = _authenticationProvider.Login(Email, Password, loginMethod, _settings.ByPassEnvironmentVersionCheck).Response; + LoginResponse result = _authenticationProvider.Login(Email, Password, loginMethod, _settings.ByPassEnvironmentVersionCheck, (progress) => + { + ProgressLog = progress; + }).Response; if (result.VersionChangeRequired && !_settings.ByPassEnvironmentVersionCheck) { diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml index e7428dd28..ff13ec2c7 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml @@ -91,8 +91,11 @@ - - Logging you in... + + + + + diff --git a/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs b/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs index 5d1c3e148..1b45e959d 100644 --- a/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs +++ b/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs @@ -52,55 +52,79 @@ namespace Tango.BL /// /// Initializes this instance. /// - public void Initialize() + public void Initialize(Action progressLog = null) { if (!_initialized) { + progressLog.Invoke("Loading static collections..."); db = ObservablesContext.CreateDefault(); WindingMethods = db.WindingMethods.ToObservableCollection(); + progressLog.Invoke("Loading color spaces..."); ColorSpaces = db.ColorSpaces.ToObservableCollection(); + + progressLog.Invoke("Loading spools..."); SpoolTypes = db.SpoolTypes.ToObservableCollection(); + progressLog.Invoke("Loading event..."); EventTypes = db.EventTypes.ToObservableCollection(); + progressLog.Invoke("Loading blowers..."); HardwareBlowerTypes = db.HardwareBlowerTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwareBlowers = db.HardwareBlowers.ToObservableCollection(); + //HardwareBlowers = db.HardwareBlowers.ToObservableCollection(); + progressLog.Invoke("Loading break sensors..."); HardwareBreakSensorTypes = db.HardwareBreakSensorTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwareBreakSensors = db.HardwareBreakSensors.ToObservableCollection(); + //HardwareBreakSensors = db.HardwareBreakSensors.ToObservableCollection(); + progressLog.Invoke("Loading dancers..."); HardwareDancerTypes = db.HardwareDancerTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwareDancers = db.HardwareDancers.ToObservableCollection(); + //HardwareDancers = db.HardwareDancers.ToObservableCollection(); + progressLog.Invoke("Loading motors..."); HardwareMotorTypes = db.HardwareMotorTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwareMotors = db.HardwareMotors.ToObservableCollection(); + //HardwareMotors = db.HardwareMotors.ToObservableCollection(); + progressLog.Invoke("Loading pid controls..."); HardwarePidControlTypes = db.HardwarePidControlTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwarePidControls = db.HardwarePidControls.ToObservableCollection(); + //HardwarePidControls = db.HardwarePidControls.ToObservableCollection(); + progressLog.Invoke("Loading speed sensors..."); HardwareSpeedSensorTypes = db.HardwareSpeedSensorTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwareSpeedSensors = db.HardwareSpeedSensors.ToObservableCollection(); + //HardwareSpeedSensors = db.HardwareSpeedSensors.ToObservableCollection(); + progressLog.Invoke("Loading winders..."); HardwareWinderTypes = db.HardwareWinderTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - HardwareWinders = db.HardwareWinders.ToObservableCollection(); + //HardwareWinders = db.HardwareWinders.ToObservableCollection(); + progressLog.Invoke("Loading tech controllers..."); TechControllers = db.TechControllers.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); + + progressLog.Invoke("Loading tech dispensers..."); TechDispensers = db.TechDispensers.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); + + progressLog.Invoke("Loading tech io's..."); TechIos = db.TechIos.ToObservableCollection(); + + progressLog.Invoke("Loading tech monitors..."); TechMonitors = db.TechMonitors.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); + + progressLog.Invoke("Loading tech valves..."); TechValves = db.TechValves.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); + + progressLog.Invoke("Loading tech heaters..."); TechHeaters = db.TechHeaters.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); + progressLog.Invoke("Loading machines..."); Machines = db.Machines.Include(x => x.Organization).ToObservableCollection(); + progressLog.Invoke("Loading users..."); Users = db.Users.Where(x => !x.Deleted).Include(x => x.Contact).ToObservableCollection(); + progressLog.Invoke("Loading machine versions..."); MachineVersions = db.MachineVersions.ToObservableCollection(); - - //Load later... Task.Factory.StartNew(() => { -- cgit v1.3.1 From 7ffd0bab3c6f397936f8ef9f6829cdf33b850efa Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 19 Jan 2020 16:10:55 +0200 Subject: Implemented new ms user creation + PASSWORD_CHANGE_REQUIRED. Improved ms login design + password change. Improved ms main menu and current user design. --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes .../DB/SQLExaminer Projects/LOCAL TO DEV.seproj | 68 +++++++++ Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../Views/MachineCreationDialog.xaml | 2 +- .../Images/login.png | Bin 0 -> 6401 bytes .../Tango.MachineStudio.UsersAndRoles.csproj | 21 ++- .../ViewModels/MainViewVM.cs | 31 ++-- .../ViewModels/UserCreationDialogVM.cs | 74 ++++++++++ .../Views/UserCreationDialog.xaml | 53 +++++++ .../Views/UserCreationDialog.xaml.cs | 28 ++++ .../Views/UserManagementView.xaml | 2 +- .../Views/UserView.xaml | 2 - .../packages.config | 1 + .../Web/LoginResponse.cs | 1 + .../DefaultAuthenticationProvider.cs | 8 ++ .../Tango.MachineStudio.UI/Images/login_white.png | Bin 0 -> 3308 bytes .../Tango.MachineStudio.UI.csproj | 1 + .../ViewModels/LoginViewVM.cs | 135 +++++++++++++++++- .../Tango.MachineStudio.UI/Views/LoginView.xaml | 45 +++++- .../Tango.MachineStudio.UI/Views/MainView.xaml | 75 +++++----- .../Visual_Studio/Tango.BL/DTO/JobRunDTOBase.cs | 8 +- Software/Visual_Studio/Tango.BL/DTO/UserDTOBase.cs | 8 ++ .../Visual_Studio/Tango.BL/Entities/JobRunBase.cs | 52 +++---- Software/Visual_Studio/Tango.BL/Entities/User.cs | 39 ------ .../Visual_Studio/Tango.BL/Entities/UserBase.cs | 38 +++++ .../Visual_Studio/Tango.DAL.Remote/DB/JOB_RUNS.cs | 2 +- .../Tango.DAL.Remote/DB/RemoteADO.edmx | 9 +- .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 156 ++++++++++----------- Software/Visual_Studio/Tango.DAL.Remote/DB/USER.cs | 1 + .../Controllers/MachineStudioController.cs | 3 +- 32 files changed, 649 insertions(+), 214 deletions(-) create mode 100644 Software/DB/SQLExaminer Projects/LOCAL TO DEV.seproj create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.png (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index d11f45fb6..b662518b9 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index 34e1b9a60..2c32260dc 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/SQLExaminer Projects/LOCAL TO DEV.seproj b/Software/DB/SQLExaminer Projects/LOCAL TO DEV.seproj new file mode 100644 index 000000000..ba509261c --- /dev/null +++ b/Software/DB/SQLExaminer Projects/LOCAL TO DEV.seproj @@ -0,0 +1,68 @@ + + + + MsSqlServer + LiveDb + localhost\sqlexpress + Tango + True + + + MsSqlAzure + LiveDb + twine.database.windows.net + Tango_DEV + False + SqlServer + Roy + Aa123456 + true + + + + + + + + false + false + false + false + false + false + false + false + true + false + false + false + true + true + true + true + false + true + false + false + false + false + true + false + false + false + false + false + false + false + true + false + false + true + + + + + + + + \ No newline at end of file diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index fbfed2eae..966874e5f 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 6099b8a73..5b42f3fba 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml index e3ba1bff4..2d380c0d2 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml @@ -8,7 +8,7 @@ xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels" xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" mc:Ignorable="d" - d:DesignHeight="400" d:DesignWidth="700" Height="400" Width="700" Background="White" d:DataContext="{d:DesignInstance Type=vm:MachineCreationDialogVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="400" d:DesignWidth="700" Height="400" Width="700" Background="{StaticResource WhiteBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:MachineCreationDialogVM, IsDesignTimeCreatable=False}"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png new file mode 100644 index 000000000..9f7d0b9ba Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj index 82376b751..035cb2b9d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj @@ -49,6 +49,9 @@ ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + ..\..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll + @@ -80,6 +83,7 @@ + AddressView.xaml @@ -95,6 +99,9 @@ OrganizationSelectionView.xaml + + UserCreationDialog.xaml + UserManagementView.xaml @@ -120,7 +127,9 @@ ResXFileCodeGenerator Resources.Designer.cs - + + Designer + SettingsSingleFileGenerator @@ -186,6 +195,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -210,11 +223,13 @@ - + + + - + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs index 2f4e5c9a3..81ef04dd4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs @@ -370,20 +370,19 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels } } - private async void AddNewUser() + private void AddNewUser() { - String email = _notification.ShowTextInput("Enter user email", "email"); - - if (!String.IsNullOrWhiteSpace(email)) + _notification.ShowModalDialog(async (vm) => { User user = new User(); - user.Email = email; - user.Password = "1111"; + user.Email = vm.Email; + user.Password = User.GetPasswordHash(vm.Password); + user.PasswordChangeRequired = true; user.Contact = new Contact() { - FirstName = "Twine", - LastName = "User", - Email = email, + FirstName = vm.FirstName, + LastName = vm.LastName, + Email = vm.Email, }; user.Address = new Address(); @@ -394,6 +393,18 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.User) }); + user.UsersRoles.Add(new UsersRole() + { + User = user, + Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.MachineStudioUser) + }); + + user.UsersRoles.Add(new UsersRole() + { + User = user, + Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.PPCUser) + }); + try { user.Validate(_manageContext); @@ -413,7 +424,7 @@ namespace Tango.MachineStudio.UsersAndRoles.ViewModels await LoadOrganizations(); SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == ManagedOrganization.Guid); } - } + }); } private void SetUserPlace(Place place) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs new file mode 100644 index 000000000..08762ac96 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SimpleValidator.Extensions; +using Tango.SharedUI; + +namespace Tango.MachineStudio.UsersAndRoles.ViewModels +{ + public class UserCreationDialogVM : DialogViewVM + { + private static Random rnd = new Random(); + + private String _email; + [Required(ErrorMessage = "Email is required")] + [EmailAddress(ErrorMessage = "Please provide a valid email")] + public String Email + { + get { return _email; } + set { _email = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _password; + public String Password + { + get { return _password; } + set { _password = value; RaisePropertyChangedAuto(); } + } + + private String _firstName; + [Required(ErrorMessage = "First name is required")] + public String FirstName + { + get { return _firstName; } + set { _firstName = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _lastName; + [Required(ErrorMessage = "Last name is required")] + public String LastName + { + get { return _lastName; } + set { _lastName = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + protected override void Accept() + { + if (Validate()) + { + base.Accept(); + } + } + + public override void OnShow() + { + base.OnShow(); + Password = GetRandomPassword(4); + } + + private String GetRandomPassword(int count) + { + String pass = String.Empty; + + for (int i = 0; i < count; i++) + { + pass += rnd.Next(0, 9).ToString(); + } + + return pass; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml new file mode 100644 index 000000000..7433d3768 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml @@ -0,0 +1,53 @@ + + + + + + + + + + NEW USER + + + + + + + + + + + + + + EMAIL + + FIRST NAME + + LAST NAME + + + + + Provide this password to the user + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs new file mode 100644 index 000000000..cfa389ed1 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +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; + +namespace Tango.MachineStudio.UsersAndRoles.Views +{ + /// + /// Interaction logic for UserCreationDialog.xaml + /// + public partial class UserCreationDialog : UserControl + { + public UserCreationDialog() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml index 5246ae09c..3964abfc8 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml @@ -50,7 +50,7 @@ LOGIN - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml index 0858d7e08..37f649a7a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml @@ -16,8 +16,6 @@ - - diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config index fe4f26e87..8696cb880 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config @@ -7,4 +7,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs index 4ae22fa93..3515c32d1 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs @@ -14,5 +14,6 @@ namespace Tango.MachineStudio.Common.Web public DataSource DataSource { get; set; } public bool VersionChangeRequired { get; set; } public String RequiredVersion { get; set; } + public bool PasswordChangeRequired { get; set; } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs index 0131cd209..26938b203 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs @@ -147,6 +147,14 @@ namespace Tango.MachineStudio.UI.Authentication }; } + if (response.PasswordChangeRequired) + { + return new AuthenticationLoginResult() + { + Response = response + }; + } + try { ObservablesStaticCollections.Instance.Initialize((x) => diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.png new file mode 100644 index 000000000..10a054147 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.png differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index 13f22dfda..0525c2351 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -363,6 +363,7 @@ TCC\template.bmp Always + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs index dce469dbd..c00caf72a 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs @@ -22,6 +22,9 @@ using Tango.MachineStudio.UI.Messages; using Tango.Settings; using Tango.SharedUI; using Tango.Web; +using SimpleValidator.Extensions; +using Tango.BL.Entities; +using System.Data.Entity; namespace Tango.MachineStudio.UI.ViewModels { @@ -38,6 +41,7 @@ namespace Tango.MachineStudio.UI.ViewModels private Rfc2898Cryptographer cryptographer; private MachineStudioSettings _settings; private MachineStudioWebClient _machineStudioWebClient; + private TaskCompletionSource _updatePasswordCompletionSource; private String _email; /// @@ -82,6 +86,14 @@ namespace Tango.MachineStudio.UI.ViewModels set { _isLogging = value; RaisePropertyChangedAuto(); } } + private bool _showLogginDetails; + public bool ShowLoggingDetails + { + get { return _showLogginDetails; } + set { _showLogginDetails = value; RaisePropertyChangedAuto(); } + } + + private bool _rememberMe; /// /// Gets or sets a value indicating whether to remember the last user email and password. @@ -123,11 +135,37 @@ namespace Tango.MachineStudio.UI.ViewModels set { _progressLog = value; RaisePropertyChangedAuto(); } } + private bool _isChangingPassword; + public bool IsChangingPassword + { + get { return _isChangingPassword; } + set { _isChangingPassword = value; RaisePropertyChangedAuto(); } + } + + private String _newPassword1; + public String NewPassword1 + { + get { return _newPassword1; } + set { _newPassword1 = value; RaisePropertyChangedAuto(); } + } + + private String _newPassword2; + public String NewPassword2 + { + get { return _newPassword2; } + set { _newPassword2 = value; RaisePropertyChangedAuto(); } + } + /// /// Gets or sets the login command. /// public RelayCommand LoginCommand { get; set; } + /// + /// Gets or sets the update password command. + /// + public RelayCommand UpdatePasswordCommand { get; set; } + /// /// Initializes a new instance of the class. /// @@ -137,6 +175,7 @@ namespace Tango.MachineStudio.UI.ViewModels public LoginViewVM(MachineStudioWebClient machineStudioWebClient, IAuthenticationProvider authenticationProvider, INavigationManager navigationManager, INotificationProvider notificationProvider, IEventLogger eventLogger) { EnableSlotSelection = true; + ShowLoggingDetails = true; _machineStudioWebClient = machineStudioWebClient; _settings = SettingsManager.Default.GetOrCreate(); @@ -146,6 +185,7 @@ namespace Tango.MachineStudio.UI.ViewModels _authenticationProvider = authenticationProvider; _eventLogger = eventLogger; LoginCommand = new RelayCommand(Login, () => !IsLogging); + UpdatePasswordCommand = new RelayCommand(UpdatePassword, () => IsChangingPassword); cryptographer = new Rfc2898Cryptographer(); Email = _settings.LastLoginEmail; @@ -181,6 +221,10 @@ namespace Tango.MachineStudio.UI.ViewModels try { IsLogging = true; + ShowLoggingDetails = false; + NewPassword1 = String.Empty; + NewPassword2 = String.Empty; + InvalidateRelayCommands(); LoginMethod loginMethod = IsActiveDirectory ? LoginMethod.ActiveDirectory : LoginMethod.StandardUser; @@ -190,9 +234,9 @@ namespace Tango.MachineStudio.UI.ViewModels _settings.DeploymentSlot = DeploymentSlot; LoginResponse result = _authenticationProvider.Login(Email, Password, loginMethod, _settings.ByPassEnvironmentVersionCheck, (progress) => - { - ProgressLog = progress; - }).Response; + { + ProgressLog = progress; + }).Response; if (result.VersionChangeRequired && !_settings.ByPassEnvironmentVersionCheck) { @@ -211,6 +255,14 @@ namespace Tango.MachineStudio.UI.ViewModels return; } + if (result.PasswordChangeRequired) + { + StartUpdatePassword().Task.GetAwaiter().GetResult(); + Password = NewPassword1; + Login(); + return; + } + _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!"); _navigationManager.NavigateTo(NavigationView.MainView); @@ -224,19 +276,94 @@ namespace Tango.MachineStudio.UI.ViewModels _eventLogger.Log("User logged in."); EnableSlotSelection = false; + + IsLogging = false; + ShowLoggingDetails = true; + IsChangingPassword = false; + InvalidateRelayCommands(); }); } catch (Exception ex) { + IsLogging = false; + ShowLoggingDetails = true; + IsChangingPassword = false; + InvalidateRelayCommands(); LogManager.Log(ex, "Login Error."); _notificationProvider.ShowError($"An error occurred while trying to perform the log-in operation.\n{ex.FlattenMessage()}"); } - finally + } + } + + private TaskCompletionSource StartUpdatePassword() + { + _updatePasswordCompletionSource = new TaskCompletionSource(); + + IsChangingPassword = true; + ShowLoggingDetails = false; + IsLogging = false; + InvalidateRelayCommands(); + + return _updatePasswordCompletionSource; + } + + private async void UpdatePassword() + { + await Task.Factory.StartNew(() => + { + try + { + if (!Validate()) + { + return; + } + + ProgressLog = "Updating your password..."; + IsChangingPassword = false; + IsLogging = true; + InvalidateRelayCommands(); + + using (var db = ObservablesContext.CreateDefault()) + { + var user = db.Users.SingleOrDefault(x => x.Email == Email); + user.PasswordChangeRequired = false; + user.Password = User.GetPasswordHash(NewPassword1); + db.SaveChanges(); + } + + _updatePasswordCompletionSource.SetResult(true); + } + catch (Exception ex) { IsLogging = false; + IsChangingPassword = false; + ShowLoggingDetails = true; + InvalidateRelayCommands(); + _updatePasswordCompletionSource.SetException(ex); + } + finally + { InvalidateRelayCommands(); } + }); + } + + protected override void OnValidating() + { + if (IsChangingPassword) + { + if (!NewPassword1.IsBetweenLength(6, 8)) + { + InsertError(nameof(NewPassword1), "Password must be 6 to 8 characters long"); + } + + if (NewPassword1 != NewPassword2) + { + InsertError(nameof(NewPassword2), "Passwords do not match"); + } } + + base.OnValidating(); } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml index ff13ec2c7..9a3b3405e 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml @@ -47,7 +47,7 @@ - + @@ -57,10 +57,36 @@ - + + + + + - + Login to your account @@ -97,6 +123,19 @@ + + + Password change required + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml index 48f7b46d3..2d5a5c3aa 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml @@ -50,48 +50,19 @@ + + - - - - - - - - , - - - - - - - - - - - - - - - ... - - - - - - - - - - - - Home - - + MODULES @@ -148,8 +119,36 @@ - + + + + + + + + + , + + + + + + + + + + + + + + + ... + + + +