[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">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment="">
|
<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$/.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>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -250,6 +252,8 @@
|
|||||||
<workItem from="1759137056827" duration="1026000" />
|
<workItem from="1759137056827" duration="1026000" />
|
||||||
<workItem from="1759150007653" duration="169000" />
|
<workItem from="1759150007653" duration="169000" />
|
||||||
<workItem from="1759314718830" duration="55000" />
|
<workItem from="1759314718830" duration="55000" />
|
||||||
|
<workItem from="1759315721112" duration="82000" />
|
||||||
|
<workItem from="1759398581423" duration="2195000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -20,110 +20,52 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
public async Task<IActionResult> Challenge(string user)
|
public async Task<IActionResult> Challenge(string user)
|
||||||
{
|
{
|
||||||
var c = await userService.Challenge(user);
|
var c = await userService.Challenge(user);
|
||||||
if (c == null)
|
return c != null ? Ok(c): _403;
|
||||||
return _403;
|
|
||||||
|
|
||||||
return Ok(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{user}")]
|
[HttpPost("{user}")]
|
||||||
public async Task<IActionResult> Challenge(string user, [FromBody] ChallengeResponse response)
|
public async Task<IActionResult> Challenge(string user, [FromBody] ChallengeResponse response)
|
||||||
{
|
{
|
||||||
var r = await userService.Verify(user, response.Response, Ip);
|
var r = await userService.Verify(user, response.Response, Ip);
|
||||||
if (r == null)
|
if (r != null)
|
||||||
return _403;
|
{
|
||||||
|
Response.Cookies.Append("token", r);
|
||||||
|
return Ok(r);
|
||||||
|
}
|
||||||
|
|
||||||
Response.Cookies.Append("token", r);
|
return _403;
|
||||||
return Ok(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("validate")]
|
[HttpPost("validate")]
|
||||||
public IActionResult Validate(string token)
|
public IActionResult Validate(string token)
|
||||||
{
|
{
|
||||||
var u = userService.Validate(token, Ip);
|
var u = userService.Validate(token, Ip);
|
||||||
if (u == -1)
|
return u == -1 ? _401 : Ok(u);
|
||||||
{
|
|
||||||
return _401;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("destroy")]
|
[HttpPost("destroy")]
|
||||||
public IActionResult Destroy(string token)
|
public IActionResult Destroy(string token)
|
||||||
{
|
{
|
||||||
var u = userService.Validate(token, Ip);
|
var u = userService.Validate(token, Ip);
|
||||||
if (u == -1)
|
if (u != -1)
|
||||||
{
|
{
|
||||||
return _401;
|
userService.Destroy(token);
|
||||||
|
return Ok("Success");
|
||||||
}
|
}
|
||||||
|
return _401;
|
||||||
userService.Destroy(token);
|
|
||||||
return Ok("Success");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPatch("{user}")]
|
[HttpPatch("{user}")]
|
||||||
public async Task<IActionResult> Create(string user, [FromBody] UserCreating creating)
|
public async Task<IActionResult> Create(string user, [FromBody] UserCreating creating)
|
||||||
{
|
{
|
||||||
// Valid token
|
bool r = await userService.CreateUserAsync(user, creating, Ip);
|
||||||
var r = await userService.Verify(user, creating.Response, Ip);
|
return r ? Ok("Success") : _403;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{user}/open")]
|
[HttpGet("{user}/open")]
|
||||||
public async Task<IActionResult> Open(string user, [FromQuery] string token, [FromQuery] string? bindIp = null)
|
public async Task<IActionResult> Open(string user, [FromQuery] string token, [FromQuery] string? bindIp = null)
|
||||||
{
|
{
|
||||||
var caller = userService.Validate(token, Ip);
|
string? r = await userService.OpenUserAsync(user, token, bindIp, Ip);
|
||||||
if (caller != 1)
|
return r != null ? Ok(r) : _403;
|
||||||
{
|
|
||||||
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]+$");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using Abyss.Components.Services.Misc;
|
using Abyss.Components.Services.Misc;
|
||||||
using Abyss.Model.Security;
|
using Abyss.Model.Security;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
@@ -17,7 +18,6 @@ public class UserService
|
|||||||
private readonly ILogger<UserService> _logger;
|
private readonly ILogger<UserService> _logger;
|
||||||
private readonly IMemoryCache _cache;
|
private readonly IMemoryCache _cache;
|
||||||
private readonly SQLiteAsyncConnection _database;
|
private readonly SQLiteAsyncConnection _database;
|
||||||
|
|
||||||
public UserService(ILogger<UserService> logger, ConfigureService config, IMemoryCache cache)
|
public UserService(ILogger<UserService> logger, ConfigureService config, IMemoryCache cache)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -59,6 +59,62 @@ public class UserService
|
|||||||
Console.ReadKey();
|
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)
|
public async Task<string?> Challenge(string user)
|
||||||
{
|
{
|
||||||
var u = await _database.Table<User>().Where(x => x.Username == user).FirstOrDefaultAsync();
|
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");
|
_logger.LogInformation($"Created token for {uid}@{ip}, valid {lifetime.TotalMinutes} minutes");
|
||||||
return token;
|
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