592 lines
No EOL
20 KiB
C#
592 lines
No EOL
20 KiB
C#
using iFileProxy.Attributes;
|
||
using iFileProxy.Helpers;
|
||
using iFileProxy.Models;
|
||
using iFileProxy.Services;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
|
||
namespace iFileProxy.Controllers
|
||
{
|
||
[Route("[controller]")]
|
||
[ApiController]
|
||
public class UserController : ControllerBase
|
||
{
|
||
private readonly AuthService _authService;
|
||
private readonly ILogger<UserController> _logger;
|
||
|
||
public UserController(AuthService authService, ILogger<UserController> logger)
|
||
{
|
||
_authService = authService;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用户注册
|
||
/// </summary>
|
||
[HttpPost("register")]
|
||
public async Task<ActionResult<CommonRsp>> Register([FromBody] RegisterRequest request)
|
||
{
|
||
try
|
||
{
|
||
var ip = MasterHelper.GetClientIPAddr(HttpContext);
|
||
var (success, message) = await _authService.RegisterAsync(request,ip);
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = message
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "注册失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "注册失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用户登录
|
||
/// </summary>
|
||
[HttpPost("login")]
|
||
public async Task<ActionResult<CommonRsp>> Login([FromBody] LoginRequest request)
|
||
{
|
||
try
|
||
{
|
||
var ip = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
|
||
var (success, token, message) = await _authService.LoginAsync(request.Username, request.Password, ip);
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = message,
|
||
Data = success ? new { token } : null
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "登录失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "登录失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前用户信息
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpGet("info")]
|
||
public async Task<ActionResult<CommonRsp>> GetUserInfo()
|
||
{
|
||
try
|
||
{
|
||
var userId = HttpContext.Items["User"]?.ToString();
|
||
if (string.IsNullOrEmpty(userId))
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "未登录"
|
||
});
|
||
}
|
||
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
var user = await dbGateService.GetUserByIdAsync(userId);
|
||
if (user == null)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "用户不存在"
|
||
});
|
||
}
|
||
|
||
// 不返回敏感信息
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 0,
|
||
Message = "success",
|
||
Data = new
|
||
{
|
||
user.UserId,
|
||
user.Username,
|
||
user.Mask,
|
||
user.State,
|
||
user.CreateTime,
|
||
user.LastLoginTime,
|
||
user.LastLoginIP,
|
||
user.Nickname
|
||
}
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取用户信息失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "获取用户信息失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改用户权限
|
||
/// </summary>
|
||
[Authorize(UserMask.SuperAdmin)]
|
||
[HttpPost("updateMask/{userId}")]
|
||
public async Task<ActionResult<CommonRsp>> UpdateUserMask(string userId, [FromBody] UpdateUserMaskRequest request)
|
||
{
|
||
try
|
||
{
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
|
||
// 获取目标用户
|
||
var targetUser = await dbGateService.GetUserByIdAsync(userId);
|
||
if (targetUser == null)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "用户不存在"
|
||
});
|
||
}
|
||
|
||
// 不允许修改超级管理员的权限
|
||
if (targetUser.Mask == UserMask.SuperAdmin)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "不能修改超级管理员的权限"
|
||
});
|
||
}
|
||
|
||
// 更新权限
|
||
targetUser.Mask = request.NewMask;
|
||
var success = await dbGateService.UpdateUserAsync(targetUser);
|
||
|
||
// 记录操作事件
|
||
var operatorId = HttpContext.Items["User"]?.ToString();
|
||
if (success && !string.IsNullOrEmpty(operatorId))
|
||
{
|
||
var userEvent = new UserEvent
|
||
{
|
||
UserId = targetUser.UserId,
|
||
EventType = UserEventType.UpdateMask,
|
||
EventIP = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||
EventDetail = $"权限被修改为 {request.NewMask},操作者ID: {operatorId}"
|
||
};
|
||
await dbGateService.CreateUserEventAsync(userEvent);
|
||
}
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = success ? "权限修改成功" : "权限修改失败"
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "修改用户权限失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "修改用户权限失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户列表(分页)
|
||
/// </summary>
|
||
[Authorize(UserMask.SuperAdmin)]
|
||
[HttpGet("list")]
|
||
public async Task<ActionResult<CommonRsp>> GetUserList([FromQuery] int page = 1, [FromQuery] int pageSize = 10, [FromQuery] UserMask? mask = null)
|
||
{
|
||
try
|
||
{
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
var result = await dbGateService.GetPagedUserListAsync(page, pageSize, mask);
|
||
|
||
// 移除敏感信息
|
||
foreach (var user in result.Data)
|
||
{
|
||
user.PasswordHash = "***************";
|
||
}
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 0,
|
||
Message = "success",
|
||
Data = result
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取用户列表失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "获取用户列表失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改个人昵称
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpPost("updateNickname")]
|
||
public async Task<ActionResult<CommonRsp>> UpdateNickname([FromBody] UpdateNicknameRequest request)
|
||
{
|
||
try
|
||
{
|
||
var userId = HttpContext.Items["User"]?.ToString();
|
||
if (string.IsNullOrEmpty(userId))
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "未登录"
|
||
});
|
||
}
|
||
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
var user = await dbGateService.GetUserByIdAsync(userId);
|
||
if (user == null)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "用户不存在"
|
||
});
|
||
}
|
||
|
||
user.Nickname = request.NewNickname;
|
||
var success = await dbGateService.UpdateUserAsync(user);
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = success ? "昵称修改成功" : "昵称修改失败"
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "修改昵称失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "修改昵称失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改密码
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpPost("updatePassword")]
|
||
public async Task<ActionResult<CommonRsp>> UpdatePassword([FromBody] UpdatePasswordRequest request)
|
||
{
|
||
try
|
||
{
|
||
var userId = HttpContext.Items["User"]?.ToString();
|
||
if (string.IsNullOrEmpty(userId))
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "未登录"
|
||
});
|
||
}
|
||
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
var user = await dbGateService.GetUserByIdAsync(userId);
|
||
if (user == null)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "用户不存在"
|
||
});
|
||
}
|
||
|
||
// 验证旧密码
|
||
if (!BCrypt.Net.BCrypt.Verify(request.OldPassword, user.PasswordHash))
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "旧密码错误"
|
||
});
|
||
}
|
||
|
||
// 更新密码
|
||
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.NewPassword);
|
||
var success = await dbGateService.UpdateUserAsync(user);
|
||
|
||
// 记录密码修改事件
|
||
if (success)
|
||
{
|
||
var userEvent = new UserEvent
|
||
{
|
||
UserId = user.UserId,
|
||
EventType = UserEventType.UpdatePassword,
|
||
EventIP = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||
EventDetail = "密码已修改"
|
||
};
|
||
await dbGateService.CreateUserEventAsync(userEvent);
|
||
}
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = success ? "密码修改成功" : "密码修改失败"
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "修改密码失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "修改密码失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 超级管理员修改用户密码
|
||
/// </summary>
|
||
[Authorize(UserMask.SuperAdmin)]
|
||
[HttpPost("resetPassword/{userId}")]
|
||
public async Task<ActionResult<CommonRsp>> ResetUserPassword(string userId, [FromBody] ResetPasswordRequest request)
|
||
{
|
||
try
|
||
{
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
|
||
// 获取目标用户
|
||
var targetUser = await dbGateService.GetUserByIdAsync(userId);
|
||
if (targetUser == null)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "用户不存在"
|
||
});
|
||
}
|
||
|
||
// 不允许修改超级管理员的密码
|
||
if (targetUser.Mask == UserMask.SuperAdmin && targetUser.UserId != HttpContext.Items["User"]?.ToString())
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "不能修改其他超级管理员的密码"
|
||
});
|
||
}
|
||
|
||
// 更新密码
|
||
targetUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.NewPassword);
|
||
var success = await dbGateService.UpdateUserAsync(targetUser);
|
||
|
||
// 记录密码重置事件
|
||
if (success)
|
||
{
|
||
var operatorId = HttpContext.Items["User"]?.ToString();
|
||
var userEvent = new UserEvent
|
||
{
|
||
UserId = targetUser.UserId,
|
||
EventType = UserEventType.UpdatePassword,
|
||
EventIP = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||
EventDetail = $"密码被管理员重置,操作者ID: {operatorId}"
|
||
};
|
||
await dbGateService.CreateUserEventAsync(userEvent);
|
||
}
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = success ? "密码重置成功" : "密码重置失败"
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "重置密码失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "重置密码失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户事件列表
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpGet("events")]
|
||
public async Task<ActionResult<CommonRsp>> GetUserEvents(
|
||
[FromQuery] int page = 1,
|
||
[FromQuery] int pageSize = 10,
|
||
[FromQuery] string? keyword = null,
|
||
[FromQuery] string? userId = null)
|
||
{
|
||
try
|
||
{
|
||
var currentUserId = HttpContext.Items["User"]?.ToString();
|
||
if (string.IsNullOrEmpty(currentUserId))
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "未登录"
|
||
});
|
||
}
|
||
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
var currentUser = await dbGateService.GetUserByIdAsync(currentUserId);
|
||
|
||
// 如果不是超级管理员,只能查看自己的事件
|
||
if (currentUser?.Mask != UserMask.SuperAdmin)
|
||
{
|
||
userId = currentUserId;
|
||
}
|
||
// 如果是管理员且未指定用户ID,则查看所有事件
|
||
else if (string.IsNullOrEmpty(userId))
|
||
{
|
||
userId = null; // 查询所有用户的事件
|
||
}
|
||
|
||
var result = await dbGateService.GetPagedUserEventsAsync(page, pageSize, userId, keyword);
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 0,
|
||
Message = "success",
|
||
Data = result
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取用户事件失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "获取用户事件失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 管理员修改用户昵称
|
||
/// </summary>
|
||
[Authorize(UserMask.Admin, UserMask.SuperAdmin)]
|
||
[HttpPost("updateNickname/{userId}")]
|
||
public async Task<ActionResult<CommonRsp>> UpdateUserNickname(string userId, [FromBody] UpdateNicknameRequest request)
|
||
{
|
||
try
|
||
{
|
||
var dbGateService = HttpContext.RequestServices.GetRequiredService<DatabaseGateService>();
|
||
|
||
// 获取目标用户
|
||
var targetUser = await dbGateService.GetUserByIdAsync(userId);
|
||
if (targetUser == null)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "用户不存在"
|
||
});
|
||
}
|
||
|
||
// 获取当前操作者信息
|
||
var operatorId = HttpContext.Items["User"]?.ToString();
|
||
var operator_ = await dbGateService.GetUserByIdAsync(operatorId);
|
||
|
||
// 如果目标用户是超级管理员,只有超级管理员自己能修改自己的昵称
|
||
if (targetUser.Mask == UserMask.SuperAdmin &&
|
||
(operator_?.Mask != UserMask.SuperAdmin || targetUser.UserId != operatorId))
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "不能修改超级管理员的昵称"
|
||
});
|
||
}
|
||
|
||
// 如果目标用户是管理员,只有超级管理员能修改
|
||
if (targetUser.Mask == UserMask.Admin && operator_?.Mask != UserMask.SuperAdmin)
|
||
{
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "只有超级管理员能修改管理员的昵称"
|
||
});
|
||
}
|
||
|
||
// 更新昵称
|
||
targetUser.Nickname = request.NewNickname;
|
||
var success = await dbGateService.UpdateUserAsync(targetUser);
|
||
|
||
// 记录操作事件
|
||
if (success)
|
||
{
|
||
var userEvent = new UserEvent
|
||
{
|
||
UserId = targetUser.UserId,
|
||
EventType = UserEventType.UpdateNickname, // 需要添加这个事件类型
|
||
EventIP = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||
EventDetail = $"昵称被修改为 {request.NewNickname},操作者ID: {operatorId}"
|
||
};
|
||
await dbGateService.CreateUserEventAsync(userEvent);
|
||
}
|
||
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = success ? 0 : 1,
|
||
Message = success ? "昵称修改成功" : "昵称修改失败"
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "修改用户昵称失败");
|
||
return Ok(new CommonRsp
|
||
{
|
||
Retcode = 1,
|
||
Message = "修改用户昵称失败"
|
||
});
|
||
}
|
||
}
|
||
|
||
public class UpdateUserMaskRequest
|
||
{
|
||
public UserMask NewMask { get; set; }
|
||
}
|
||
|
||
public class UpdateNicknameRequest
|
||
{
|
||
public string NewNickname { get; set; } = string.Empty;
|
||
}
|
||
|
||
public class UpdatePasswordRequest
|
||
{
|
||
public string OldPassword { get; set; } = string.Empty;
|
||
public string NewPassword { get; set; } = string.Empty;
|
||
}
|
||
|
||
public class ResetPasswordRequest
|
||
{
|
||
public string NewPassword { get; set; } = string.Empty;
|
||
}
|
||
}
|
||
|
||
} |