mirror of
https://github.com/hmaxnl/SharpRSS.git
synced 2025-01-18 12:54:20 +01:00
Working on auth implentation.
This commit is contained in:
parent
952e0d7e3e
commit
8511401bff
15
SharpRSS.API.Contracts/ApiError.cs
Normal file
15
SharpRSS.API.Contracts/ApiError.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SharpRSS.API.Contracts
|
||||||
|
{
|
||||||
|
public class ApiError
|
||||||
|
{
|
||||||
|
public ApiError()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public bool Logged { get; set; }
|
||||||
|
public string Message { get; set; } = string.Empty;
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
}
|
||||||
|
}
|
16
SharpRSS.API.Contracts/DTO/ApiListResult.cs
Normal file
16
SharpRSS.API.Contracts/DTO/ApiListResult.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
namespace SharpRSS.API.Contracts.DTO
|
||||||
|
{
|
||||||
|
public class ApiListResult<TResultValue>
|
||||||
|
{
|
||||||
|
public ApiListResult(int hits, int total, TResultValue? data)
|
||||||
|
{
|
||||||
|
Hits = hits;
|
||||||
|
Total = total;
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Hits { get; }
|
||||||
|
public int Total { get; }
|
||||||
|
public TResultValue? Data { get; }
|
||||||
|
}
|
||||||
|
}
|
8
SharpRSS.API.Contracts/Models/User/AuthenticateUser.cs
Normal file
8
SharpRSS.API.Contracts/Models/User/AuthenticateUser.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace SharpRSS.API.Contracts.Models.User
|
||||||
|
{
|
||||||
|
public class AuthenticateUser
|
||||||
|
{
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
|
public string Password { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
34
SharpRSS.API/Auth/SessionAuthorizeAttribute.cs
Normal file
34
SharpRSS.API/Auth/SessionAuthorizeAttribute.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using ToolQit;
|
||||||
|
using ToolQit.Logging;
|
||||||
|
|
||||||
|
namespace SharpRSS.API.Auth
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
|
public class SessionAuthorizeAttribute : Attribute, IAuthorizationFilter
|
||||||
|
{
|
||||||
|
public SessionAuthorizeAttribute(string permission = "")
|
||||||
|
{
|
||||||
|
_log = LogManager.CreateLogger(typeof(SessionAuthorizeAttribute));
|
||||||
|
_perm = permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ILog _log;
|
||||||
|
private readonly string _perm;
|
||||||
|
|
||||||
|
public void OnAuthorization(AuthorizationFilterContext context)
|
||||||
|
{
|
||||||
|
if (context.ActionDescriptor.EndpointMetadata.Any(obj => obj.GetType() == typeof(AllowAnonymousAttribute)))
|
||||||
|
{
|
||||||
|
context.Result = new OkResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//TODO: Check session ID!
|
||||||
|
context.Result = new UnauthorizedResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SharpRSS.API.Auth;
|
||||||
using SharpRSS.API.Contracts;
|
using SharpRSS.API.Contracts;
|
||||||
using SharpRSS.API.Contracts.DTO;
|
using SharpRSS.API.Contracts.DTO;
|
||||||
|
using SharpRSS.API.Contracts.Models.User;
|
||||||
using SharpRSS.API.Data;
|
using SharpRSS.API.Data;
|
||||||
using SharpRSS.API.Models;
|
using SharpRSS.API.Models;
|
||||||
using SharpRSS.API.Models.Auth;
|
using SharpRSS.API.Models.Auth;
|
||||||
|
@ -9,6 +14,7 @@ using SharpRSS.API.Models.Auth;
|
||||||
namespace SharpRSS.API.Controllers
|
namespace SharpRSS.API.Controllers
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
[SessionAuthorize]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class AuthController : ControllerBase
|
public class AuthController : ControllerBase
|
||||||
{
|
{
|
||||||
|
@ -19,13 +25,28 @@ namespace SharpRSS.API.Controllers
|
||||||
|
|
||||||
private readonly AuthService _authService;
|
private readonly AuthService _authService;
|
||||||
|
|
||||||
[HttpPost("create")]
|
[HttpPost("[action]")]
|
||||||
public async Task<ActionResult<UserDto>> CreateUser(UserRequest user)
|
[AllowAnonymous]
|
||||||
|
public async Task<ActionResult<string>> Authenticate(AuthenticateUser authenticateUser)
|
||||||
{
|
{
|
||||||
Result<User> result = await _authService.CreateUser(user);
|
return Ok("Ok!");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("user")]
|
||||||
|
public async Task<ActionResult<UserDto>> CreateUser(AuthenticateUser authenticateUser)
|
||||||
|
{
|
||||||
|
Result<User> result = await _authService.CreateUser(authenticateUser);
|
||||||
if (result.Success)
|
if (result.Success)
|
||||||
return Ok(Models.Auth.User.ToDto(result.Value ?? new User()));
|
return Ok(Models.Auth.User.ToDto(result.Value ?? new User()));
|
||||||
return BadRequest(new ApiResult(result.Message, ApiResults.Error));
|
return BadRequest(new ApiResult(result.Message, ApiResults.Error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("user")]
|
||||||
|
public async Task<ActionResult<ApiListResult<IEnumerable<UserDto>>>> GetUsers(int take, int skip)
|
||||||
|
{
|
||||||
|
var usersAuth = await _authService.GetUsers(take, skip);
|
||||||
|
List<UserDto> users = usersAuth.Value?.Select(Models.Auth.User.ToDto).ToList() ?? new List<UserDto>();
|
||||||
|
return Ok(new ApiListResult<IEnumerable<UserDto>>(users.Count, await _authService.UserCount(), users));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -9,7 +8,7 @@ namespace SharpRSS.API.Cryptography
|
||||||
{
|
{
|
||||||
private const int KeySize = 128;
|
private const int KeySize = 128;
|
||||||
private const int Iterations = 420069;
|
private const int Iterations = 420069;
|
||||||
static readonly HashAlgorithmName Algorithm = HashAlgorithmName.SHA512;
|
private static readonly HashAlgorithmName Algorithm = HashAlgorithmName.SHA512;
|
||||||
|
|
||||||
public static byte[] HashPassword(string password, out byte[] salt)
|
public static byte[] HashPassword(string password, out byte[] salt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using SharpRSS.API.Contracts.Models.User;
|
||||||
using SharpRSS.API.Cryptography;
|
using SharpRSS.API.Cryptography;
|
||||||
using SharpRSS.API.Models;
|
using SharpRSS.API.Models;
|
||||||
using SharpRSS.API.Models.Auth;
|
using SharpRSS.API.Models.Auth;
|
||||||
|
@ -23,19 +24,22 @@ namespace SharpRSS.API.Data
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly ILog _log;
|
private readonly ILog _log;
|
||||||
|
|
||||||
public async Task<Result<User>> CreateUser(UserRequest userRequest)
|
public async Task<Result<User>> CreateUser(AuthenticateUser authenticateUserRequest)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result;
|
||||||
await using DbAccess access = new DbAccess(_configuration);
|
if (authenticateUserRequest.UserName.Any(char.IsWhiteSpace))
|
||||||
|
return new Result<User>(null, message: "Username should not contain space/whitespaces!");
|
||||||
|
|
||||||
var user = access.Users.FirstOrDefault(u => u.UserName == userRequest.UserName);
|
await using DbAccess access = new DbAccess(_configuration);
|
||||||
|
var user = access.Users.FirstOrDefault(u => u.UserName == authenticateUserRequest.UserName);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
return new Result<User>(user, message:"User name already exists!");
|
return new Result<User>(user, message:"User name already exists!");
|
||||||
byte[] hashedPwdBytes = Hasher.HashPassword(userRequest.Password, out byte[] salt);
|
|
||||||
|
byte[] hashedPwdBytes = Hasher.HashPassword(authenticateUserRequest.Password, out byte[] salt);
|
||||||
user = new User()
|
user = new User()
|
||||||
{
|
{
|
||||||
UserName = userRequest.UserName,
|
UserName = authenticateUserRequest.UserName,
|
||||||
Mail = userRequest.EMail,
|
Mail = "",
|
||||||
Password = hashedPwdBytes,
|
Password = hashedPwdBytes,
|
||||||
Salt = salt
|
Salt = salt
|
||||||
};
|
};
|
||||||
|
@ -50,7 +54,24 @@ namespace SharpRSS.API.Data
|
||||||
_log.Error(e, "Error creating user: {UserName}", user.UserName);
|
_log.Error(e, "Error creating user: {UserName}", user.UserName);
|
||||||
return new Result<User>(user, message: "Could not create user!");
|
return new Result<User>(user, message: "Could not create user!");
|
||||||
}
|
}
|
||||||
return new Result<User>(user, result);
|
return new Result<User>(user, result, "Ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result<IEnumerable<User>>> GetUsers(int take = 50, int skip = 0)
|
||||||
|
{
|
||||||
|
if (take is 0 or > 50)
|
||||||
|
take = 50;
|
||||||
|
await using DbAccess access = new DbAccess(_configuration);
|
||||||
|
IEnumerable<User> users = access.Users.Skip(skip).Take(take).ToList();
|
||||||
|
if (!users.Any())
|
||||||
|
return new Result<IEnumerable<User>>(users, false, "No users found!");
|
||||||
|
return new Result<IEnumerable<User>>(users, true, "Ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UserCount()
|
||||||
|
{
|
||||||
|
await using DbAccess access = new DbAccess(_configuration);
|
||||||
|
return access.Users.Count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
namespace SharpRSS.API.Models.Auth
|
|
||||||
{
|
|
||||||
public class UserRequest
|
|
||||||
{
|
|
||||||
public string UserName { get; set; }
|
|
||||||
public string EMail { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@ namespace SharpRSS.API.Models
|
||||||
{
|
{
|
||||||
public class Result<TValue>
|
public class Result<TValue>
|
||||||
{
|
{
|
||||||
public Result(TValue value, bool success = false, string message = "")
|
public Result(TValue? value, bool success = false, string message = "")
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
Success = success;
|
Success = success;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user