using Furion.DatabaseAccessor.Extensions;
using Furion.EventBus;
using Microsoft.Extensions.Options;
using UAParser;
using YBEE.EQM.Core;
namespace YBEE.EQM.Application;
///
/// 认证服务
///
public class SysAuthService(IOptions options,
IHttpContextAccessor httpContextAccessor,
IEventPublisher eventPublisher,
IRepository userRep,
ISysRoleUserService roleUserService,
ISysMenuService menuService,
IGeneralCaptchaService captchaService) : ISysAuthService, ITransient
{
private readonly AuthOptions _authOptions = options.Value;
///
/// 登录处理
///
/// 账户密码
///
private async Task Login(LoginInput accountLoginInput)
{
var checkCaptcha = captchaService.CheckCode(accountLoginInput.Captcha);
if (checkCaptcha.Code != 0)
{
throw Oops.Oh(checkCaptcha.Message);
}
string pwd = "";
string newPwd = "";
try
{
pwd = RSAEncryption.Decrypt(accountLoginInput.Password, _authOptions.RsaPrivateKey);
if (!string.IsNullOrEmpty(accountLoginInput.NewPassword))
{
newPwd = RSAEncryption.Decrypt(accountLoginInput.NewPassword, _authOptions.RsaPrivateKey);
if (pwd == newPwd)
{
throw Oops.Oh(ErrorCode.E1009);
}
}
}
catch
{
throw Oops.Oh("密码格式错误!");
}
//// 判断用户名和密码是否正确 忽略全局过滤器
//var users = await _userRep.DetachedEntities
// .Include(t => t.SysOrg)
// .Where(u => (u.Account.Equals(accountLoginInput.Account) || u.Mobile.Equals(accountLoginInput.Account) || u.Email.Equals(accountLoginInput.Account)) && u.IsDeleted == false)
// .ToListAsync();
var user = await userRep.Include(t => t.SysOrg)
.FirstOrDefaultAsync(u => u.IsDeleted == false &&
(u.Account.Equals(accountLoginInput.Account) ||
u.Mobile.Equals(accountLoginInput.Account) ||
u.Email.Equals(accountLoginInput.Account)
)) ?? throw Oops.Oh(ErrorCode.E1001);
//if (!AESEncryption.Decrypt(user.Password, _authOptions.AesPassword).Equals(pwd))
if (!PBKDF2Encryption.Compare(pwd, user.Password))
{
throw Oops.Oh(ErrorCode.E1001);
}
//var user = (users?.FirstOrDefault(u => AESEncryption.Decrypt(u.Password, _authOptions.AesPassword).Equals(pwd))) ?? throw Oops.Oh(ErrorCode.E1001);
if (!user.IsActivated && newPwd != "")
{
//user.Password = AESEncryption.Encrypt(newPwd, _authOptions.AesPassword);
user.Password = PBKDF2Encryption.Encrypt(newPwd);
user.IsActivated = true;
user.ActivateTime = DateTime.Now;
await user.UpdateIncludeNowAsync(new[] { nameof(user.Password), nameof(user.IsActivated), nameof(user.ActivateTime) });
}
AuthOutput ret = new()
{
OrgName = user.SysOrg.Name,
Name = user.Name,
Account = user.Account,
IsActivated = user.IsActivated,
AccessToken = "",
};
if (!user.IsActivated)
{
return ret;
}
// 验证账号是否被冻结
if (user.Status == CommonStatus.DISABLE)
{
throw Oops.Oh(ErrorCode.E1003);
}
var isSuperAdmin = await roleUserService.IsSuperAdmin(user.Id);
// 生成Token令牌
var accessToken = JWTEncryption.Encrypt(new Dictionary
{
{ClaimConst.CLAINM_USERID, user.Id},
{ClaimConst.CLAINM_ACCOUNT, user.Account},
{ClaimConst.CLAINM_NAME, user.Name},
{ClaimConst.CLAINM_ORGID, user.SysOrgId},
{ClaimConst.CLAINM_ORGNAME, user.SysOrg.Name},
{ClaimConst.CLAINM_SUPERADMIN, isSuperAdmin.ToString()},
});
// 设置Swagger自动登录
httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
// 生成刷新Token令牌
var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, App.GetOptions().ExpiredTime);
// 设置刷新Token令牌
httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
ret.AccessToken = accessToken;
return ret;
}
///
/// 账户密码登录
///
///
///
public async Task LoginByAccount([Required] LoginInput input)
{
return await Login(accountLoginInput: input);
}
///
/// 获取当前登录用户信息
///
///
public async Task GetLoginUser()
{
var user = await userRep.Include(t => t.SysOrg).FirstOrDefaultAsync(u => u.Id == CurrentSysUserInfo.SysUserId) ?? throw Oops.Oh(ErrorCode.E1002);
var userId = user.Id;
var loginOutput = user.Adapt();
var httpContext = httpContextAccessor.HttpContext;
loginOutput.LastLoginTime = user.LastLoginTime = DateTime.Now;
loginOutput.LastLoginIp = user.LastLoginIp = httpContext.GetRequestIPv4();
var client = Parser.GetDefault().Parse(httpContext.Request.Headers["User-Agent"]);
loginOutput.LastLoginBrowser = client.UA.Family + client.UA.Major;
loginOutput.LastLoginOs = client.OS.Family + client.OS.Major;
// 角色信息
loginOutput.SysRoles = await roleUserService.GetLoginUserRoleList(userId);
// 权限信息
loginOutput.Permissions = await menuService.GetLoginPermissionList(userId);
// 系统所有权限信息
loginOutput.AllPermissions = await menuService.GetAllPermissionList();
// 菜单信息
loginOutput.Menus = await menuService.GetLoginAntMenus(userId);
// 更新用户最后登录Ip和时间
await userRep.UpdateIncludeAsync(user, new[] { nameof(SysUser.LastLoginIp), nameof(SysUser.LastLoginTime) });
// 增加登录日志
await eventPublisher.PublishAsync(new ChannelEventSource("Create:VisLog",
new SysLogVis
{
Name = loginOutput.Name,
Success = true,
Message = "登录成功",
Ip = loginOutput.LastLoginIp,
Browser = loginOutput.LastLoginBrowser,
Os = loginOutput.LastLoginOs,
VisType = LoginType.LOGIN,
VisTime = loginOutput.LastLoginTime,
Account = loginOutput.Account
}));
return loginOutput;
}
///
/// 退出
///
///
public async Task Logout()
{
var ip = httpContextAccessor.HttpContext.GetRequestIPv4();
httpContextAccessor.HttpContext.SignoutToSwagger();
//_httpContextAccessor.HttpContext.Response.Headers["access-token"] = "invalid token";
// 增加退出日志
await eventPublisher.PublishAsync(new ChannelEventSource("Create:VisLog",
new SysLogVis
{
Name = CurrentSysUserInfo.Name,
Success = true,
Message = "退出成功",
VisType = LoginType.LOGOUT,
VisTime = DateTime.Now,
Account = CurrentSysUserInfo.Account,
Ip = ip
}));
}
///
/// 获取验证码
///
///
public Task GetCaptcha()
{
// 图片大小要与前端保持一致(坐标范围)
return Task.FromResult(captchaService.CreateCaptchaImage());
}
///
/// 校验验证码
///
///
///
public Task VerifyCaptcha(GeneralCaptchaInput input)
{
return Task.FromResult(captchaService.CheckCode(input));
}
///
/// 获取临时密码
///
///
///
public List GetTempPassword(List input)
{
List ret = [];
foreach (string pwd in input)
{
//var npwd = AESEncryption.Encrypt(pwd, _authOptions.AesPassword);
var npwd = PBKDF2Encryption.Encrypt(pwd);
ret.Add(npwd);
}
return ret;
}
}