using System; using System.Collections.Generic; using System.Linq; using Falcon.Extend; using FAuth.DataBase.Tables; using FAuth.Extensions; 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 { /// /// 用户相关api控制器接口 /// public class UserController:ApiControllerBase { public IUserTicketDryptor UserTicketDryptor { get; set; } public AccountHelper Account { get; set; } public UserController(ILogger logger,IServiceProvider service) : base(logger,service) { this.Account = service.GetRequiredService(); this.UserTicketDryptor = service.GetRequiredService(); } /// /// 用户登录方法 /// /// 用户名 /// 密码 /// 登录结果 [HttpPost] [ProducesResponseType(typeof(CheckUserResult),200)] public CheckUserResult Login(string userName,string password) { if(userName.IsNullOrEmpty()) { throw new ApiArgumentNullException(nameof(userName)); } var qu = this.Db.Users.Where(m => m.UserName == userName && m.Password == password); if(!qu.Any()) { throw new ApiException("提供的用户名或密码不正确"); } 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, }), }; } /// /// 登出用户 /// /// 用户票据 /// 是否成功 [HttpPost] public bool Logout(string ticket) { if(ticket.IsNullOrEmpty()) { throw new ApiArgumentNullException(nameof(ticket)); } var userTicketModel = this.UserTicketDryptor.Decrypt(ticket); var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id); if(!qu.Any()) { throw new ApiException("提交的票据信息错误"); } 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; } /// /// 根据用户凭据获取用户信息 /// /// 登录票据 /// 用户信息 [HttpGet] [ProducesResponseType(typeof(UserInfo),200)] public UserInfo GetUserByTicket(string ticket) { if(ticket.IsNullOrEmpty()) { throw new ApiArgumentNullException(nameof(ticket)); } var userTicketModel = this.UserTicketDryptor.Decrypt(ticket); var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id); if(!qu.Any()) { throw new ApiException("提交的票据信息错误"); } var fir = qu.First(); if(fir.LastLogoutDatetime.HasValue && userTicketModel.LoginDatetime < fir.LastLogoutDatetime.Value) { throw new ApiException("用户已登出"); } return new UserInfo { Id = fir.Id, LastLoginDatetime = fir.LastLoginDatetime, UserName = fir.UserName, Name = fir.Name, }; } /// /// 获取用户信息列表 /// /// 用户信息列表 [HttpGet] [ProducesResponseType(typeof(IEnumerable),200)] public IEnumerable GetUsers() { var key = "FAuth:Users"; var obj = this.Cache?.GetObj>(key); if(obj == null) { obj = this.Db.Users .Select(m => new UserInfo { Id = m.Id, UserName = m.UserName, }).ToList(); this.Cache?.SetCache(key,obj,new TimeSpan(0,5,0)); } return obj; } /// /// 根据提供的登陆票据修改用户密码 /// /// 票据 /// 新密码 /// 是否成功 [HttpPost] public bool ChangePassword(string ticket,string nPassword) { if(ticket.IsNullOrEmpty()) { throw new ApiArgumentNullException(nameof(ticket)); } var userTicketModel = this.UserTicketDryptor.Decrypt(ticket); var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id); if(!qu.Any()) { throw new ApiException("没找到票据对应用户"); } foreach(var item in qu) { item.Password = nPassword; } this.Db.SaveChangesAsync().Wait(); this.Logger.LogInformation($"用户{userTicketModel.Id}:{userTicketModel.UserName}修改密码成功!"); return true; } /// /// 通过提供管理员票据和新用户信息创建用户 /// /// 管理员票据 /// 登录用户名 /// 用户名称 /// 用户密码 /// 是否成功 [HttpPost] public bool AddNewUser(string adminTicket,string userName,string name,string password) { if(adminTicket is null) throw new ApiArgumentNullException(nameof(adminTicket)); if(userName is null) throw new ApiArgumentNullException(nameof(userName)); if(password is null) throw new ApiArgumentNullException(nameof(password)); if(this.Account.IsNotSystemAdmin(adminTicket)) { throw new ApiException($"用户必须在应用FAuth中具有Admin角色!"); } var qu = this.Db.Users.Where(m => m.UserName == userName); if(qu.Any()) { throw new ApiException("用户登录名已经存在,不能重复添加"); } 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; } /// /// 重置用户密码 /// /// 管理员票据 /// 要重置密码的用户名 /// 新密码 /// 是否成功。成功True 否则返回False [HttpPost] public bool ResetUserPassword(string adminTicket,string userName,string newPassword) { if(adminTicket is null) throw new ApiArgumentNullException(nameof(adminTicket)); if(userName is null) throw new ApiArgumentNullException(nameof(userName)); if(newPassword is null) throw new ApiArgumentNullException(nameof(newPassword)); if(this.Account.IsNotSystemAdmin(adminTicket)) { throw new ApiException($"用户必须在应用FAuth中具有Admin角色!"); } var qu = this.Db.Users.Where(m => m.UserName == userName); if(!qu.Any()) { throw new ApiException("用户登录名不存在"); } foreach(var item in qu) { item.Password = newPassword; } this.Db.SaveChangesAsync().Wait(); return true; } } }