FalconSSO/FAuth/Controllers/api/UserController.cs

202 lines
8.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Linq;
using Falcon.Extend;
using FAuth.DataBase.Tables;
using FAuth.Extensions.Account;
using FAuth.Extensions.Decryptor;
using FAuth.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace FAuth.Controllers.api
{
/// <summary>
/// 用户相关api控制器接口
/// </summary>
public class UserController:ApiControllerBase<UserController>
{
public IUserTicketDryptor UserTicketDryptor { get; set; }
public AccountHelper Account { get; set; }
public UserController(ILogger<UserController> logger,IServiceProvider service)
: base(logger,service) {
this.Account = service.GetRequiredService<AccountHelper>();
this.UserTicketDryptor = service.GetRequiredService<IUserTicketDryptor>();
}
/// <summary>
/// 用户登录方法
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
/// <returns>登录结果</returns>
[HttpPost]
[ProducesResponseType(typeof(CheckUserResult),200)]
public CheckUserResult Login(string userName,string password) {
if(userName.IsNullOrEmpty()) {
throw new ArgumentNullException(nameof(userName));
}
var qu = this.Db.Users.Where(m => m.UserName == userName && m.Password == password);
if(!qu.Any()) {
throw new Exception("提供的用户名或密码不正确");
}
var fir = qu.First();
var now = DateTimeOffset.Now;
fir.LastLoginDatetime = now;
fir.Status |= FUserStatusEnum.Login;
this.Db.SaveChangesAsync().Wait();
this.Logger.LogInformation($"用户{userName}登录成功!");
return new CheckUserResult {
Ticket = this.UserTicketDryptor.Encrypt(new UserTicketModel {
Id = fir.Id,
UserName = fir.UserName,
LoginDatetime = now,
}),
};
}
/// <summary>
/// 登出用户
/// </summary>
/// <param name="ticket">用户票据</param>
/// <returns>是否成功</returns>
[HttpPost]
public bool Logout(string ticket) {
if(ticket.IsNullOrEmpty()) {
throw new ArgumentNullException(nameof(ticket));
}
var userTicketModel = this.UserTicketDryptor.Decrypt(ticket);
var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id);
if(!qu.Any()) {
throw new Exception("提交的票据信息错误");
}
var fir = qu.First();
fir.Status &= ~FUserStatusEnum.Login;
fir.LastLogoutDatetime = DateTimeOffset.Now;
this.Db.SaveChangesAsync().Wait();
this.Logger.LogInformation($"用户{userTicketModel.Id}:{userTicketModel.UserName}登出成功!");
return true;
}
/// <summary>
/// 根据用户凭据获取用户信息
/// </summary>
/// <param name="ticket">登录票据</param>
/// <returns>用户信息</returns>
[HttpGet]
[ProducesResponseType(typeof(UserInfo),200)]
public UserInfo GetUserByTicket([BindRequired]string ticket) {
if(ticket.IsNullOrEmpty()) {
throw new ArgumentNullException(nameof(ticket));
}
var userTicketModel = this.UserTicketDryptor.Decrypt(ticket);
var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id);
if(!qu.Any()) {
throw new Exception("提交的票据信息错误");
}
var fir = qu.First();
if(fir.LastLogoutDatetime.HasValue && userTicketModel.LoginDatetime < fir.LastLogoutDatetime.Value) {
throw new Exception("用户已登出");
}
return new UserInfo {
Id = fir.Id,
LastLoginDatetime = fir.LastLoginDatetime,
UserName = fir.UserName,
};
}
/// <summary>
/// 根据提供的登陆票据修改用户密码
/// </summary>
/// <param name="ticket">票据</param>
/// <param name="nPassword">新密码</param>
/// <returns>是否成功</returns>
[HttpPost]
public bool ChangePassword(string ticket,string nPassword) {
if(ticket.IsNullOrEmpty()) {
throw new ArgumentNullException(nameof(ticket));
}
var userTicketModel = this.UserTicketDryptor.Decrypt(ticket);
var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id);
if(!qu.Any()) {
throw new Exception("没找到票据对应用户");
}
foreach(var item in qu) {
item.Password = nPassword;
}
this.Db.SaveChangesAsync().Wait();
this.Logger.LogInformation($"用户{userTicketModel.Id}:{userTicketModel.UserName}修改密码成功!");
return true;
}
/// <summary>
/// 通过提供管理员票据和新用户信息创建用户
/// </summary>
/// <param name="adminTicket">管理员票据</param>
/// <param name="userName">登录用户名</param>
/// <param name="name">用户名称</param>
/// <param name="password">用户密码</param>
/// <returns>是否成功</returns>
[HttpPost]
public bool AddNewUser(string adminTicket,string userName,string name,string password) {
if(string.IsNullOrEmpty(adminTicket))
throw new ArgumentException("必须提供管理票据",nameof(adminTicket));
if(string.IsNullOrEmpty(userName))
throw new ArgumentException("新用户登录名不能为空",nameof(userName));
if(string.IsNullOrEmpty(name))
throw new ArgumentException("用户姓名不能为空",nameof(name));
if(string.IsNullOrEmpty(password))
throw new ArgumentException("密码不能为空",nameof(password));
if(this.Account.IsNotSystemAdmin(adminTicket)) {
throw new Exception($"用户必须在应用FAuth中具有Admin角色");
}
var qu = this.Db.Users.Where(m => m.UserName == userName);
if(qu.Any()) {
throw new Exception("用户登录名已经存在,不能重复添加");
}
var nUser = new FUser {
Name = name,
UserName = userName,
Password = password,
};
this.Db.Entry(nUser).State = EntityState.Added;
this.Db.SaveChangesAsync().Wait();
this.Logger.LogInformation($"用户{nUser.Id}:{nUser.UserName}:{nUser.Name}添加成功!");
return true;
}
/// <summary>
/// 重置用户密码
/// </summary>
/// <param name="adminTicket">管理员票据</param>
/// <param name="userName">要重置密码的用户名</param>
/// <param name="newPassword">新密码</param>
/// <returns>是否成功。成功True 否则返回False</returns>
[HttpPost]
public bool ResetUserPassword(string adminTicket,string userName,string newPassword) {
if(string.IsNullOrEmpty(adminTicket))
throw new ArgumentException("必须提供管理票据",nameof(adminTicket));
if(string.IsNullOrEmpty(userName))
throw new ArgumentException("新用户登录名不能为空",nameof(userName));
if(string.IsNullOrEmpty(newPassword))
throw new ArgumentException("密码不能为空",nameof(newPassword));
if(this.Account.IsNotSystemAdmin(adminTicket)) {
throw new Exception($"用户必须在应用FAuth中具有Admin角色");
}
var qu = this.Db.Users.Where(m => m.UserName == userName);
if(!qu.Any()) {
throw new Exception("用户登录名不存在");
}
foreach(var item in qu) {
item.Password = newPassword;
}
this.Db.SaveChangesAsync().Wait();
return true;
}
}
}