Skip to content

Commit 30e0ca9

Browse files
committed
feat/active directory feature with integration gateway
1 parent 561178c commit 30e0ca9

18 files changed

Lines changed: 264 additions & 3 deletions

File tree

backend/src/CCE.Api.External/appsettings.Development.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
"CommunicationGateway": {
7878
"BaseUrl": "http://localhost:3001",
7979
"TimeoutSeconds": 30
80+
},
81+
"AdminAuthGateway": {
82+
"BaseUrl": "http://localhost:3001",
83+
"TimeoutSeconds": 30
8084
}
8185
}
8286
}

backend/src/CCE.Api.External/appsettings.Production.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
"CommunicationGateway": {
7878
"BaseUrl": "https://cce-mocks.bonto.run",
7979
"TimeoutSeconds": 30
80+
},
81+
"AdminAuthGateway": {
82+
"BaseUrl": "https://cce-mocks.bonto.run",
83+
"TimeoutSeconds": 30
8084
}
8185
}
8286
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using CCE.Api.Common.Extensions;
2+
using CCE.Application.Identity.Auth.AdLogin;
3+
using MediatR;
4+
using Microsoft.AspNetCore.Builder;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Routing;
7+
8+
namespace CCE.Api.Internal.Endpoints;
9+
10+
public static class AdminAuthEndpoints
11+
{
12+
public static IEndpointRouteBuilder MapAdminAuthEndpoints(this IEndpointRouteBuilder app)
13+
{
14+
var auth = app.MapGroup("/api/auth").WithTags("Auth");
15+
16+
auth.MapPost("/ad-login", async (
17+
AdLoginRequest body,
18+
HttpContext ctx,
19+
IMediator mediator,
20+
CancellationToken ct) =>
21+
{
22+
var result = await mediator.Send(new AdLoginCommand(
23+
body.Username,
24+
body.Password,
25+
ctx.Connection.RemoteIpAddress?.ToString(),
26+
ctx.Request.Headers.UserAgent.ToString()), ct).ConfigureAwait(false);
27+
28+
return result.ToHttpResult();
29+
})
30+
.AllowAnonymous()
31+
.WithName("InternalAdLogin");
32+
33+
return app;
34+
}
35+
}

backend/src/CCE.Api.Internal/Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@
5959

6060
app.UseCceOpenApi(apiTag: "internal");
6161

62-
app.MapAuthEndpoints(CCE.Application.Identity.Auth.Common.LocalAuthApi.Internal);
63-
app.MapIdentityEndpoints();
62+
app.MapAuthEndpoints(CCE.Application.Identity.Auth.Common.LocalAuthApi.Internal);
63+
app.MapAdminAuthEndpoints();
64+
app.MapIdentityEndpoints();
6465
app.MapExpertEndpoints();
6566
app.MapAssetEndpoints();
6667
app.MapResourceEndpoints();

backend/src/CCE.Api.Internal/appsettings.Development.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@
6464
"CommunicationGateway": {
6565
"BaseUrl": "http://localhost:3001",
6666
"TimeoutSeconds": 30
67+
},
68+
"AdminAuthGateway": {
69+
"BaseUrl": "http://localhost:3001",
70+
"TimeoutSeconds": 30
6771
}
6872
}
6973
}

backend/src/CCE.Api.Internal/appsettings.Production.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@
6464
"CommunicationGateway": {
6565
"BaseUrl": "https://cce-mocks.bonto.run",
6666
"TimeoutSeconds": 30
67+
},
68+
"AdminAuthGateway": {
69+
"BaseUrl": "https://cce-mocks.bonto.run",
70+
"TimeoutSeconds": 30
6771
}
6872
}
6973
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using CCE.Application.Common;
2+
using CCE.Application.Identity.Auth.Common;
3+
using MediatR;
4+
5+
namespace CCE.Application.Identity.Auth.AdLogin;
6+
7+
public sealed record AdLoginCommand(
8+
string Username,
9+
string Password,
10+
string? Ip,
11+
string? UserAgent)
12+
: IRequest<Response<AuthTokenDto>>;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using CCE.Application.Common;
2+
using CCE.Application.Identity.Auth.Common;
3+
using CCE.Application.Messages;
4+
using MediatR;
5+
6+
namespace CCE.Application.Identity.Auth.AdLogin;
7+
8+
internal sealed class AdLoginCommandHandler
9+
: IRequestHandler<AdLoginCommand, Response<AuthTokenDto>>
10+
{
11+
private readonly IAuthService _auth;
12+
private readonly MessageFactory _msg;
13+
14+
public AdLoginCommandHandler(IAuthService auth, MessageFactory msg)
15+
{
16+
_auth = auth;
17+
_msg = msg;
18+
}
19+
20+
public async Task<Response<AuthTokenDto>> Handle(AdLoginCommand request, CancellationToken ct)
21+
{
22+
var dto = await _auth.AdLoginAsync(
23+
request.Username,
24+
request.Password,
25+
request.Ip,
26+
request.UserAgent,
27+
ct).ConfigureAwait(false);
28+
29+
if (dto is null)
30+
{
31+
return _msg.InvalidCredentials<AuthTokenDto>();
32+
}
33+
34+
return _msg.Ok(dto, "AD_LOGIN_SUCCESS");
35+
}
36+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using FluentValidation;
2+
3+
namespace CCE.Application.Identity.Auth.AdLogin;
4+
5+
public sealed class AdLoginCommandValidator : AbstractValidator<AdLoginCommand>
6+
{
7+
public AdLoginCommandValidator()
8+
{
9+
RuleFor(x => x.Username)
10+
.NotEmpty()
11+
.WithMessage("Username is required.");
12+
13+
RuleFor(x => x.Password)
14+
.NotEmpty()
15+
.WithMessage("Password is required.");
16+
}
17+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace CCE.Application.Identity.Auth.AdLogin;
2+
3+
public sealed record AdLoginRequest(
4+
string Username,
5+
string Password);

0 commit comments

Comments
 (0)