235 lines
7.9 KiB
C#
235 lines
7.9 KiB
C#
using Flawless.Communication.Request;
|
|
using Flawless.Communication.Response;
|
|
using Flawless.Server.Models;
|
|
using Flawless.Server.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Flawless.Server.Controllers;
|
|
|
|
[ApiController, Authorize, Route("api/admin")]
|
|
public class AdminController(
|
|
UserManager<AppUser> userManager,
|
|
AccessControlService accessControlService,
|
|
ILogger<AdminController> logger,
|
|
AppDbContext dbContext) : ControllerBase
|
|
{
|
|
|
|
private async ValueTask<ActionResult?> TestIfValid()
|
|
{
|
|
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
|
if (user.Admin == false) return BadRequest(new FailedResponse("Only admin can do this!"));
|
|
return null;
|
|
}
|
|
|
|
[HttpPost("add_user")]
|
|
public async Task<IActionResult> AddUserAsync(RegisterRequest request)
|
|
{
|
|
var user = new AppUser
|
|
{
|
|
UserName = request.Username,
|
|
Email = request.Email,
|
|
EmailConfirmed = true,
|
|
CreatedOn = DateTime.UtcNow
|
|
};
|
|
|
|
user.RenewSecurityStamp();
|
|
var result = await userManager.CreateAsync(user, request.Password);
|
|
if (result.Succeeded)
|
|
{
|
|
await userManager.SetLockoutEnabledAsync(user, false);
|
|
logger.LogInformation("User '{0}' created (SUPERUSER REGISTER)", user.UserName);
|
|
return Ok();
|
|
}
|
|
|
|
logger.LogInformation("User '{0}' NOT created (SUPERUSER REGISTER) : {1}", user.UserName, result.Errors);
|
|
return BadRequest(new FailedResponse(result.Errors));
|
|
}
|
|
|
|
[HttpPost("superuser/{username}")]
|
|
public async Task<IActionResult> SetSuperuserAsync(string username, bool toSuper)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var user = await userManager.FindByNameAsync(username);
|
|
var optUser = (await userManager.GetUserAsync(HttpContext.User))!;
|
|
|
|
if (user == null) return BadRequest(new FailedResponse("User does not exist!"));
|
|
if (optUser == user) return BadRequest(new FailedResponse("You cannot set/unset yourself to superuser!"));
|
|
|
|
user.Admin = toSuper;
|
|
await userManager.UpdateAsync(user);
|
|
return Ok();
|
|
}
|
|
|
|
|
|
[HttpGet("superuser/{username}")]
|
|
public async Task<ActionResult<bool>> GetSuperuserAsync(string username)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var user = await userManager.FindByNameAsync(username);
|
|
if (user == null) return BadRequest(new FailedResponse("User does not exist!"));
|
|
|
|
return user.Admin;
|
|
}
|
|
|
|
[HttpGet("user/list")]
|
|
public async Task<ActionResult<IEnumerable<UserInfoResponse>>> GetUsersAsync()
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var r = await userManager.Users.Select(x => new UserInfoResponse
|
|
{
|
|
Authorized = true,
|
|
Username = x.UserName,
|
|
CreatedAt = x.CreatedOn,
|
|
Bio = x.Bio,
|
|
Gender = x.Gender,
|
|
NickName = x.NickName,
|
|
PublicEmail = x.PublicEmail,
|
|
Email = x.Email,
|
|
Phone = x.PhoneNumber,
|
|
IsAdmin = x.Admin,
|
|
IsActive = !x.LockoutEnabled
|
|
}).ToArrayAsync();
|
|
|
|
return r;
|
|
}
|
|
|
|
[HttpPost("user/delete/{username}")]
|
|
public async Task<IActionResult> DeleteUserAsync(string username)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var user = await userManager.FindByNameAsync(username);
|
|
|
|
if (user == null) return BadRequest(new FailedResponse("User does not exist!"));
|
|
var result = await userManager.DeleteAsync(user);
|
|
|
|
if (!result.Succeeded) return BadRequest(new FailedResponse(result.Errors));
|
|
return Ok();
|
|
}
|
|
|
|
[HttpPost("user/enable/{username}")]
|
|
public async Task<IActionResult> EnableUserAsync(string username)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var user = await userManager.FindByNameAsync(username);
|
|
|
|
if (user == null) return BadRequest(new FailedResponse("User does not exist!"));
|
|
var result = await userManager.SetLockoutEnabledAsync(user, false);
|
|
|
|
if (!result.Succeeded) return BadRequest(new FailedResponse(result.Errors));
|
|
return Ok();
|
|
}
|
|
|
|
[HttpPost("user/disable/{username}")]
|
|
public async Task<IActionResult> DisableUserAsync(string username)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var user = await userManager.FindByNameAsync(username);
|
|
|
|
if (user == null) return BadRequest(new FailedResponse("User does not exist!"));
|
|
var result = await userManager.SetLockoutEnabledAsync(user, true);
|
|
|
|
if (!result.Succeeded) return BadRequest(new FailedResponse(result.Errors));
|
|
return Ok();
|
|
}
|
|
|
|
[HttpPost("user/reset_password")]
|
|
public async Task<IActionResult> ResetPasswordAsync(ResetPasswordRequest r)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
if (r.Identity == null) return BadRequest(new FailedResponse("Identity (User Id) is not set!"));
|
|
var user = await userManager.FindByNameAsync(r.Identity);
|
|
|
|
if (user == null) return BadRequest(new FailedResponse("Identity (User Id) does not exist!"));
|
|
var result = await userManager.ResetPasswordAsync(user, "", r.NewPassword);
|
|
|
|
if (!result.Succeeded) return BadRequest(new FailedResponse(result.Errors));
|
|
return Ok();
|
|
}
|
|
|
|
[HttpPost("access_control/ip_whitelist")]
|
|
public async Task<IActionResult> SetIpWhitelistAsync([FromBody] string[] ips)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
await accessControlService.UpdatePolicyAsync(IpPolicyType.Whitelist, ips);
|
|
return Ok();
|
|
}
|
|
|
|
[HttpGet("access_control/ip_whitelist")]
|
|
public async Task<ActionResult<IEnumerable<string>>> GetIpWhitelistAsync()
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
return Ok(await accessControlService.GetIpListAsync(IpPolicyType.Whitelist));
|
|
}
|
|
|
|
[HttpPost("access_control/ip_blacklist")]
|
|
public async Task<IActionResult> SetIpBlacklistAsync([FromBody] string[] ips)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
await accessControlService.UpdatePolicyAsync(IpPolicyType.Blacklist, ips);
|
|
return Ok();
|
|
}
|
|
|
|
[HttpGet("access_control/ip_blacklist")]
|
|
public async Task<ActionResult<IEnumerable<string>>> GetIpBlacklistAsync()
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
return Ok(await accessControlService.GetIpListAsync(IpPolicyType.Blacklist));
|
|
}
|
|
|
|
[HttpGet("logs")]
|
|
public async Task<ActionResult<IEnumerable<LogEntryResponse>>> GetSystemLogsAsync(
|
|
[FromQuery] DateTime startTime,
|
|
[FromQuery] DateTime endTime,
|
|
[FromQuery] int level,
|
|
[FromQuery] int page,
|
|
[FromQuery] int pageSize)
|
|
{
|
|
var t = await TestIfValid();
|
|
if (t != null) return t;
|
|
|
|
var query = dbContext.SystemLogs.Where(x =>
|
|
x.Timestamp >= startTime && x.Timestamp <= endTime && (int) x.LogLevel >= level
|
|
).AsQueryable();
|
|
|
|
// 分页处理
|
|
// var totalCount = await query.CountAsync();
|
|
var results = await query
|
|
.OrderByDescending(l => l.Timestamp)
|
|
.Skip((page - 1) * pageSize)
|
|
.Take(pageSize)
|
|
.Select(l => new LogEntryResponse(
|
|
l.Timestamp,
|
|
l.LogLevel.ToString(),
|
|
l.Message,
|
|
l.Exception))
|
|
.ToListAsync();
|
|
|
|
return Ok(results);
|
|
}
|
|
}
|