diff --git a/crs/CommonComponents/Contracts/Contracts.csproj b/crs/CommonComponents/Contracts/Contracts.csproj
index 7521ead..7b5f0d4 100644
--- a/crs/CommonComponents/Contracts/Contracts.csproj
+++ b/crs/CommonComponents/Contracts/Contracts.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/crs/CommonComponents/Contracts/Services/Identity/Identity.proto b/crs/CommonComponents/Contracts/Services/Identity/identity.v1.proto
similarity index 71%
rename from crs/CommonComponents/Contracts/Services/Identity/Identity.proto
rename to crs/CommonComponents/Contracts/Services/Identity/identity.v1.proto
index 2be51d9..8d6cb82 100644
--- a/crs/CommonComponents/Contracts/Services/Identity/Identity.proto
+++ b/crs/CommonComponents/Contracts/Services/Identity/identity.v1.proto
@@ -1,18 +1,16 @@
syntax = "proto3";
-option csharp_namespace = "Contracts.Services.Identity";
-
-package identity;
+package identity.v1;
service IdentityService {
- rpc GetUser(GetUserRequest) returns (User);
+ rpc GetUserInfo(GetUserRequest) returns (UserInfo);
}
message GetUserRequest {
string id = 1;
}
-message User {
+message UserInfo {
string user_id = 1;
string email = 2;
string first_name = 3;
diff --git a/crs/Docker/docker-compose.override.yml b/crs/Docker/docker-compose.override.yml
index 9884f16..4316733 100644
--- a/crs/Docker/docker-compose.override.yml
+++ b/crs/Docker/docker-compose.override.yml
@@ -76,18 +76,21 @@ services:
email.app:
environment:
- - ASPNETCORE_URLS=http://+:80
- - ASPNETCORE_HTTP_PORTS=5110
- - ASPNETCORE_ENVIRONMENT=Development
- # Custom environment variables
- - Email__From=${EMAIL_FROM}}
- - Email__Host=${EMAIL_HOST}
- - Email__Port=${EMAIL_PORT}
- - Email__Username=${EMAIL_USERNAME}
- - Email__Password=${EMAIL_PASSWORD}
- - Retry__Message__Send__Count=3
- - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
+ - ASPNETCORE_URLS=http://+:80
+ - ASPNETCORE_HTTP_PORTS=5110
+ - ASPNETCORE_ENVIRONMENT=Development
+ # Custom environment variables
+ - Email__From=${EMAIL_FROM}}
+ - Email__Host=${EMAIL_HOST}
+ - Email__Port=${EMAIL_PORT}
+ - Email__Username=${EMAIL_USERNAME}
+ - Email__Password=${EMAIL_PASSWORD}
+ - Retry__Message__Send__Count=3
+ - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
+ - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
+ - AUTH_ISSUER=${AUTH_ISSUER}
+ - WEB_AUDIENCE=${WEB_AUDIENCE}
+ - JWT_SECURITY_KEY=${JWT_SECURITY_KEY}
ports:
- "5110:80"
diff --git a/crs/Services/Catalog/Catalog.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs b/crs/Services/Catalog/Catalog.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs
index 858ba11..f244ecb 100644
--- a/crs/Services/Catalog/Catalog.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs
+++ b/crs/Services/Catalog/Catalog.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs
@@ -1,6 +1,4 @@
-using Microsoft.AspNetCore.Authentication.JwtBearer;
-
-namespace Catalog.App.Configurations;
+namespace Catalog.App.Configurations;
internal sealed class AuthenticationAuthorizationServiceInstaller : IServiceInstaller
{
diff --git a/crs/Services/Catalog/Catalog.App/GlobalUsings.cs b/crs/Services/Catalog/Catalog.App/GlobalUsings.cs
index d1f0c96..e44d44e 100644
--- a/crs/Services/Catalog/Catalog.App/GlobalUsings.cs
+++ b/crs/Services/Catalog/Catalog.App/GlobalUsings.cs
@@ -20,4 +20,5 @@
global using Microsoft.AspNetCore.Diagnostics.HealthChecks;
global using OpenTelemetry.Metrics;
global using Prometheus;
-global using Common.App.HealthChecks;
\ No newline at end of file
+global using Common.App.HealthChecks;
+global using Microsoft.AspNetCore.Authentication.JwtBearer;
\ No newline at end of file
diff --git a/crs/Services/Email/Email.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs b/crs/Services/Email/Email.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs
index 88e8990..1cac009 100644
--- a/crs/Services/Email/Email.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs
+++ b/crs/Services/Email/Email.App/Configurations/AuthenticationAuthorizationServiceInstaller.cs
@@ -4,6 +4,31 @@ internal sealed class AuthenticationAuthorizationServiceInstaller : IServiceInst
{
public void Install(IServiceCollection services, IConfiguration configuration)
{
+ services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, configureOptions =>
+ {
+ configureOptions.RequireHttpsMetadata = true;
+ configureOptions.SaveToken = true;
+ configureOptions.TokenValidationParameters = new TokenValidationParameters
+ {
+ ValidateIssuer = true,
+ ValidIssuer = Env.AUTH_ISSUER,
+ ValidateAudience = true,
+ ValidAudiences = [Env.WEB_AUDIENCE],
+
+ RequireExpirationTime = true,
+ ValidateLifetime = true,
+ ClockSkew = TimeSpan.Zero,
+
+ RoleClaimType = ClaimTypes.Role,
+
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = new SymmetricSecurityKey(
+ Encoding.UTF8.GetBytes(Env.JWT_SECURITY_KEY)),
+ };
+ });
+
+ services.AddAuthorization();
}
}
diff --git a/crs/Services/Email/Email.App/Configurations/GrpcServiceInstaller.cs b/crs/Services/Email/Email.App/Configurations/GrpcServiceInstaller.cs
index 1dbe857..d989682 100644
--- a/crs/Services/Email/Email.App/Configurations/GrpcServiceInstaller.cs
+++ b/crs/Services/Email/Email.App/Configurations/GrpcServiceInstaller.cs
@@ -4,7 +4,7 @@ internal sealed class GrpcServiceInstaller : IServiceInstaller
{
public void Install(IServiceCollection services, IConfiguration configuration)
{
- services.AddGrpcClient(options =>
+ services.AddGrpcClient(options =>
{
options.Address = new Uri(Env.IDENTITY_URL);
});
diff --git a/crs/Services/Email/Email.App/Email.App.csproj b/crs/Services/Email/Email.App/Email.App.csproj
index 09640ab..3ce5b1b 100644
--- a/crs/Services/Email/Email.App/Email.App.csproj
+++ b/crs/Services/Email/Email.App/Email.App.csproj
@@ -14,6 +14,7 @@
+
diff --git a/crs/Services/Email/Email.App/Env.cs b/crs/Services/Email/Email.App/Env.cs
index 093443a..00c25ab 100644
--- a/crs/Services/Email/Email.App/Env.cs
+++ b/crs/Services/Email/Email.App/Env.cs
@@ -8,6 +8,9 @@ internal static class Env
public static string IDENTITY_URL => GetEnvironmentVariable("IDENTITY_URL");
public static string RABBITMQ_DEFAULT_USER => GetEnvironmentVariable("RABBITMQ_DEFAULT_USER");
public static string RABBITMQ_DEFAULT_PASS => GetEnvironmentVariable("RABBITMQ_DEFAULT_PASS");
+ public static string AUTH_ISSUER => GetEnvironmentVariable("AUTH_ISSUER");
+ public static string WEB_AUDIENCE => GetEnvironmentVariable("WEB_AUDIENCE");
+ public static string JWT_SECURITY_KEY => GetEnvironmentVariable("JWT_SECURITY_KEY");
public static class ConnectionString
{
diff --git a/crs/Services/Email/Email.App/GlobalUsings.cs b/crs/Services/Email/Email.App/GlobalUsings.cs
index 22f1a83..823bd97 100644
--- a/crs/Services/Email/Email.App/GlobalUsings.cs
+++ b/crs/Services/Email/Email.App/GlobalUsings.cs
@@ -8,4 +8,8 @@
global using FluentValidation;
global using Email.App.OptionsSetup;
global using Common.Infrastructure.Middleware;
-global using Contracts.Services.Identity;
\ No newline at end of file
+global using Contracts.Services.Identity;
+global using Microsoft.AspNetCore.Authentication.JwtBearer;
+global using Microsoft.IdentityModel.Tokens;
+global using System.Security.Claims;
+global using System.Text;
diff --git a/crs/Services/Identity/Idenitty.Grpc/GlobalUsings.cs b/crs/Services/Identity/Idenitty.Grpc/GlobalUsings.cs
index 854cfaa..62fac2e 100644
--- a/crs/Services/Identity/Idenitty.Grpc/GlobalUsings.cs
+++ b/crs/Services/Identity/Idenitty.Grpc/GlobalUsings.cs
@@ -1,3 +1,2 @@
global using Grpc.Core;
-global using Contracts.Services.Identity;
global using MediatR;
\ No newline at end of file
diff --git a/crs/Services/Identity/Idenitty.Grpc/Idenitty.Grpc.csproj b/crs/Services/Identity/Idenitty.Grpc/Idenitty.Grpc.csproj
index df18c01..8fd29f0 100644
--- a/crs/Services/Identity/Idenitty.Grpc/Idenitty.Grpc.csproj
+++ b/crs/Services/Identity/Idenitty.Grpc/Idenitty.Grpc.csproj
@@ -15,6 +15,7 @@
+
diff --git a/crs/Services/Identity/Idenitty.Grpc/IdentityGrpcService.cs b/crs/Services/Identity/Idenitty.Grpc/IdentityGrpcService.cs
deleted file mode 100644
index 809728a..0000000
--- a/crs/Services/Identity/Idenitty.Grpc/IdentityGrpcService.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Idenitty.Grpc;
-
-public sealed class IdentityGrpcService(ISender sender) : IdentityService.IdentityServiceBase
-{
- private readonly ISender _sender = sender;
-
- public override async Task GetUser(GetUserRequest request, ServerCallContext context)
- {
- var result = await _sender.Send();
-
- return base.GetUser(request, context);
- }
-}
diff --git a/crs/Services/Identity/Idenitty.Grpc/IdentityGrpcServiceV1.cs b/crs/Services/Identity/Idenitty.Grpc/IdentityGrpcServiceV1.cs
new file mode 100644
index 0000000..775ff50
--- /dev/null
+++ b/crs/Services/Identity/Idenitty.Grpc/IdentityGrpcServiceV1.cs
@@ -0,0 +1,24 @@
+using Identity.Application.Users.Queries.GetUserInfoById;
+using Identity.V1;
+
+namespace Idenitty.Grpc;
+
+public sealed class IdentityGrpcServiceV1(ISender sender) : IdentityService.IdentityServiceBase
+{
+ private readonly ISender _sender = sender;
+
+ public override async Task GetUserInfo(GetUserRequest request, ServerCallContext context)
+ {
+ Guid.TryParse(request.Id, out Guid userId);
+
+ //if(userId == Guid.Empty)
+ //{
+ // context.Status = new Status(StatusCode.InvalidArgument, "Invalid user id");
+ //}
+
+ var query = new GetUserInfoByIdQuery(userId);
+ var result = await _sender.Send(query);
+ var response = new UserInfo() { s};
+ return base.GetUser(request, context);
+ }
+}
diff --git a/crs/Services/Identity/Identity.App/Startup.cs b/crs/Services/Identity/Identity.App/Startup.cs
index 88775bb..1ae6587 100644
--- a/crs/Services/Identity/Identity.App/Startup.cs
+++ b/crs/Services/Identity/Identity.App/Startup.cs
@@ -31,7 +31,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
configure.MapControllers();
configure.MapPrometheusScrapingEndpoint();
- configure.MapGrpcService();
+ configure.MapGrpcService();
configure.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
diff --git a/crs/Services/Identity/Identity.Application/GlobalUsings.cs b/crs/Services/Identity/Identity.Application/GlobalUsings.cs
index 88f94f1..fa9aac6 100644
--- a/crs/Services/Identity/Identity.Application/GlobalUsings.cs
+++ b/crs/Services/Identity/Identity.Application/GlobalUsings.cs
@@ -15,4 +15,5 @@
global using EventBus.Common.Abstractions;
global using Contracts.Services.Identity.Commands;
global using Identity.Infrastructure.Hashing;
-global using Identity.Infrastructure.Authentication;
\ No newline at end of file
+global using Identity.Infrastructure.Authentication;
+global using Identity.Application.Users.Common;
diff --git a/crs/Services/Identity/Identity.Application/Identity.Application.csproj b/crs/Services/Identity/Identity.Application/Identity.Application.csproj
index 7ef1778..d7ce476 100644
--- a/crs/Services/Identity/Identity.Application/Identity.Application.csproj
+++ b/crs/Services/Identity/Identity.Application/Identity.Application.csproj
@@ -17,8 +17,4 @@
-
-
-
-
diff --git a/crs/Services/Identity/Identity.Application/Users/Common/UserInfo.cs b/crs/Services/Identity/Identity.Application/Users/Common/UserInfo.cs
new file mode 100644
index 0000000..5eeec00
--- /dev/null
+++ b/crs/Services/Identity/Identity.Application/Users/Common/UserInfo.cs
@@ -0,0 +1,10 @@
+namespace Identity.Application.Users.Common;
+
+public sealed record UserInfo(
+ Guid UserId,
+ string Email,
+ string FirstName,
+ string LastName,
+ bool IsEmailConfirmed,
+ string Role,
+ string Gender);
diff --git a/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdHandler.cs b/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdHandler.cs
deleted file mode 100644
index 6ea1114..0000000
--- a/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdHandler.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Identity.Application.Users.Queries.GetUserInfoById;
-
-internal sealed class GetUserInfoByIdHandler
-{
-
-}
\ No newline at end of file
diff --git a/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdQuery.cs b/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdQuery.cs
new file mode 100644
index 0000000..ea9809f
--- /dev/null
+++ b/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdQuery.cs
@@ -0,0 +1,4 @@
+namespace Identity.Application.Users.Queries.GetUserInfoById;
+
+public sealed record GetUserInfoByIdQuery(Guid Id) : IQuery;
+
diff --git a/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdQueryHandler.cs b/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdQueryHandler.cs
new file mode 100644
index 0000000..450bcbb
--- /dev/null
+++ b/crs/Services/Identity/Identity.Application/Users/Queries/GetUserInfoById/GetUserInfoByIdQueryHandler.cs
@@ -0,0 +1,26 @@
+namespace Identity.Application.Users.Queries.GetUserInfoById;
+
+internal sealed class GetUserInfoByIdQueryHandler(IUserRepository userRepository) : IQueryHandler
+{
+ private readonly IUserRepository _userRepository = userRepository;
+
+ public async Task> Handle(GetUserInfoByIdQuery request, CancellationToken cancellationToken)
+ {
+ var userId = new UserId(request.Id);
+
+ var user = await _userRepository.GetUserByIdAsync(userId, cancellationToken);
+
+ if (user is null)
+ {
+ return Result.Failure(
+ UserErrors.UserDoesNotExist);
+ }
+
+ var userInfo = new UserInfo(
+ user.Id,
+ user.Email.Value,
+ user.(r => r.Name).ToList());
+
+ return Result.Success(userInfo);
+ }
+}
diff --git a/img/Eshop_logo.png b/img/Eshop_logo.png
new file mode 100644
index 0000000..b5be050
Binary files /dev/null and b/img/Eshop_logo.png differ