更新库文件600d1bc,完善单一用户登录机制,增加登录测试项目UserLoginTester。
This commit is contained in:
parent
ad1f13c3e0
commit
f9197020b8
|
@ -59,7 +59,7 @@
|
|||
BorderBrush="Gray"
|
||||
BorderThickness="3"
|
||||
Message="{Binding RequestLoginIndicatorText}"
|
||||
Visibility="{Binding IsShowRequestLoginIndicator, Converter={StaticResource BoolVisibilityConverter}}">
|
||||
Visibility="{Binding IsShowLoginWaiter, Converter={StaticResource BoolVisibilityConverter}}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Canceled">
|
||||
<cal:ActionMessage MethodName="CancelRequestLogin" />
|
||||
|
@ -1098,7 +1098,7 @@
|
|||
Style="{DynamicResource Logout_Button}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Click">
|
||||
<cal:ActionMessage MethodName="Logout" />
|
||||
<cal:ActionMessage MethodName="ShowLogoutDialog" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</Button>
|
||||
|
|
|
@ -27,10 +27,7 @@ using Sicentury.Core.Collections;
|
|||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Aitex.Core.WCF.Interface;
|
||||
using Caliburn.Micro.Core;
|
||||
using AuthorizeResult = MECF.Framework.UI.Client.ClientBase.AuthorizeResult;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace SicUI.Client
|
||||
{
|
||||
|
@ -412,27 +409,31 @@ namespace SicUI.Client
|
|||
break;
|
||||
|
||||
case EventType.LoginBySameUser_Notify:
|
||||
if (evt.Tag is Credential cred)
|
||||
if (Guid.TryParse(evt.Description, out var token) && evt.Tag is Credential requestingCred)
|
||||
{
|
||||
if (cred.LoginName == BaseApp.Instance.UserContext.LoginName
|
||||
|| cred.Token == BaseApp.Instance.UserContext.Token)
|
||||
if (token == BaseApp.Instance.UserContext.Token)
|
||||
{
|
||||
Execute.OnUIThread(()=>
|
||||
{
|
||||
var ret = DialogBox.ShowDialog(
|
||||
DialogButton.Yes | DialogButton.No,
|
||||
DialogType.INFO,
|
||||
"Some users is logging into the system, you will be forced to switch to read-only mode, do you agree?");
|
||||
"Some users is requesting to login the system, you will be forced to switch to read-only mode, do you agree?");
|
||||
|
||||
if (ret == DialogButton.Yes)
|
||||
{
|
||||
AccountClient.Instance.Service.ConfirmLoginRequest(requestingCred);
|
||||
|
||||
Logoff();
|
||||
User.LoginName = "Read-Only";
|
||||
|
||||
// 降级为仅查看模式
|
||||
BaseApp.Instance.UserContext.Credential = Credential.ReadOnlyOne;
|
||||
IsReadOnlyMode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AccountClient.Instance.Service.RejectLoginRequest(requestingCred);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -455,20 +456,21 @@ namespace SicUI.Client
|
|||
|
||||
}
|
||||
|
||||
#region login part
|
||||
#region Login/Logout Operations
|
||||
|
||||
public void Enter(KeyEventArgs args, string loginName, PasswordBox password, Role role)
|
||||
{
|
||||
if (args.Key == Key.Enter)
|
||||
Login(loginName, password, role);
|
||||
RequestLogin(loginName, password, role);
|
||||
}
|
||||
|
||||
private bool _isShowRequestLoginIndicator;
|
||||
public bool IsShowRequestLoginIndicator
|
||||
private bool _isShowLoginWaiter;
|
||||
public bool IsShowLoginWaiter
|
||||
{
|
||||
get=>_isShowRequestLoginIndicator;
|
||||
get=>_isShowLoginWaiter;
|
||||
set
|
||||
{
|
||||
_isShowRequestLoginIndicator = value;
|
||||
_isShowLoginWaiter = value;
|
||||
NotifyOfPropertyChange();
|
||||
}
|
||||
}
|
||||
|
@ -484,12 +486,14 @@ namespace SicUI.Client
|
|||
}
|
||||
}
|
||||
|
||||
private Task<LoginRequestResults> _loginTask;
|
||||
private Task<LoginResult> _loginTask;
|
||||
private CancellationTokenSource _ctsWaitingTask;
|
||||
private string _lastLoginUserName = "";
|
||||
|
||||
public void CancelRequestLogin()
|
||||
{
|
||||
AccountClient.Instance.Service.CancelLoginRequest();
|
||||
if(string.IsNullOrEmpty(_lastLoginUserName) == false)
|
||||
AccountClient.Instance.Service.CancelLoginRequest(_lastLoginUserName);
|
||||
}
|
||||
|
||||
public Task ShowRequestLoginIndicator()
|
||||
|
@ -508,7 +512,7 @@ namespace SicUI.Client
|
|||
if (token.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
Execute.OnUIThread(() => IsShowRequestLoginIndicator = true);
|
||||
Execute.OnUIThread(() => IsShowLoginWaiter = true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -529,7 +533,7 @@ namespace SicUI.Client
|
|||
Execute.OnUIThread(() =>
|
||||
{
|
||||
RequestLoginIndicatorText = "Waiting for RT to confirm login request, 0s remained";
|
||||
IsShowRequestLoginIndicator = false;
|
||||
IsShowLoginWaiter = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -540,13 +544,17 @@ namespace SicUI.Client
|
|||
if (_loginTask is { Status: TaskStatus.Running })
|
||||
return;
|
||||
|
||||
Task taskWaiting = default;
|
||||
_lastLoginUserName = loginName;
|
||||
|
||||
var myInfo = new LoginClientInfo();
|
||||
myInfo.HostName = Dns.GetHostName();
|
||||
myInfo.HostIP = (await Dns.GetHostEntryAsync(myInfo.HostName)).AddressList[0];
|
||||
|
||||
// 向RT请求登录
|
||||
try
|
||||
{
|
||||
taskWaiting =ShowRequestLoginIndicator();
|
||||
_loginTask = AccountClient.Instance.Service.RequestLogin();
|
||||
var taskWaiting = ShowRequestLoginIndicator();
|
||||
_loginTask = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role.RoleId, myInfo);
|
||||
|
||||
await Task.WhenAny(_loginTask, taskWaiting);
|
||||
|
||||
|
@ -554,120 +562,81 @@ namespace SicUI.Client
|
|||
|
||||
if (taskWaiting.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
// 等待超时
|
||||
DialogBox.ShowError("Login failed, timeout of waiting login request confirmation.");
|
||||
AccountClient.Instance.Service.CancelLoginRequest(loginName);
|
||||
}
|
||||
else if (_loginTask.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
switch (_loginTask.Result.Result)
|
||||
{
|
||||
case LoginRequestResults.Error:
|
||||
DialogBox.ShowError("Error occurred when login, see log for details.");
|
||||
break;
|
||||
case LoginRequestResults.WrongPwd:
|
||||
DialogBox.ShowError("Invalid password.");
|
||||
break;
|
||||
case LoginRequestResults.NoMatchRole:
|
||||
DialogBox.ShowError("The user does not belong to the role.");
|
||||
break;
|
||||
case LoginRequestResults.NoMatchUser:
|
||||
DialogBox.ShowError("The user is not found.");
|
||||
break;
|
||||
case LoginRequestResults.Rejected:
|
||||
DialogBox.ShowError("Login Request is rejected.");
|
||||
break;
|
||||
case LoginRequestResults.RequstingLogin:
|
||||
DialogBox.ShowError(
|
||||
"The same user is requesting to login from other place, please try again later.");
|
||||
break;
|
||||
case LoginRequestResults.Timeout:
|
||||
DialogBox.ShowError("Timeout to wait login request confirmation.");
|
||||
break;
|
||||
case LoginRequestResults.Confirmed:
|
||||
var cred = _loginTask.Result.Credential;
|
||||
BaseApp.Instance.UserMode = UserMode.Normal;
|
||||
BaseApp.Instance.UserContext.Credential = cred;
|
||||
BaseApp.Instance.UserContext.Role = role;
|
||||
BaseApp.Instance.UserContext.LastAccessTime = DateTime.Now;
|
||||
BaseApp.Instance.UserContext.IsLogin = true;
|
||||
|
||||
//Load menu by role
|
||||
//filer menu if necessary...
|
||||
BaseApp.Instance.MenuManager.LoadMenu(
|
||||
RoleAccountProvider.Instance.GetMenusByRole(role.RoleId));
|
||||
|
||||
IsAutoLogout = role.IsAutoLogout;
|
||||
LogoutTime = role.LogoutTime;
|
||||
|
||||
IsPermission = RoleAccountProvider.Instance.GetMenuPermission(role.RoleId, "Header") == 3;
|
||||
|
||||
InitMenu(); //bind menu to main view
|
||||
|
||||
IsLogin = true; //control the display logic of main view
|
||||
IsReadOnlyMode = false;
|
||||
|
||||
LOG.Info($"{loginName} login as {role.RoleName}");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
DialogBox.ShowError("Unknown login result, see log for details.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (_loginTask.Result == LoginRequestResults.Rejected)
|
||||
DialogBox.ShowError("Login failed, rejected by RT.");
|
||||
else
|
||||
Login(loginName, password, role);
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void Login(string loginName, PasswordBox password, Role role)
|
||||
{
|
||||
try
|
||||
{
|
||||
var myInfo = new LoginClientInfo();
|
||||
myInfo.HostName = Dns.GetHostName();
|
||||
myInfo.HostIP = Dns.GetHostEntry(myInfo.HostName).AddressList[0];
|
||||
|
||||
var result = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role.RoleId, myInfo);
|
||||
if (result.ActSucc)
|
||||
{
|
||||
BaseApp.Instance.UserMode = UserMode.Normal;
|
||||
BaseApp.Instance.UserContext.LoginName = loginName;
|
||||
BaseApp.Instance.UserContext.Role = role;
|
||||
BaseApp.Instance.UserContext.LoginTime = result.LoginTime;
|
||||
BaseApp.Instance.UserContext.Token = result.Token;
|
||||
BaseApp.Instance.UserContext.LastAccessTime = DateTime.Now;
|
||||
BaseApp.Instance.UserContext.IsLogin = true;
|
||||
|
||||
//Load menu by role
|
||||
//filer menu if necessary...
|
||||
BaseApp.Instance.MenuManager.LoadMenu(RoleAccountProvider.Instance.GetMenusByRole(role.RoleId));
|
||||
|
||||
IsAutoLogout = role.IsAutoLogout;
|
||||
LogoutTime = role.LogoutTime;
|
||||
|
||||
IsPermission = RoleAccountProvider.Instance.GetMenuPermission(role.RoleId, "Header") == 3;
|
||||
|
||||
InitMenu(); //bind menu to main view
|
||||
|
||||
IsLogin = true; //control the display logic of main view
|
||||
IsReadOnlyMode = false;
|
||||
|
||||
LOG.Info($"{loginName} login as {role.RoleName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Enum.TryParse(result.Description, out AuthorizeResult errCode);
|
||||
|
||||
switch (errCode)
|
||||
{
|
||||
case AuthorizeResult.None:
|
||||
DialogBox.ShowError("Not connected with RT.");
|
||||
break;
|
||||
case AuthorizeResult.WrongPwd:
|
||||
DialogBox.ShowError("Invalid password.");
|
||||
break;
|
||||
case AuthorizeResult.HasLogin:
|
||||
DialogBox.ShowError("{0} has already logged in.", loginName);
|
||||
break;
|
||||
case AuthorizeResult.NoMatchRole:
|
||||
DialogBox.ShowError("{0} does not match {1} role.", loginName, role.RoleName);
|
||||
break;
|
||||
case AuthorizeResult.NoMatchUser:
|
||||
DialogBox.ShowError("{0} does not exists.", loginName);
|
||||
break;
|
||||
case AuthorizeResult.NoSession:
|
||||
DialogBox.ShowError("The current session is invalid.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
password.Clear();
|
||||
LOG.Error(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOG.Error(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void SetModuleOnline(string module)
|
||||
{
|
||||
if (MessageBoxResult.Yes == MessageBox.Show($"Set {module} Online ?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning))
|
||||
{
|
||||
InvokeClient.Instance.Service.DoOperation($"{module}.SetOnline");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetModuleOffline(string module)
|
||||
{
|
||||
if (MessageBoxResult.Yes == MessageBox.Show($"Set {module} Offline ?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning))
|
||||
{
|
||||
InvokeClient.Instance.Service.DoOperation($"{module}.SetOffline");
|
||||
LOG.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Logout()
|
||||
{
|
||||
OnLogoutCommand();
|
||||
}
|
||||
|
||||
public void OnLogoutCommand()
|
||||
public void ShowLogoutDialog()
|
||||
{
|
||||
if (!IsReadOnlyMode)
|
||||
{
|
||||
|
@ -715,6 +684,7 @@ namespace SicUI.Client
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void Logoff()
|
||||
{
|
||||
BaseApp.Instance.UserMode = UserMode.Logoff;
|
||||
|
@ -735,9 +705,25 @@ namespace SicUI.Client
|
|||
}
|
||||
IsLogin = false; //no independent login page
|
||||
Roles = RoleAccountProvider.Instance.GetRoles();
|
||||
// 如果 ProcessMonitor 打开,则关闭
|
||||
//if (_eventAggregator?.HandlerExistsFor(typeof(ShowCloseMonitorWinEvent)) == true)
|
||||
// _eventAggregator?.PublishOnUIThread(new ShowCloseMonitorWinEvent(false));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetModuleOnline(string module)
|
||||
{
|
||||
if (MessageBoxResult.Yes == MessageBox.Show($"Set {module} Online ?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning))
|
||||
{
|
||||
InvokeClient.Instance.Service.DoOperation($"{module}.SetOnline");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetModuleOffline(string module)
|
||||
{
|
||||
if (MessageBoxResult.Yes == MessageBox.Show($"Set {module} Offline ?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning))
|
||||
{
|
||||
InvokeClient.Instance.Service.DoOperation($"{module}.SetOffline");
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
@ -751,15 +737,13 @@ namespace SicUI.Client
|
|||
}
|
||||
|
||||
#region override functions
|
||||
|
||||
public override void CanClose(Action<bool> callback)
|
||||
{
|
||||
if (BaseApp.Instance.UserMode == UserMode.Normal)
|
||||
{
|
||||
callback(false);
|
||||
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate
|
||||
{
|
||||
OnLogoutCommand();
|
||||
});
|
||||
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)ShowLogoutDialog);
|
||||
}
|
||||
else
|
||||
callback(true);
|
||||
|
@ -774,7 +758,7 @@ namespace SicUI.Client
|
|||
StartTimer();
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, null));
|
||||
RequestLogin("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -942,23 +926,34 @@ namespace SicUI.Client
|
|||
if (_alarmMenu != null)
|
||||
_alarmMenu.IsAlarm = SystemHasAlarm;
|
||||
}
|
||||
|
||||
protected override bool OnTimer()
|
||||
{
|
||||
try
|
||||
{
|
||||
base.Poll();
|
||||
List<Role> roles = RoleAccountProvider.Instance.GetRoles();
|
||||
if (!string.IsNullOrEmpty(BaseApp.Instance.UserContext.Role.RoleName))
|
||||
var roles = RoleAccountProvider.Instance.GetRoles();
|
||||
if (!Credential.IsEmpty(BaseApp.Instance.UserContext.Credential))
|
||||
{
|
||||
Role role = roles.Find(x => x.RoleName == BaseApp.Instance.UserContext.Role.RoleName);
|
||||
var role = roles.Find(x => x.RoleName == BaseApp.Instance.UserContext.Role.RoleName);
|
||||
LogoutTime = role.LogoutTime;
|
||||
IsAutoLogout = role.IsAutoLogout;
|
||||
int intervaltime = GetLastInputTime();
|
||||
//if (System.DateTime.Now >= ClientApp.Instance.UserContext.LoginTime.AddMinutes(LogoutTime) && IsLogin && IsAutoLogout)
|
||||
if (intervaltime >= LogoutTime * 60 && IsLogin && IsAutoLogout)
|
||||
var idleDuration = GetLastInputTime();
|
||||
if (idleDuration >= LogoutTime * 60 && IsLogin && IsAutoLogout)
|
||||
Logoff();
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep credential alive
|
||||
var ret = AccountClient.Instance.Service.KeepAlive(BaseApp.Instance.UserContext.Token);
|
||||
if (ret == CredentialKeepAliveResults.NotFound)
|
||||
{
|
||||
Logoff();
|
||||
|
||||
Execute.OnUIThread(() => { DialogBox.ShowError("You are kicked by RT."); });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Aitex.Core.RT.Log;
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue