123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- using WingServerCommon.Config;
- using WingServerCommon.Config.Parameters;
- using WingServerCommon.Interfaces.Cache;
- using WingServerCommon.Log;
- using WingServerCommon.Utilities;
- namespace WingServerCommon.Interfaces.PasswordVerify
- {
- /// <summary>
- /// 登保用户密码过期校验
- /// </summary>
- public class PasswordExpireVerify
- {
- /// <summary>
- /// send notice 事件
- /// </summary>
- public event EventHandler<SendNoticeArgs> SendNoticeEvent;
- //待加载数据委托
- private Func<IList<string>, IList<PasswordVerifyModel>> _loadDatasFunc;
- private Queue<DateTime> _dtQueue = new Queue<DateTime>();
- //密码更新周期,天数
- private int _pwdUpdatePeriod;
- //提前预警天数
- private int _warningDays;
- //记录密码次数
- private int _keepPwdTimes;
- //预警周期cron表达式,默认频率每天10点触发
- private string _verifyPeriodCron;
- //任务周期
- private int _dutyCycle = 1 * 60 * 1000;
- // AccountType
- private int _accountType = 0;
- /// <summary>
- /// 初始化构造
- /// </summary>
- public PasswordExpireVerify(Func<IList<string>, IList<PasswordVerifyModel>> loadDatasFunc)
- {
- _pwdUpdatePeriod = ConfigurationManager.GetParammeter<IntParameter>("Authentication", "PwdUpdatePeriod").Value;
- if (_pwdUpdatePeriod <= 0)
- {
- _pwdUpdatePeriod = 90;
- }
- _warningDays = ConfigurationManager.GetParammeter<IntParameter>("Authentication", "WarningDays").Value;
- if (_warningDays <= 0)
- {
- _warningDays = 5;
- }
- _keepPwdTimes = ConfigurationManager.GetParammeter<IntParameter>("Authentication", "KeepPwdTimes").Value;
- if (_keepPwdTimes <= 0)
- {
- _keepPwdTimes = 5;
- }
- _verifyPeriodCron = ConfigurationManager.GetParammeter<StringParameter>("Authentication", "VerifyPeriodCron").Value;
- if (string.IsNullOrEmpty(_verifyPeriodCron))
- {
- _verifyPeriodCron = "0 0 10 * * ?";
- }
- _loadDatasFunc = loadDatasFunc;
- }
- /// <summary>
- /// 检查用户密码过期监听
- /// </summary>
- protected async Task VerifyUserPasswordListen(int type, bool isOpen)
- {
- if (isOpen)
- {
- var verifyTime = Convert.ToDateTime(CronHelper.GetNextDateTime(_verifyPeriodCron, DateTime.Now));
- _dtQueue.Enqueue(verifyTime);
- _accountType = type;
- var timer = new System.Timers.Timer();
- timer.Elapsed += new System.Timers.ElapsedEventHandler(Verify_Elapsed);
- timer.Interval = _dutyCycle;
- timer.Enabled = true;
- }
- }
- /// <summary>
- /// 自定义定时任务
- /// </summary>
- /// <param name="clientIdList">用户code列表</param>
- /// <param name="sendNoticeFunc">发送通知委托</param>
- /// <returns>是否成功</returns>
- private void Verify_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
- {
- try
- {
- if (_dtQueue.Count > 0)
- {
- var verifyTime = _dtQueue.Dequeue();//解析到的时间都是固定的时间点,而不是直接加间隔时间
- var curDT = DateTime.Now;
- var curStartTime = Convert.ToDateTime((curDT.ToString("yyyy-MM-dd HH:mm") + ":00"));
- var curEndTime = Convert.ToDateTime((curDT.AddMinutes(1).ToString("yyyy-MM-dd HH:mm") + ":00"));
- //只有特定的时间点,才可以执行监察工作
- if (verifyTime != null && verifyTime >= curStartTime && verifyTime < curEndTime)
- {
- Logger.WriteLineInfo($"PasswordExpireVerify Begin Run");
- //获取所有的在线的Token;
- var tokenList = CacheMaintenance.Instance.Get<ITokensManager>().Where(x => x.IsOnline == true && !string.IsNullOrEmpty(x.ClientId) && x.AccountType == _accountType);
- VerifyPasswordExpire(tokenList);
- verifyTime = Convert.ToDateTime(CronHelper.GetNextDateTime(_verifyPeriodCron, DateTime.Now));
- _dtQueue.Enqueue(verifyTime);
- Logger.WriteLineInfo($"PasswordExpireVerify End Run");
- }
- else
- {
- _dtQueue.Enqueue(verifyTime);
- }
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"Dispatch VerifyPasswordExpire Error:{ex}");
- }
- }
- /// <summary>
- /// 在线用户密码是否过期校验,如果过期,则发送通知
- /// </summary>
- /// <param name="clientIdList">用户code列表</param>
- /// <param name="sendNoticeFunc">发送通知委托</param>
- /// <returns>是否成功</returns>
- private void VerifyPasswordExpire(IList<Token> tokenList)
- {
- var clientIds = new List<string>();
- //业务处理逻辑
- if (tokenList == null || tokenList.Count <= 0)
- {
- return;
- }
- // AccountType
- // "0": "管理员",
- // "1": "用户",
- // "2": "超声机",
- // "3": "超声魔盒",
- // "4": "合作方",
- clientIds = tokenList.Select(c => c.ClientId).Distinct().ToList();
- //获取数据源
- IList<PasswordVerifyModel> dataList = _loadDatasFunc(clientIds);
- if (dataList != null && dataList.Count > 0)
- {
- //找到对应的token信息,发送通知
- var args = new SendNoticeArgs();
- foreach (var item in dataList)
- {
- if (item.PasswordLastUpdateTime < Convert.ToDateTime("2000-1-1"))
- {
- continue;
- }
- var verifyResult = VerifyData(item.ClientId, item.PasswordLastUpdateTime);
- args.VerifyList.Add(verifyResult);
- }
- if (args.VerifyList?.Count > 0)
- {
- //发送成功
- SendNoticeEvent?.Invoke(null, args);
- }
- }
- }
- /// <summary>
- /// 单个用户的验证逻辑
- /// </summary>
- /// <param name="tokenList">用户数据</param>
- /// <returns>验证结果</returns>
- protected VerifyBaseModel VerifyData(string clientId, DateTime lastUpdateTime)
- {
- var verifyResult = new VerifyBaseModel()
- {
- ClientId = clientId
- };
- //验证逻辑
- var expireTime = lastUpdateTime.AddDays(_pwdUpdatePeriod);
- var warningTime = expireTime.AddDays(-_warningDays);
- //过期时间跟当前时间比较,如果当前时间>过期时间,表示过期,否则未过期
- if (DateTime.UtcNow > expireTime)
- {
- //已过期
- TimeSpan diffTime = expireTime - DateTime.UtcNow;
- //分钟转天数
- verifyResult.SurplusTime = TransferMinutesToDays(diffTime.TotalMinutes);
- }
- //如果过期时间>当前时间,且当前时间>预警时间,则表示需要预警
- else if (expireTime > DateTime.UtcNow && DateTime.UtcNow > warningTime)
- {
- //即将过期
- TimeSpan diffTime = expireTime - warningTime;
- verifyResult.SurplusTime = TransferMinutesToDays(diffTime.TotalMinutes);
- }
- else
- {
- //无需预警
- }
- return verifyResult;
- }
- /// <summary>
- /// 分钟转天数
- /// </summary>
- /// <param name="request">修改请求数据</param>
- /// <returns>是否成功</returns>
- private double TransferMinutesToDays(double totalMinutes)
- {
- double days = 0;
- //分钟转天数
- var surplusTime = totalMinutes / (60f * 24f);
- if (Math.Abs(surplusTime) < 0.01)
- {
- days = surplusTime > 0 ? 0.01 : -0.01;
- }
- else
- {
- days = Math.Round(surplusTime, 2);
- }
- return days;
- }
- }
- /// <summary>
- /// 通知参数
- /// </summary>
- public class SendNoticeArgs : EventArgs
- {
- /// <summary>
- /// 验证结果列表
- /// </summary>
- public IList<VerifyBaseModel> VerifyList { get; set; } = new List<VerifyBaseModel>();
- }
- /// <summary>
- /// 密码验证实体
- /// </summary>
- public class PasswordVerifyModel
- {
- /// <summary>
- /// 用户id
- /// </summary>
- public string ClientId { get; set; } = string.Empty;
- /// <summary>
- /// 密码过期时间
- /// </summary>
- public DateTime PasswordLastUpdateTime { get; set; } = DateTime.MinValue;
- /// <summary>
- /// 密码记录
- /// </summary>
- public List<string> PasswordRecords { get; set; } = new List<string>();
- /// <summary>
- /// 新密码
- /// </summary>
- public string NewPassword { get; set; } = string.Empty;
- }
- /// <summary>
- /// 验证基础类
- /// </summary>
- public class VerifyBaseModel
- {
- /// <summary>
- /// 登录用户code
- /// </summary>
- public string ClientId { get; set; } = string.Empty;
-
- /// <summary>
- /// 密码过期剩余时间: 天,可以为负,负责表示已经过期
- /// </summary>
- public double SurplusTime { get; set; } = 0;
- }
- }
|