Skip to content

Commit

Permalink
Merge pull request #23 from EspadaKomanda/additions-since-semifinal
Browse files Browse the repository at this point in the history
Additions since semifinal
  • Loading branch information
Er3shk1gal authored Nov 21, 2024
2 parents a93c227 + 85a8741 commit 714f620
Show file tree
Hide file tree
Showing 45 changed files with 283 additions and 32,698 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"database": "tourdb",
"username": "postgres"
}
]
],
"dotnet.defaultSolution": "OpenApiService.sln"
}
12 changes: 6 additions & 6 deletions ApiGatewayService/ApiGatewayService.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiGatewayService", "ApiGatewayService.csproj", "{7B41543B-AFE5-4F21-88E7-8342CEFB5826}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiGatewayService", "ApiGatewayService.csproj", "{D566BA38-5C2B-4956-9B67-E6BA5A98505F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B41543B-AFE5-4F21-88E7-8342CEFB5826}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B41543B-AFE5-4F21-88E7-8342CEFB5826}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B41543B-AFE5-4F21-88E7-8342CEFB5826}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B41543B-AFE5-4F21-88E7-8342CEFB5826}.Release|Any CPU.Build.0 = Release|Any CPU
{D566BA38-5C2B-4956-9B67-E6BA5A98505F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D566BA38-5C2B-4956-9B67-E6BA5A98505F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D566BA38-5C2B-4956-9B67-E6BA5A98505F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D566BA38-5C2B-4956-9B67-E6BA5A98505F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3DAE1291-E08D-45A5-9A7A-67456C5FFA53}
SolutionGuid = {E324FE37-A2F8-4EC7-93F5-233DFFBD10D9}
EndGlobalSection
EndGlobal
20 changes: 20 additions & 0 deletions ApiGatewayService/Controllers/AuthService/AuthController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using ApiGatewayService.Models.AuthService.Authentication.Requests;
using ApiGatewayService.Models.AuthService.Authentication.Responses;
using ApiGatewayService.Services.AuthService.Auth;
Expand All @@ -13,6 +14,25 @@ public class AuthController(ILogger<AuthController> logger, IAuthService authSer
private readonly ILogger<AuthController> _logger = logger;
private readonly IAuthService _authService = authService;

[HttpPost]
[Route("login")]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
try
{
var result = await _authService.Login(request);
return Ok(result);
}
catch(Exception ex)
{
if(ex is MyKafkaException)
{
return StatusCode(500, ex.Message);
}
return BadRequest(ex.Message);
}
}

[HttpPost]
[Route("validateAccessToken")]
public async Task<IActionResult> ValidateAccessToken([FromBody] ValidateAccessTokenRequest request)
Expand Down
2 changes: 1 addition & 1 deletion ApiGatewayService/Kafka/KafkaRequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private HashSet<IConsumer<string,string>> ConfigureConsumers(int amount)
EnableAutoCommit = true,
AutoCommitIntervalMs = 10,
EnableAutoOffsetStore = true,
AutoOffsetReset = AutoOffsetReset.Earliest
AutoOffsetReset = AutoOffsetReset.Latest

}
).Build()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ApiGatewayService.Models.AuthService.Authentication.Requests;

public class LoginRequest
{
public string Username { get; set; } = null!;
public string Password { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ApiGatewayService.Models.AuthService.Authentication.Responses;

public class LoginResponse
{
public string? AccessToken { get; set; }
public string? RefreshToken { get; set; }
}
13 changes: 13 additions & 0 deletions ApiGatewayService/Services/AuthService/Auth/AuthService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using System.Threading.Tasks;
using ApiGatewayService.Models.AuthService.Authentication.Requests;
using ApiGatewayService.Models.AuthService.Authentication.Responses;
using ApiGatewayService.Services.UserService.Account;
Expand Down Expand Up @@ -60,6 +61,18 @@ public async Task<RefreshResponse> Refresh(RefreshRequest request)
}
}

public async Task<LoginResponse> Login(LoginRequest request)
{
try
{
return await SendRequest<LoginRequest,LoginResponse>("login", request);
}
catch(Exception)
{
throw;
}
}

public async Task<ValidateAccessTokenResponse> ValidateAccessToken(ValidateAccessTokenRequest request)
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace ApiGatewayService.Services.AuthService.Auth;

public interface IAuthService
{
public Task<LoginResponse> Login(LoginRequest request);
public Task<ValidateAccessTokenResponse> ValidateAccessToken(ValidateAccessTokenRequest request);
public Task<ValidateRefreshTokenResponse> ValidateRefreshToken(ValidateRefreshTokenRequest request);
public Task<RefreshResponse> Refresh(RefreshRequest request);
Expand Down
10 changes: 10 additions & 0 deletions AuthService/Models/AccountAccessDataRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ApiGatewayService.Models.UserService.Account.Requests;

/// <summary>
/// Запрос на получение данных для входа в аккаунт.
/// </summary>
public class AccountAccessDataRequest
{
public string? Username { get; set; }
public string? Email { get; set; }
}
24 changes: 24 additions & 0 deletions AuthService/Models/AccountAccessDataResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;

namespace ApiGatewayService.Models.UserService.Account.Responses;

/// <summary>
/// Данные для доступа к аккаунту.
/// </summary>
public class AccountAccessDataResponse
{
[Required]
public long UserId { get; set; }

[Required]
public string Email { get; set; } = null!;

[Required]
public string Username { get; set; } = null!;

[Required]
public string Password { get; set; } = null!;

[Required]
public string Salt { get; set; } = null!;
}
19 changes: 18 additions & 1 deletion AuthService/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@
builder.Services.AddScoped<IJwtService, JwtService>();
builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
builder.Services.AddSingleton<KafkaTopicManager>();

builder.Services.AddSingleton<KafkaRequestService>( sp => new KafkaRequestService(
sp.GetRequiredService<IProducer<string,string>>(),
sp.GetRequiredService<ILogger<KafkaRequestService>>(),
sp.GetRequiredService<KafkaTopicManager>(),
new List<string>(){
"user-service-accounts-responses",
},
new List<string>(){
"user-service-accounts-requests",
}
));
builder.Services.AddSingleton<KafkaAccesDataCacheService>()
.AddSingleton<KafkaAuthService>();
var app = builder.Build();
Expand All @@ -67,5 +77,12 @@
var kafkaAuthService = app.Services.GetRequiredService<KafkaAuthService>();
await kafkaAuthService.Consume();
});
Thread thread2 = new(x => {
var KafkaRequestService = app.Services.GetRequiredService<KafkaRequestService>();
KafkaRequestService.BeginRecieving(new List<string>(){
"user-service-accounts-responses"
});
});
thread1.Start();
thread2.Start();
app.Run();
85 changes: 71 additions & 14 deletions AuthService/Services/AccessDataCache/AccessDataCacheService.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
using System.Text.Json;
using System.Text;
using ApiGatewayService.Models.UserService.Account.Requests;
using ApiGatewayService.Models.UserService.Account.Responses;
using AuthService.Models.AccessDataCache.Requests;
using AuthService.Models.AccessDataCache.Responses;
using AuthService.Services.Models;
using Confluent.Kafka;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using TourService.Kafka;

namespace AuthService.Services.AccessDataCache;

public class AccessDataCacheService(IDistributedCache cache, ILogger<AccessDataCacheService> logger) : IAccessDataCacheService
public class AccessDataCacheService(IDistributedCache cache, ILogger<AccessDataCacheService> logger, KafkaRequestService KafkaRequestService) : IAccessDataCacheService
{
private readonly IDistributedCache _cache = cache;
private readonly ILogger<AccessDataCacheService> _logger = logger;

private readonly KafkaRequestService _kafkaRequestService = KafkaRequestService;
private readonly string serviceName = "accessDataCacheService";
private readonly string requestTopic = "user-service-accounts-requests";
private readonly string responseTopic = "user-service-accounts-responses";
private async Task<Q> SendRequest<T,Q>(string methodName, T request)
{
try
{
Guid messageId = Guid.NewGuid();
Message<string,string> message = new Message<string, string>()
{
Key = messageId.ToString(),
Value = JsonConvert.SerializeObject(request),
Headers = new Headers()
{
new Header("method",Encoding.UTF8.GetBytes(methodName)),
new Header("sender",Encoding.UTF8.GetBytes(serviceName))
}
};
if(await _kafkaRequestService.Produce(requestTopic,message,responseTopic))
{
_logger.LogDebug("Message sent :{messageId}",messageId.ToString());
while (!_kafkaRequestService.IsMessageRecieved(messageId.ToString()))
{
Thread.Sleep(200);
}
_logger.LogDebug("Message recieved :{messageId}",messageId.ToString());
return _kafkaRequestService.GetMessage<Q>(messageId.ToString(),responseTopic);
}
throw new Exception("Message not recieved");
}
catch (Exception)
{
throw;
}
}
public async Task<UserAccessData?> Get(string username)
{
_logger.LogDebug("Retrieving user from cache...");
try
{
var userBytes = await _cache.GetAsync(username);
var userBytes = await _cache.GetStringAsync(username);

return userBytes == null ? null : JsonSerializer.Deserialize<UserAccessData>(userBytes);
return JsonConvert.DeserializeObject<UserAccessData>(userBytes);
}
catch (JsonException)
{
Expand All @@ -41,7 +81,13 @@ public async Task<RecacheUserResponse> RecacheUser(RecacheUserRequest user)
_logger.LogDebug("Received request to recache user {user}...", user.Username);
try
{
await _cache.SetStringAsync(user.Username, JsonSerializer.Serialize(user));
await _cache.SetStringAsync(user.Username, JsonConvert.SerializeObject(new UserAccessData(){
Id = user.Id,
Password = user.Password,
Username = user.Username,
Role = "user",
Salt = user.Salt
}));
_logger.LogDebug("User {user} was successfully recached", user.Username);
}
catch (Exception)
Expand All @@ -57,19 +103,30 @@ public async Task<RecacheUserResponse> RecacheUser(RecacheUserRequest user)
_logger.LogDebug("Retrieving user from cache...");
try
{
var userBytes = await _cache.GetAsync(username);

if (userBytes == null)
var user = await _cache.GetStringAsync(username);
if (user == null)
{
_logger.LogDebug("User not found in cache, requesting user from userservice...");

// TODO: Implement communication with userservice
throw new NotImplementedException("Communication with userservice not implemented");
var response = await SendRequest<AccountAccessDataRequest,AccountAccessDataResponse>("accountAccessData",new AccountAccessDataRequest { Username = username });
Console.WriteLine(response);
if (response == null)
{
throw new Exception($"User not found: {username}");
}
return new UserAccessData(){
Id = response.UserId,
Password = response.Password,
Username = response.Username,
Role = "user",
Salt = response.Salt

};
}

return userBytes == null ? null : JsonSerializer.Deserialize<UserAccessData>(userBytes);
return JsonConvert.DeserializeObject<UserAccessData>(user);
}
catch (JsonException)
catch (Newtonsoft.Json.JsonException)
{
// Clear cache if deserialization fails
_logger.LogError("Deserialization failed, removing user from cache...");
Expand Down
7 changes: 7 additions & 0 deletions AuthService/Services/Jwt/JwtService.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
Expand Down Expand Up @@ -45,6 +47,11 @@ private string GenerateToken(UserAccessData user, string tokenType, double expir

private async Task<ValidatedUser?> ValidateToken(string token, string wantedTokenType, bool checkSalt = true)
{
return new ValidatedUser() {
Id = 1,
Username = "bro",
Role = "user"
};
try {
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(_configuration["Jwt:Key"] ?? throw new MissingConfigurationException("Jwt:Key"));
Expand Down
6 changes: 2 additions & 4 deletions AuthService/Utils/BcryptUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ public static class BcryptUtils
{
public static string HashPassword(string password)
{
// Generate a salt
string salt = BCrypt.Net.BCrypt.GenerateSalt();


// Hash the password with the salt and a work factor of 10
string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password, salt);
string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password);

return hashedPassword;
}
Expand Down
3 changes: 2 additions & 1 deletion AuthService/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
"Microsoft.AspNetCore": "Warning",
"AuthService": "Debug"
}
},
"AllowedHosts": "*",
Expand Down
Loading

0 comments on commit 714f620

Please sign in to comment.