aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2020-01-19 16:10:55 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2020-01-19 16:10:55 +0200
commit7ffd0bab3c6f397936f8ef9f6829cdf33b850efa (patch)
treec2fb5b6cef2d04fe529b284a734657749880abf9 /Software/Visual_Studio/MachineStudio
parent09d432566f696f0eeb3fce97d2c870cfd1c91f89 (diff)
downloadTango-7ffd0bab3c6f397936f8ef9f6829cdf33b850efa.tar.gz
Tango-7ffd0bab3c6f397936f8ef9f6829cdf33b850efa.zip
Implemented new ms user creation + PASSWORD_CHANGE_REQUIRED.
Improved ms login design + password change. Improved ms main menu and current user design.
Diffstat (limited to 'Software/Visual_Studio/MachineStudio')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineCreationDialog.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.pngbin0 -> 6401 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj21
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs31
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs74
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml53
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs28
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config1
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs1
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs8
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.pngbin0 -> 3308 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj1
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs135
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml45
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml75
17 files changed, 417 insertions, 62 deletions
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}">
<Grid Margin="10">
<DockPanel>
<Grid DockPanel.Dock="Top">
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
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png
Binary files 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 @@
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
+ <Reference Include="SimpleValidator, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
@@ -80,6 +83,7 @@
<Compile Include="UsersAndRolesModule.cs" />
<Compile Include="ViewModelLocator.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="ViewModels\UserCreationDialogVM.cs" />
<Compile Include="Views\AddressView.xaml.cs">
<DependentUpon>AddressView.xaml</DependentUpon>
</Compile>
@@ -95,6 +99,9 @@
<Compile Include="Views\OrganizationSelectionView.xaml.cs">
<DependentUpon>OrganizationSelectionView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\UserCreationDialog.xaml.cs">
+ <DependentUpon>UserCreationDialog.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\UserManagementView.xaml.cs">
<DependentUpon>UserManagementView.xaml</DependentUpon>
</Compile>
@@ -120,7 +127,9 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
+ <None Include="app.config">
+ <SubType>Designer</SubType>
+ </None>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -186,6 +195,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\UserCreationDialog.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\UserManagementView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -210,11 +223,13 @@
<ItemGroup>
<Resource Include="Images\roles.png" />
</ItemGroup>
- <ItemGroup />
+ <ItemGroup>
+ <Resource Include="Images\login.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ 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<UserCreationDialogVM>(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 @@
+<UserControl x:Class="Tango.MachineStudio.UsersAndRoles.Views.UserCreationDialog"
+ 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:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:global="clr-namespace:Tango.MachineStudio.UsersAndRoles"
+ xmlns:vm="clr-namespace:Tango.MachineStudio.UsersAndRoles.ViewModels"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UsersAndRoles.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="400" d:DesignWidth="700" Height="400" Width="700" Background="{StaticResource WhiteBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:UserCreationDialogVM, IsDesignTimeCreatable=False}">
+ <Grid Margin="10">
+ <DockPanel>
+ <Grid DockPanel.Dock="Top">
+ <StackPanel Orientation="Horizontal">
+ <Grid>
+ <Image Source="../Images/login.png" Width="80" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <materialDesign:PackIcon HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 -14 -10" Kind="PlusCircle" Foreground="#15C315" Width="42" Height="42" />
+ </Grid>
+ <TextBlock Margin="30 0 0 0" VerticalAlignment="Bottom" FontSize="22">NEW USER</TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <Grid DockPanel.Dock="Bottom">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" DockPanel.Dock="Bottom">
+ <Button Command="{Binding CloseCommand}" Width="140" Height="40" Margin="0 0 10 0">
+ CANCEL
+ </Button>
+ <Button Command="{Binding OKCommand}" IsDefault="True" Width="140" Height="40">
+ CREATE
+ </Button>
+ </StackPanel>
+ </Grid>
+
+ <Grid>
+ <StackPanel Width="400" HorizontalAlignment="Center" Margin="20">
+ <controls:TableGrid RowHeight="40">
+ <TextBlock>EMAIL</TextBlock>
+ <TextBox Text="{Binding Email,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox>
+ <TextBlock>FIRST NAME</TextBlock>
+ <TextBox Text="{Binding FirstName,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox>
+ <TextBlock>LAST NAME</TextBlock>
+ <TextBox Text="{Binding LastName,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}"></TextBox>
+ </controls:TableGrid>
+
+ <TextBox Margin="0 -15 0 0" Style="{x:Null}" BorderThickness="0" FontSize="30" HorizontalAlignment="Center" Text="{Binding Password}" IsReadOnly="True"></TextBox>
+ <TextBlock HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="{StaticResource GrayBrush}">Provide this password to the user</TextBlock>
+ </StackPanel>
+ </Grid>
+ </DockPanel>
+ </Grid>
+</UserControl>
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
+{
+ /// <summary>
+ /// Interaction logic for UserCreationDialog.xaml
+ /// </summary>
+ 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 @@
<StackPanel>
<TextBlock FontSize="16" FontWeight="SemiBold">LOGIN</TextBlock>
<Border Width="300" BorderThickness="1" BorderBrush="Gray" Margin="0 5 0 0" Padding="15 5" Height="150" Background="{StaticResource TransparentBackgroundBrush500}">
- <local:UserView FontSize="10" DataContext="{Binding ManagedUser}" />
+ <local:UserView VerticalAlignment="Top" Margin="0 15 0 0" FontSize="10" DataContext="{Binding ManagedUser}" />
</Border>
</StackPanel>
<StackPanel Margin="10 0 0 0">
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 @@
<controls:TableGrid>
<TextBlock Text="EMAIL"></TextBlock>
<TextBox Text="{Binding Email}"></TextBox>
- <TextBlock Text="PASSWORD"></TextBlock>
- <PasswordBox MaxLength="30" pass:PasswordHelper.Attach="True" pass:PasswordHelper.Password="{Binding PasswordGateWay,Mode=TwoWay}"></PasswordBox>
</controls:TableGrid>
</Grid>
</UserControl>
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 @@
<package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" />
<package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+ <package id="SimpleValidator" version="0.6.1.0" targetFramework="net461" />
</packages> \ 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
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.png
Binary files 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 @@
<Link>TCC\template.bmp</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
+ <Resource Include="Images\login_white.png" />
<Resource Include="Images\login.png" />
<Resource Include="Images\active_directory.png" />
<Resource Include="Images\machinestudio_login.png" />
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<object> _updatePasswordCompletionSource;
private String _email;
/// <summary>
@@ -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;
/// <summary>
/// Gets or sets a value indicating whether to remember the last user email and password.
@@ -123,12 +135,38 @@ 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(); }
+ }
+
/// <summary>
/// Gets or sets the login command.
/// </summary>
public RelayCommand LoginCommand { get; set; }
/// <summary>
+ /// Gets or sets the update password command.
+ /// </summary>
+ public RelayCommand UpdatePasswordCommand { get; set; }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="LoginViewVM"/> class.
/// </summary>
/// <param name="authenticationProvider">The authentication provider.</param>
@@ -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<MachineStudioSettings>();
@@ -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<object> StartUpdatePassword()
+ {
+ _updatePasswordCompletionSource = new TaskCompletionSource<object>();
+
+ 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 @@
</StackPanel>
<Grid>
- <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-600 110 0 0" Visibility="{Binding IsLogging,Converter={StaticResource BooleanToVisibilityInverseConverter}}">
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-600 110 0 0" Visibility="{Binding ShowLoggingDetails,Converter={StaticResource BooleanToVisibilityConverter}}">
<RadioButton ToolTip="Login using your an active directory account" IsChecked="{Binding IsActiveDirectory}" FontSize="16" VerticalContentAlignment="Center" Padding="10 0 0 0">
<Image Source="/Images/active_directory.png" Stretch="Uniform" Height="80" RenderOptions.BitmapScalingMode="Fant" />
</RadioButton>
@@ -57,10 +57,36 @@
</StackPanel>
<DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="320" Margin="0 120 0 0" Height="510">
- <Button DockPanel.Dock="Bottom" AutomationProperties.AutomationId="{x:Static automation:UI.LoginButton}" Margin="25 20 0 0" Height="50" Command="{Binding LoginCommand}" Content="LOGIN"></Button>
+ <Grid DockPanel.Dock="Bottom" Margin="25 20 0 0" >
+ <Button AutomationProperties.AutomationId="{x:Static automation:UI.LoginButton}" Height="50" Command="{Binding LoginCommand}" Content="LOGIN">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsChangingPassword}" Value="True">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button AutomationProperties.AutomationId="{x:Static automation:UI.LoginButton}" Height="50" Command="{Binding UpdatePasswordCommand}" Content="CHANGE PASSWORD">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsChangingPassword}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ </Grid>
<Grid>
- <StackPanel Visibility="{Binding IsLogging,Converter={StaticResource BooleanToVisibilityInverseConverter}}">
+ <StackPanel Visibility="{Binding ShowLoggingDetails,Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock HorizontalAlignment="Center" FontSize="24">Login to your account</TextBlock>
<Image Source="/Images/login.png" RenderOptions.BitmapScalingMode="Fant" Width="100" Margin="0 20 0 0"></Image>
<DockPanel Margin="0 20 0 0">
@@ -97,6 +123,19 @@
</Grid>
<TextBlock HorizontalAlignment="Center" Margin="0 30 0 0" FontSize="16" FontStyle="Italic" Foreground="{StaticResource GrayBrush200}" Text="{Binding ProgressLog}"></TextBlock>
</StackPanel>
+
+ <StackPanel Visibility="{Binding IsChangingPassword,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <TextBlock HorizontalAlignment="Center" FontSize="24">Password change required</TextBlock>
+ <Image Source="/Images/login.png" RenderOptions.BitmapScalingMode="Fant" Width="100" Margin="0 20 0 0"></Image>
+ <DockPanel Margin="0 40 0 0">
+ <materialDesign:PackIcon Margin="0 0 0 0" Width="20" Height="20" VerticalAlignment="Top" Foreground="{Binding ElementName=txtNewPass1, Path=BorderBrush}" Kind="Key" />
+ <PasswordBox x:Name="txtNewPass1" helpers:PasswordHelper.Attach="True" helpers:PasswordHelper.Password="{Binding NewPassword1,Mode=TwoWay,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}" Margin="5 0 0 0" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="New Password" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" FontSize="20" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" AutomationProperties.IsRequiredForForm="True" />
+ </DockPanel>
+ <DockPanel Margin="0 40 0 0">
+ <materialDesign:PackIcon Margin="0 0 0 0" Width="20" Height="20" VerticalAlignment="Top" Foreground="{Binding ElementName=txtNewPass2, Path=BorderBrush}" Kind="Key" />
+ <PasswordBox x:Name="txtNewPass2" helpers:PasswordHelper.Attach="True" helpers:PasswordHelper.Password="{Binding NewPassword2,Mode=TwoWay,UpdateSourceTrigger=LostFocus,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}" Margin="5 0 0 0" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="Confirm Password" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" FontSize="20" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" AutomationProperties.IsRequiredForForm="True" />
+ </DockPanel>
+ </StackPanel>
</Grid>
</DockPanel>
</Grid>
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 @@
<DockPanel LastChildFill="False" TextElement.Foreground="{StaticResource MainWindow.Foreground}" >
<StackPanel MinWidth="300" DockPanel.Dock="Top">
<Grid>
+ <Button Foreground="{StaticResource BlackBrush}" Style="{StaticResource MaterialDesignFlatButton}" Command="{Binding HomeCommand}" HorizontalAlignment="Left" HorizontalContentAlignment="Left" Margin="5 10 0 0" Width="200" Height="40" Padding="5 8 8 8">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon VerticalAlignment="Center" Kind="Home" Width="32" Height="32"></materialDesign:PackIcon>
+ <TextBlock FontSize="16" VerticalAlignment="Center" Margin="10 0 0 0">Home</TextBlock>
+ </StackPanel>
+ </Button>
+
<ToggleButton Style="{StaticResource MaterialDesignHamburgerToggleButton}"
HorizontalAlignment="Right" Margin="16"
IsChecked="{Binding Source={x:Reference MenuToggleButton}, Path=IsChecked, Mode=TwoWay}" />
-
- <StackPanel Margin="5 0 0 0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
- <Image Source="/Images/login.png" RenderOptions.BitmapScalingMode="Fant" VerticalAlignment="Center" Width="50" Height="50"></Image>
- <StackPanel Margin="0 5 0 0">
- <TextBlock FontSize="16" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" FontWeight="Bold" Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding AuthenticationProvider.CurrentUser.Contact.FullName}"></TextBlock>
- <TextBlock FontSize="12" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" Margin="10 5 0 0" VerticalAlignment="Center">
- <Run Text="{Binding AuthenticationProvider.CurrentUser.Organization.Name}"></Run>
- ,
- <Run Text="{Binding AuthenticationProvider.CurrentUser.Roles[0].Name}">
- <Run.ToolTip>
- <ItemsControl ItemsSource="{Binding AuthenticationProvider.CurrentUser.Roles}">
- <ItemsControl.ItemTemplate>
- <DataTemplate>
- <StackPanel Orientation="Horizontal" Margin="2">
- <materialDesign:PackIcon Kind="AccountKey" Width="16" Height="16" />
- <TextBlock Margin="5 0 0 0" Text="{Binding Name}"></TextBlock>
- </StackPanel>
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
- </Run.ToolTip>
- </Run>
- <Run>...</Run>
- </TextBlock>
- </StackPanel>
- </StackPanel>
</Grid>
<StackPanel Margin="0 16 0 0">
- <ListBoxItem>
- <i:Interaction.Triggers>
- <i:EventTrigger EventName="PreviewMouseUp">
- <i:InvokeCommandAction Command="{Binding HomeCommand}"></i:InvokeCommandAction>
- </i:EventTrigger>
- </i:Interaction.Triggers>
- <StackPanel Orientation="Horizontal">
- <materialDesign:PackIcon VerticalAlignment="Center" Kind="Home" Width="32" Height="32"></materialDesign:PackIcon>
- <TextBlock FontSize="16" VerticalAlignment="Center" Margin="10 0 0 0">Home</TextBlock>
- </StackPanel>
- </ListBoxItem>
+
</StackPanel>
<StackPanel Margin="10 10 0 0">
<TextBlock Foreground="{StaticResource borderBrush}" FontSize="16" FontWeight="Bold" FontStyle="Italic">MODULES</TextBlock>
@@ -148,8 +119,36 @@
<materialDesign:ColorZone Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth2"
Mode="PrimaryMid" DockPanel.Dock="Top" Background="{StaticResource MainWindow.Header}">
<DockPanel>
- <ToggleButton Style="{StaticResource MaterialDesignHamburgerToggleButton}" IsChecked="{Binding IsMenuOpened}"
+ <StackPanel Orientation="Horizontal">
+ <ToggleButton VerticalAlignment="Center" Style="{StaticResource MaterialDesignHamburgerToggleButton}" IsChecked="{Binding IsMenuOpened}"
x:Name="MenuToggleButton"/>
+
+ <StackPanel Margin="10 0 0 0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
+ <Image Source="/Images/login_white.png" RenderOptions.BitmapScalingMode="Fant" VerticalAlignment="Center" Width="50" Height="50"></Image>
+ <StackPanel Margin="0 5 0 0">
+ <TextBlock FontSize="16" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" FontWeight="Bold" Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding AuthenticationProvider.CurrentUser.Contact.FullName}"></TextBlock>
+ <TextBlock FontSize="12" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" Margin="10 5 0 0" VerticalAlignment="Center">
+ <Run Text="{Binding AuthenticationProvider.CurrentUser.Organization.Name}"></Run>
+ ,
+ <Run Text="{Binding AuthenticationProvider.CurrentUser.Roles[0].Name}">
+ <Run.ToolTip>
+ <ItemsControl ItemsSource="{Binding AuthenticationProvider.CurrentUser.Roles}">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" Margin="2">
+ <materialDesign:PackIcon Kind="AccountKey" Width="16" Height="16" />
+ <TextBlock Margin="5 0 0 0" Text="{Binding Name}"></TextBlock>
+ </StackPanel>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Run.ToolTip>
+ </Run>
+ <Run>...</Run>
+ </TextBlock>
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False" >
<StackPanel>
<Button Command="{Binding ConnectCommand}">