mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 19:54:55 +00:00
Registration rework
+ InvitesRepository + AdminsRepository + rework jwt
This commit is contained in:
@@ -20,7 +20,7 @@ public class AuthController : Controller
|
||||
|
||||
[HttpPost("register")]// api/auth/register
|
||||
[RequireHttps]
|
||||
public async Task<IActionResult> Register([FromBody] UserDto userDto)
|
||||
public async Task<IActionResult> Register([FromBody] RegistrationDto registrationDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -29,25 +29,25 @@ public class AuthController : Controller
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var token = await _accountService.RegistrationAsync(userDto.Name, userDto.Password);
|
||||
_logger.LogInformation($"Register request for {userDto.Name}");
|
||||
var token = await _accountService.RegistrationAsync(registrationDto.Name, registrationDto.Password, registrationDto.InviteLink);
|
||||
_logger.LogInformation($"Register request for {registrationDto.Name}");
|
||||
return Ok(new { token });
|
||||
}
|
||||
catch (UserAlreadyExistException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, $"Registration failed for user {userDto.Name}");
|
||||
_logger.LogWarning(ex, $"Registration failed for user {registrationDto.Name}");
|
||||
return BadRequest("Registration failed: user already exists.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unexpected error during registration for user {Name}", userDto.Name);
|
||||
_logger.LogError(ex, "Unexpected error during registration for user {Name}", registrationDto.Name);
|
||||
return StatusCode(500, "An unexpected error occurred. Please try again later.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("login")]// api/auth/login
|
||||
[RequireHttps]
|
||||
public async Task<IActionResult> Login([FromBody] UserDto userDto)
|
||||
public async Task<IActionResult> Login([FromBody] LoginDto userDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Govor.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/admin/[controller]")]
|
||||
//[Authorize(Roles = "Admin")]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public class UsersController : Controller
|
||||
{
|
||||
private readonly ILogger<UsersController> _logger;
|
||||
|
||||
+36
-5
@@ -1,3 +1,4 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Govor.API.Hubs;
|
||||
using Govor.API.Services;
|
||||
@@ -8,6 +9,8 @@ using Govor.API.Services.Authentication.Interfaces;
|
||||
using Govor.Core.Infrastructure.Extensions;
|
||||
using Govor.Core.Infrastructure.Validators;
|
||||
using Govor.Core.Models;
|
||||
using Govor.Core.Repositories.Admins;
|
||||
using Govor.Core.Repositories.Invaites;
|
||||
using Govor.Core.Repositories.MediasAttachments;
|
||||
using Govor.Core.Repositories.Messages;
|
||||
using Govor.Core.Repositories.Users;
|
||||
@@ -16,6 +19,7 @@ using Govor.Data.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
@@ -69,9 +73,6 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
|
||||
builder.Services.AddAuthorization();
|
||||
|
||||
|
||||
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddScoped<IPasswordHasher, PasswordHasher>();
|
||||
@@ -84,6 +85,8 @@ builder.Services.AddScoped<IObjectValidator<MediaAttachments>, MediaAttachmentsV
|
||||
builder.Services.AddScoped<IMessagesRepository, MessagesRepository>();
|
||||
builder.Services.AddScoped<IMediaAttachmentsRepository, MediaAttachmentsRepository>();
|
||||
builder.Services.AddScoped<IUsersAdministration, UsersService>();
|
||||
builder.Services.AddScoped<IInvitesRepository, InvitesRepository>();
|
||||
builder.Services.AddScoped<IAdminsRepository, AdminsRepository>();
|
||||
|
||||
builder.Services.AddDbContext<GovorDbContext>(
|
||||
options =>
|
||||
@@ -93,7 +96,32 @@ builder.Services.AddDbContext<GovorDbContext>(
|
||||
);
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Govor API", Version = "v1" });
|
||||
|
||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT Authorization header using the Bearer scheme. Example: 'Bearer {token}'",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "bearer"
|
||||
});
|
||||
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
|
||||
},
|
||||
Array.Empty<string>()
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//builder.Services.AddOpenApi();
|
||||
|
||||
var app = builder.Build();
|
||||
@@ -102,11 +130,12 @@ var app = builder.Build();
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
//app.MapOpenApi();
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseRouting();
|
||||
@@ -117,6 +146,8 @@ app.UseAuthorization();
|
||||
app.MapControllers();
|
||||
app.MapHub<ChatsHub>("/api/chats");
|
||||
|
||||
app.MapSwagger().RequireAuthorization();
|
||||
|
||||
app.Map("/", () => "Not for browsers");
|
||||
|
||||
app.Run();
|
||||
@@ -4,6 +4,8 @@ using Govor.Core.Infrastructure.Extensions;
|
||||
using Govor.Core.Models;
|
||||
using Govor.Core.Repositories.Users;
|
||||
using Govor.API.Services;
|
||||
using Govor.Core.Repositories.Admins;
|
||||
using Govor.Core.Repositories.Invaites;
|
||||
|
||||
|
||||
namespace Govor.API.Services.Authentication;
|
||||
@@ -13,38 +15,64 @@ public class AuthService : IAccountService
|
||||
private readonly IPasswordHasher _passwordHasher;
|
||||
private readonly IJwtService _jwtService;
|
||||
private readonly IUsersRepository _usersRepository;
|
||||
private readonly IInvitesRepository _invitesRepository;
|
||||
private readonly IAdminsRepository _adminsRepository;
|
||||
|
||||
public AuthService(IUsersRepository usersRepository, IJwtService jwtService, IPasswordHasher passwordHasher)
|
||||
public AuthService(IUsersRepository usersRepository,
|
||||
IJwtService jwtService,
|
||||
IPasswordHasher passwordHasher,
|
||||
IInvitesRepository invitesRepository,
|
||||
IAdminsRepository adminsRepository)
|
||||
{
|
||||
_usersRepository = usersRepository;
|
||||
_jwtService = jwtService;
|
||||
_passwordHasher = passwordHasher;
|
||||
_invitesRepository = invitesRepository;
|
||||
_adminsRepository = adminsRepository;
|
||||
}
|
||||
|
||||
public async Task<string> RegistrationAsync(string name, string password)
|
||||
public async Task<string> RegistrationAsync(string name, string password, string inviteCode)
|
||||
{
|
||||
// 1. Проверка существования имени
|
||||
if (await _usersRepository.ExistsUsernameAsync(name))
|
||||
throw new UserAlreadyExistException(name);
|
||||
|
||||
|
||||
// 2. Проверка валидности инвайта
|
||||
var invite = await _invitesRepository.GetByCodeAsync(inviteCode);
|
||||
|
||||
// 3. Генерация пароля
|
||||
var passwordHash = _passwordHasher.Hash(password);
|
||||
|
||||
|
||||
// 4. Создание пользователя
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Username = name,
|
||||
Description = string.Empty,
|
||||
PasswordHash = passwordHash,
|
||||
CreatedOn = DateOnly.FromDateTime(DateTime.Now),
|
||||
Description = string.Empty,
|
||||
CreatedOn = DateOnly.FromDateTime(DateTime.UtcNow),
|
||||
IconId = Guid.NewGuid(),
|
||||
WasOnline = DateTime.UtcNow
|
||||
//Role = role == "Admin" ? "Admin" : "User" // Ограничение ролей
|
||||
WasOnline = DateTime.UtcNow,
|
||||
InviteId = invite.Id
|
||||
};
|
||||
|
||||
|
||||
// 5. Добавление пользователя
|
||||
await _usersRepository.AddAsync(user);
|
||||
|
||||
|
||||
// 6. Назначение роли, если инвайт — админский
|
||||
if (invite.IsAdmin)
|
||||
{
|
||||
await _adminsRepository.AddAsync(new Admin
|
||||
{
|
||||
UserId = user.Id
|
||||
});
|
||||
}
|
||||
|
||||
// 7. Генерация токена
|
||||
return _jwtService.GenerateJwtToken(user);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> LoginAsync(string name, string password)
|
||||
{
|
||||
if (await _usersRepository.ExistsUsernameAsync(name) == false)
|
||||
|
||||
@@ -4,6 +4,6 @@ namespace Govor.API.Services.Authentication.Interfaces;
|
||||
|
||||
public interface IAccountService
|
||||
{
|
||||
public Task<string> RegistrationAsync(string name, string password);
|
||||
public Task<string> RegistrationAsync(string name, string password, string inviteCode);
|
||||
public Task<string> LoginAsync(string name, string password);
|
||||
}
|
||||
@@ -3,6 +3,8 @@ using System.Security.Claims;
|
||||
using System.Text;
|
||||
using Govor.API.Services.Authentication.Interfaces;
|
||||
using Govor.Core.Models;
|
||||
using Govor.Core.Repositories.Admins;
|
||||
using Govor.Core.Repositories.Invaites;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
@@ -11,14 +13,22 @@ namespace Govor.API.Services.Authentication;
|
||||
public class JwtService : IJwtService
|
||||
{
|
||||
private JwtOption _jwtOption;
|
||||
private IInvitesRepository _invitesRepository;
|
||||
|
||||
public JwtService(IOptions<JwtOption> options)
|
||||
{
|
||||
_jwtOption = options.Value;
|
||||
}
|
||||
|
||||
public string GenerateJwtToken(User user)
|
||||
{
|
||||
Claim[] claims = [new("userID", user.Id.ToString())];
|
||||
var invite = _invitesRepository.GetByIdAsync(user.InviteId).Result;
|
||||
|
||||
var claims = new[]
|
||||
{
|
||||
new Claim("userID", user.Id.ToString()),
|
||||
new Claim(ClaimTypes.Role, invite.IsAdmin ? "Admin" : "User", ClaimValueTypes.String)
|
||||
};
|
||||
|
||||
var singing = new SigningCredentials(
|
||||
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOption.SecretKeу)),
|
||||
|
||||
Reference in New Issue
Block a user