[optimize] Merge user logic to service

This commit is contained in:
acite
2025-10-02 18:47:15 +08:00
parent db58091814
commit dcdd9d840e
3 changed files with 85 additions and 75 deletions

View File

@@ -11,6 +11,8 @@
<component name="ChangeListManager">
<list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/Security/UserService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Security/UserService.cs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -250,6 +252,8 @@
<workItem from="1759137056827" duration="1026000" />
<workItem from="1759150007653" duration="169000" />
<workItem from="1759314718830" duration="55000" />
<workItem from="1759315721112" duration="82000" />
<workItem from="1759398581423" duration="2195000" />
</task>
<servers />
</component>

View File

@@ -20,110 +20,52 @@ public class UserController(UserService userService, ILogger<UserController> log
public async Task<IActionResult> Challenge(string user)
{
var c = await userService.Challenge(user);
if (c == null)
return _403;
return Ok(c);
return c != null ? Ok(c): _403;
}
[HttpPost("{user}")]
public async Task<IActionResult> Challenge(string user, [FromBody] ChallengeResponse response)
{
var r = await userService.Verify(user, response.Response, Ip);
if (r == null)
return _403;
if (r != null)
{
Response.Cookies.Append("token", r);
return Ok(r);
}
Response.Cookies.Append("token", r);
return Ok(r);
return _403;
}
[HttpPost("validate")]
public IActionResult Validate(string token)
{
var u = userService.Validate(token, Ip);
if (u == -1)
{
return _401;
}
return Ok(u);
return u == -1 ? _401 : Ok(u);
}
[HttpPost("destroy")]
public IActionResult Destroy(string token)
{
var u = userService.Validate(token, Ip);
if (u == -1)
if (u != -1)
{
return _401;
userService.Destroy(token);
return Ok("Success");
}
userService.Destroy(token);
return Ok("Success");
return _401;
}
[HttpPatch("{user}")]
public async Task<IActionResult> Create(string user, [FromBody] UserCreating creating)
{
// Valid token
var r = await userService.Verify(user, creating.Response, Ip);
if (r == null)
return _403;
// User exists ?
var cu = await userService.QueryUser(creating.Name);
if (cu != null)
return _403;
// Valid username string
if (!IsAlphanumeric(creating.Name))
return _403;
// Valid parent && Privilege
var ou = await userService.QueryUser(userService.Validate(r, Ip));
if (creating.Privilege > ou?.Privilege || ou == null)
return _403;
await userService.CreateUser(new User
{
Username = creating.Name,
ParentId = ou.Uuid,
Privilege = creating.Privilege,
PublicKey = creating.PublicKey,
});
userService.Destroy(r);
return Ok("Success");
bool r = await userService.CreateUserAsync(user, creating, Ip);
return r ? Ok("Success") : _403;
}
[HttpGet("{user}/open")]
public async Task<IActionResult> Open(string user, [FromQuery] string token, [FromQuery] string? bindIp = null)
{
var caller = userService.Validate(token, Ip);
if (caller != 1)
{
return _403;
}
var target = await userService.QueryUser(user);
if (target == null)
{
return _403;
}
var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? Ip : bindIp;
var t = userService.CreateToken(target.Uuid, ipToBind, TimeSpan.FromHours(1));
logger.LogInformation("Root created 1h token for {User}, bound to {BindIp}, request from {ReqIp}", user,
ipToBind, Ip);
return Ok(new { token = t, user, boundIp = ipToBind });
}
public static bool IsAlphanumeric(string input)
{
if (string.IsNullOrEmpty(input))
return false;
return Regex.IsMatch(input, @"^[a-zA-Z0-9]+$");
string? r = await userService.OpenUserAsync(user, token, bindIp, Ip);
return r != null ? Ok(r) : _403;
}
}

View File

@@ -3,6 +3,7 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Abyss.Components.Services.Misc;
using Abyss.Model.Security;
using Microsoft.Extensions.Caching.Memory;
@@ -17,7 +18,6 @@ public class UserService
private readonly ILogger<UserService> _logger;
private readonly IMemoryCache _cache;
private readonly SQLiteAsyncConnection _database;
public UserService(ILogger<UserService> logger, ConfigureService config, IMemoryCache cache)
{
_logger = logger;
@@ -59,6 +59,62 @@ public class UserService
Console.ReadKey();
}
}
public async Task<string?> OpenUserAsync(string user, string token, string? bindIp, string ip)
{
var caller = Validate(token, ip);
if (caller != 1)
{
return null;
}
var target = await QueryUser(user);
if (target == null)
{
return null;
}
var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? ip : bindIp;
var t = CreateToken(target.Uuid, ipToBind, TimeSpan.FromHours(1));
_logger.LogInformation("Root created 1h token for {User}, bound to {BindIp}, request from {ReqIp}", user,
ipToBind, ip);
return t;
}
public async Task<bool> CreateUserAsync(string user, UserCreating creating, string ip)
{
// Valid token
var r = await Verify(user, creating.Response, ip);
if (r == null)
return false;
// User exists ?
var cu = await QueryUser(creating.Name);
if (cu != null)
return false;
// Valid username string
if (!IsAlphanumeric(creating.Name))
return false;
// Valid parent && Privilege
var ou = await QueryUser(Validate(r, ip));
if (creating.Privilege > ou?.Privilege || ou == null)
return false;
await CreateUser(new User
{
Username = creating.Name,
ParentId = ou.Uuid,
Privilege = creating.Privilege,
PublicKey = creating.PublicKey,
});
Destroy(r);
return true;
}
public async Task<string?> Challenge(string user)
{
var u = await _database.Table<User>().Where(x => x.Username == user).FirstOrDefaultAsync();
@@ -226,4 +282,12 @@ public class UserService
_logger.LogInformation($"Created token for {uid}@{ip}, valid {lifetime.TotalMinutes} minutes");
return token;
}
public static bool IsAlphanumeric(string input)
{
if (string.IsNullOrEmpty(input))
return false;
return Regex.IsMatch(input, @"^[a-zA-Z0-9]+$");
}
}