[optimize] Merge user logic to service
This commit is contained in:
4
.idea/.idea.Abyss/.idea/workspace.xml
generated
4
.idea/.idea.Abyss/.idea/workspace.xml
generated
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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]+$");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user