mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-12 03:12:11 +08:00
feat: add rest client for modular monolith
This commit is contained in:
parent
ff8badcd4a
commit
d5312430ac
@ -7,6 +7,16 @@
|
||||
- [Key Features](#key-features)
|
||||
- [When to Use](#when-to-use)
|
||||
- [Challenges](#challenges)
|
||||
- [Modular Monolith Architecture Design](#modular-monolith-architecture-design)
|
||||
- [Development Setup](#development-setup)
|
||||
- [Dotnet Tools Packages](#dotnet-tools-packages)
|
||||
- [Husky](#husky)
|
||||
- [Upgrade Nuget Packages](#upgrade-nuget-packages)
|
||||
- [How to Run](#how-to-run)
|
||||
- [Build](#build)
|
||||
- [Run](#run)
|
||||
- [Test](#test)
|
||||
- [Documentation Apis](#documentation-apis)
|
||||
|
||||
|
||||
## Key Features
|
||||
@ -27,3 +37,66 @@
|
||||
- Still a single deployment unit, so scaling is limited.
|
||||
- Requires careful design to avoid tight coupling between modules.
|
||||
- Not as scalable or fault-tolerant as microservices.
|
||||
|
||||
|
||||
## Modular Monolith Architecture Design
|
||||
|
||||

|
||||
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Dotnet Tools Packages
|
||||
For installing our requirement packages with .NET cli tools, we need to install `dotnet tool manifest`.
|
||||
```bash
|
||||
dotnet new tool-manifest
|
||||
```
|
||||
And after that we can restore our dotnet tools packages with .NET cli tools from `.config` folder and `dotnet-tools.json` file.
|
||||
```
|
||||
dotnet tool restore
|
||||
```
|
||||
|
||||
### Husky
|
||||
Here we use `husky` to handel some pre commit rules and we used `conventional commits` rules and `formatting` as pre commit rules, here in [package.json](.././package.json). of course, we can add more rules for pre commit in future. (find more about husky in the [documentation](https://typicode.github.io/husky/get-started.html))
|
||||
We need to install `husky` package for `manage` `pre commits hooks` and also I add two packages `@commitlint/cli` and `@commitlint/config-conventional` for handling conventional commits rules in [package.json](.././package.json).
|
||||
Run the command bellow in the root of project to install all npm dependencies related to husky:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
> Note: In the root of project we have `.husky` folder and it has `commit-msg` file for handling conventional commits rules with provide user friendly message and `pre-commit` file that we can run our `scripts` as a `pre-commit` hooks. that here we call `format` script from [package.json](./package.json) for formatting purpose.
|
||||
|
||||
### Upgrade Nuget Packages
|
||||
For upgrading our nuget packages to last version, we use the great package [dotnet-outdated](https://github.com/dotnet-outdated/dotnet-outdated).
|
||||
Run the command below in the root of project to upgrade all of packages to last version:
|
||||
```bash
|
||||
dotnet outdated -u
|
||||
```
|
||||
|
||||
## How to Run
|
||||
|
||||
> ### Build
|
||||
To `build` all modules, run this command in the `root` of the project:
|
||||
```bash
|
||||
dotnet build
|
||||
```
|
||||
|
||||
> ### Run
|
||||
To `run` all modules, run this command in the root of the `Api` folder where the `csproj` file is located:
|
||||
```bash
|
||||
dotnet run
|
||||
```
|
||||
|
||||
> ### Test
|
||||
|
||||
To `test` all modules, run this command in the `root` of the project:
|
||||
```bash
|
||||
dotnet test
|
||||
```
|
||||
|
||||
> ### Documentation Apis
|
||||
|
||||
Each microservice provides `API documentation` and navigate to `/swagger` for `Swagger OpenAPI` or `/scalar/v1` for `Scalar OpenAPI` to visit list of endpoints.
|
||||
|
||||
As part of API testing, I created the [booking.rest](./booking.rest) file which can be run with the [REST Client](https://github.com/Huachao/vscode-restclient) `VSCode plugin`.
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 541 KiB |
230
2-modular-monolith-architecture-style/booking.rest
Normal file
230
2-modular-monolith-architecture-style/booking.rest
Normal file
@ -0,0 +1,230 @@
|
||||
|
||||
@booking-modular-monolith-api=https://localhost:5000
|
||||
|
||||
@contentType = application/json
|
||||
@flightid = "3c5c0000-97c6-fc34-2eb9-08db322230c9"
|
||||
@passengerId = "8c9c0000-97c6-fc34-2eb9-66db322230c9"
|
||||
|
||||
################################# Identity API #################################
|
||||
|
||||
###
|
||||
# @name Authenticate
|
||||
POST {{booking-modular-monolith-api}}/connect/token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
grant_type=password
|
||||
&client_id=client
|
||||
&client_secret=secret
|
||||
&username=samh
|
||||
&password=Admin@123456
|
||||
&scope=booking-modular-monolith
|
||||
###
|
||||
|
||||
|
||||
|
||||
###
|
||||
# @name Register_New_User
|
||||
POST {{booking-modular-monolith-api}}/api/v1/identity/register-user
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"firstName": "John",
|
||||
"lastName": "Do",
|
||||
"username": "admin",
|
||||
"passportNumber": "412900000",
|
||||
"email": "admin@admin.com",
|
||||
"password": "Admin@12345",
|
||||
"confirmPassword": "Admin@12345"
|
||||
}
|
||||
###
|
||||
|
||||
################################# Flight API #################################
|
||||
|
||||
###
|
||||
# @name Create_Seat
|
||||
Post {{booking-modular-monolith-api}}/api/v1/flight/seat
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"seatNumber": "1255",
|
||||
"type": 1,
|
||||
"class": 1,
|
||||
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9"
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Reserve_Seat
|
||||
Post {{booking-modular-monolith-api}}/api/v1/flight/reserve-seat
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9",
|
||||
"seatNumber": "1255"
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Get_Available_Seats
|
||||
GET {{booking-modular-monolith-api}}/api/v1/flight/get-available-seats/{{flightid}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Get_Flight_By_Id
|
||||
GET {{booking-modular-monolith-api}}/api/v1/flight/{{flightid}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Get_Available_Flights
|
||||
GET {{booking-modular-monolith-api}}/api/v1/flight/get-available-flights
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Create_Flights
|
||||
POST {{booking-modular-monolith-api}}/api/v1/flight
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"flightNumber": "12BB",
|
||||
"aircraftId": "3c5c0000-97c6-fc34-fcd3-08db322230c8",
|
||||
"departureAirportId": "3c5c0000-97c6-fc34-a0cb-08db322230c8",
|
||||
"departureDate": "2022-03-01T14:55:41.255Z",
|
||||
"arriveDate": "2022-03-01T14:55:41.255Z",
|
||||
"arriveAirportId": "3c5c0000-97c6-fc34-fc3c-08db322230c8",
|
||||
"durationMinutes": 120,
|
||||
"flightDate": "2022-03-01T14:55:41.255Z",
|
||||
"status": 1,
|
||||
"price": 8000
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Update_Flights
|
||||
PUT {{booking-modular-monolith-api}}/api/v1/flight
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"flightNumber": "BD467",
|
||||
"aircraftId": "3c5c0000-97c6-fc34-fcd3-08db322230c8",
|
||||
"departureAirportId": "3c5c0000-97c6-fc34-a0cb-08db322230c8",
|
||||
"departureDate": "2022-04-23T12:17:45.140Z",
|
||||
"arriveDate": "2022-04-23T12:17:45.140Z",
|
||||
"arriveAirportId": "3c5c0000-97c6-fc34-fc3c-08db322230c8",
|
||||
"durationMinutes": 120,
|
||||
"flightDate": "2022-04-23T12:17:45.140Z",
|
||||
"status": 4,
|
||||
"isDeleted": false,
|
||||
"price": 99000
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Delete_Flights
|
||||
DELETE {{booking-modular-monolith-api}}/api/v1/flight/{{flightid}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Create_Airport
|
||||
POST {{booking-modular-monolith-api}}/api/v1/flight/airport
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"name": "mehrabad",
|
||||
"address": "tehran",
|
||||
"code": "12YD"
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
|
||||
###
|
||||
# @name Create_Aircraft
|
||||
POST {{booking-modular-monolith-api}}/api/v1/flight/aircraft
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"name": "airbus2",
|
||||
"model": "322",
|
||||
"manufacturingYear": 2012
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
################################# Passenger API #################################
|
||||
|
||||
|
||||
###
|
||||
# @name Complete_Registration_Passenger
|
||||
POST {{booking-modular-monolith-api}}/api/v1/passenger/complete-registration
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"passportNumber": "412900000000",
|
||||
"passengerType": 1,
|
||||
"age": 30
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Get_Passenger_By_Id
|
||||
GET {{booking-modular-monolith-api}}/api/v1/passenger/{{passengerId}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
###
|
||||
|
||||
|
||||
################################# Booking API #################################
|
||||
|
||||
|
||||
###
|
||||
# @name Create_Booking
|
||||
POST {{booking-modular-monolith-api}}/api/v1/booking
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"passengerId": "8c9c0000-97c6-fc34-2eb9-66db322230c9",
|
||||
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9",
|
||||
"description": "I want to fly to iran"
|
||||
}
|
||||
###
|
||||
@ -4,7 +4,6 @@ using BuildingBlocks.Exception;
|
||||
using BuildingBlocks.HealthCheck;
|
||||
using BuildingBlocks.Jwt;
|
||||
using BuildingBlocks.Logging;
|
||||
using BuildingBlocks.Mapster;
|
||||
using BuildingBlocks.MassTransit;
|
||||
using BuildingBlocks.OpenApi;
|
||||
using BuildingBlocks.OpenTelemetryCollector;
|
||||
@ -12,7 +11,6 @@ using BuildingBlocks.PersistMessageProcessor;
|
||||
using BuildingBlocks.ProblemDetails;
|
||||
using BuildingBlocks.Web;
|
||||
using Figgle;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
|
||||
@ -38,8 +36,8 @@ public static class SharedInfrastructureExtensions
|
||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||
|
||||
builder.AddCustomSerilog(builder.Environment);
|
||||
builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>();
|
||||
builder.Services.AddJwt();
|
||||
builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>();
|
||||
builder.Services.AddTransient<AuthHeaderHandler>();
|
||||
builder.Services.AddPersistMessageProcessor();
|
||||
|
||||
@ -85,9 +83,6 @@ public static class SharedInfrastructureExtensions
|
||||
});
|
||||
|
||||
builder.Services.AddEasyCaching(options => { options.UseInMemory(builder.Configuration, "mem"); });
|
||||
|
||||
builder.Services.AddValidatorsFromAssemblies(AppDomain.CurrentDomain.GetAssemblies());
|
||||
builder.Services.AddCustomMapster(AppDomain.CurrentDomain.GetAssemblies());
|
||||
builder.Services.AddProblemDetails();
|
||||
|
||||
return builder;
|
||||
|
||||
@ -7,8 +7,6 @@ using Passenger.Extensions.Infrastructure;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.AddMinimalEndpoints(assemblies: AppDomain.CurrentDomain.GetAssemblies());
|
||||
|
||||
builder.AddSharedInfrastructure();
|
||||
|
||||
builder.AddFlightModules();
|
||||
@ -16,20 +14,19 @@ builder.AddIdentityModules();
|
||||
builder.AddPassengerModules();
|
||||
builder.AddBookingModules();
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// ref: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-7.0#routing-basics
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.MapMinimalEndpoints();
|
||||
app.UserSharedInfrastructure();
|
||||
|
||||
app.UseFlightModules();
|
||||
app.UseIdentityModules();
|
||||
app.UsePassengerModules();
|
||||
app.UseBookingModules();
|
||||
|
||||
app.UserSharedInfrastructure();
|
||||
app.MapMinimalEndpoints();
|
||||
|
||||
app.Run();
|
||||
|
||||
|
||||
@ -26,10 +26,9 @@
|
||||
"ConnectionString": "esdb://localhost:2113?tls=false"
|
||||
},
|
||||
"Jwt": {
|
||||
"Authority": "http://localhost:5001",
|
||||
"Audience": "booking_modular_monolith",
|
||||
"RequireHttpsMetadata": false,
|
||||
"MetadataAddress": "http://localhost:5001/.well-known/openid-configuration"
|
||||
"Authority": "https://localhost:5000",
|
||||
"Audience": "booking-modular-monolith",
|
||||
"RequireHttpsMetadata": false
|
||||
},
|
||||
"PersistMessageOptions": {
|
||||
"Interval": 30,
|
||||
|
||||
@ -0,0 +1 @@
|
||||
{"Version":1,"Id":"296345BF73910ADD1DAC302B848E47E7","Created":"2025-04-06T20:57:25.1670058Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8KNpFTgHKl5Nl-o13RQ8rseNpYdUTB-_FLsIGbeu6jM5x9l_rDfygUsYH6TAnyqXDFeW4U7xf8kJXDDvH1V0jkKcQaHFWYcZnKAirRBnuReu2OcaGWcn0vDccI5liTTRfp_Dknwhf3jgrU-LOBlPDoVGWwTwOQHXa4iHQjfOCG77Ey6CmJZ0w6JMi802tSMbpc2G2376b05GuzpoKwfgG_F8ZJcAtl1cql4KD11CcynPTNqK0fXOcIeGCQKgJDkJp_cHlk-sv4xJTFl5nqRx62v9auoB3AeKxqRqKqserGT-ZFYDeSxOlgmDSreVFezZ4tYd80Iq-ZpQXK5e3uz8gJ1B37_ySzgF_Rkscf67FivIqcpcV-WZzvnKXeQP0Wo7B7Qt8sKwCAW-vh3X5iMdDi-tecOWaRqeNrffbjd4efP1FK5wqmNrZirrcuCZDgPyYUiB1bSUE1HSj5vW4kFy_NF-3k0EVcQf5KqJpJ9QkTQgmTPkFCwwEcyX-P2hA21G64_M_7EjZXnjw29xjnkI7zO3mx3sA5bwPf6sCmxgE6joaI6P7G4u8JB5pbSHynOWWNTWRZm8YHngZCfK1DZa6Y-uAnrNzVQdcbB-uVGwszavP3Ohqtu7NBCaIkIhyT9N783n5-J8KAbSKu2FBF-qwNaUcmSAhbnRLyQwou-F0sxgM9iLwNcCo6jcgqz5g3MBEIcWa5IKdbtYXQQzbj3NlKmYg1l-x0SrxZD9403gNIS-zCEWLPEgpLr-NU06_Y5Vkbvn8jHKAr45nDFvY_osVvCPQ8qFuq_P-z3HMqFrfuPNlLrf_ZoJCpIKYNdXPJwHQXzGpz41QiN2omk52K5N8UCiGnDog66tJZAqGjtWWHpFCF2O4LXA9uEwnlD06N_i1T9umOtLnlGsF5SM0G3YjG_G8APqd6GDnJsM1wBoVXzzldGvS8GEwwxvVRGvLrSljPdR_l-8JifzUzhIOxMdlZUE8D9tQJhqZJovm34kfgx8AA0j4FQxAKPUhz99dapc5rmP1pgkuv7b9ZgtWa9js16GUJUYV3Dd6HC3lWU4zdXnQIsJPBUdgsiKptAXayc1KevAzw7o2PB7_auENui4cj1MuDxbaf9yrq9ZIol_tPw5rdN440vhHPIPzVi-1Wv0YyvyPD0fj2GAU5fL97lVlCprWuM71-rjVtARrn0pbf4ENBYk4ABWWke8ZHppbdFQQbjBv-yKCeiGA7qbRAeb_NMK2wmWUGz9DTVWtb04kmitXvg1-aj6ZwY-uIDSY5uaHPz7b8mxFywlSQ9plQzIkb-EfZk6RWxW1-NqyHMEAryM4QxwdDX9LjSo37CPdHCdOSRsMzH6zGH0_SgeN4W25Lk0RhoBHMMQk_gF5FCXjDteFlAdPFw9K5qmVVohHfEnAMDUZ4xYYgDx0Z254jsbSIFOuqEmUvmb5WvbKFtlcLrpFAuoqcNLfI61JM0LLxZNjpktGOMX5q1E_tYm5Y-bxd6W_2r-UUkCTKWJMp7_wr2CJPyegVshEBuUaO4_GyndCTY9_jh4OEYgyFQliEg66g3CUVy7ZBERrfz1CiHmpTqoKbs3toPsHMrB6yaQe9UtcYzLBRP3OVku3WmE1IylfUsZ64YA2DBU399JjYckXlWU3PxH9GAxcnIW8cU_29XZZ0ueGLFeSRP0mBb8TqVIcqd3xoAUbZGPnleme-D44yco8ZSGFVhQqt5qstzIA2DQALjVf2E5vg-yL8Gj9s5q-xjPjBgZgyW23gbBEO6PynDK3jfnucHXcLsHMpvZwyV1yaU3314mNLUpu241_7ukMuWC5FmxaVWqe4n9h-W479YlK5WmI5TDmWcc12DQI92eIAYCSYA60SOJhnuGsyFHwedfxIjVjouZeAWWHj1QOM3uZ1rwYOB0DZSlqI6C2kecv4D2CFq7gYosBxQX9fSnJ2MyUiGOxbdlRtwGB_dtRtlqWpt-acu-l9i5jNwdM6QnNejoPthvWPCcvfaaqFjWjnZQQKSBBfWV9Coe7mnaJYhyqWFUQ4AKcDuboQ3k3jj2p-5LTnbFlTQ3SzLfsgjLjpD5hqIY1ND5NWOT3D0pQumfh5tJxgSa0g-HhW7XBSGs2783OFdgAMuxCkZUgisdu0MRyQzdqWEY30trlpnpsAGOO3E8MMxQ2COy7Y-WrUykioag1qkJTbT-1FgHgw9Qj4dnQ136_tC3BvVrmO6pId26PzdPDpV_4T5vNLoyuiyyUqnHcKOETFrHpbj2cXmi-sYuqrwfNZKfcPIsAkekmcWlLd9s4glvD3xJ0SB0s6gJURjvupdD96l2kfdHw8qieB0ovlGISrpjnAKGn6F81_32rYULB-NDN8H4aTdiVmhvwf6KkpXHA9Euuyyir4BqHmIknr8WWuugIMxRw3ysCS4OIV5ocsjzIfQ9r_15bNWsoyWPDkVnKcS1ffbURzYPNIqTO6Ik5iC7rk705WAxaojy","DataProtected":true}
|
||||
@ -50,7 +50,7 @@ public class CreateBookingEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("CreateBooking")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Booking").Build())
|
||||
.Produces<CreateBookingResponseDto>()
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
using Booking.Data;
|
||||
using BuildingBlocks.Core;
|
||||
using BuildingBlocks.EventStoreDB;
|
||||
using BuildingBlocks.Mapster;
|
||||
using BuildingBlocks.Mongo;
|
||||
using BuildingBlocks.Web;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@ -12,6 +15,9 @@ public static class InfrastructureExtensions
|
||||
public static WebApplicationBuilder AddBookingModules(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddScoped<IEventMapper, EventMapper>();
|
||||
builder.AddMinimalEndpoints(assemblies: typeof(BookingRoot).Assembly);
|
||||
builder.Services.AddValidatorsFromAssembly(typeof(BookingRoot).Assembly);
|
||||
builder.Services.AddCustomMapster(typeof(BookingRoot).Assembly);
|
||||
builder.AddMongoDbContext<BookingReadDbContext>();
|
||||
|
||||
// ref: https://github.com/oskardudycz/EventSourcing.NetCore/tree/main/Sample/EventStoreDB/ECommerce
|
||||
|
||||
@ -54,7 +54,7 @@ public class CreateAircraftEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("CreateAircraft")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<CreateAircraftResponseDto>()
|
||||
|
||||
@ -51,7 +51,7 @@ public class CreateAirportEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("CreateAirport")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<CreateAirportResponseDto>()
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
using BuildingBlocks.Core;
|
||||
using BuildingBlocks.EFCore;
|
||||
using BuildingBlocks.Mapster;
|
||||
using BuildingBlocks.Mongo;
|
||||
using BuildingBlocks.Web;
|
||||
using Flight.Data;
|
||||
using Flight.Data.Seed;
|
||||
using Flight.GrpcServer.Services;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@ -15,6 +18,9 @@ public static class InfrastructureExtensions
|
||||
public static WebApplicationBuilder AddFlightModules(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddScoped<IEventMapper, EventMapper>();
|
||||
builder.AddMinimalEndpoints(assemblies: typeof(FlightRoot).Assembly);
|
||||
builder.Services.AddValidatorsFromAssembly(typeof(FlightRoot).Assembly);
|
||||
builder.Services.AddCustomMapster(typeof(FlightRoot).Assembly);
|
||||
builder.AddCustomDbContext<FlightDbContext>(nameof(Flight));
|
||||
builder.Services.AddScoped<IDataSeeder, FlightDataSeeder>();
|
||||
builder.AddMongoDbContext<FlightReadDbContext>();
|
||||
|
||||
@ -14,7 +14,7 @@ public static class MediatRExtensions
|
||||
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(typeof(FlightRoot).Assembly));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
|
||||
// services.AddScoped(typeof(IPipelineBehavior<,>), typeof(EfTxFlightBehavior<,>));
|
||||
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(EfTxFlightBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(CachingBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(InvalidateCachingBehavior<,>));
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ public class CreateFlightEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.CreatedAtRoute("GetFlightById", new { id = result.Id }, response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("CreateFlight")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<CreateFlightResponseDto>(StatusCodes.Status201Created)
|
||||
|
||||
@ -45,7 +45,7 @@ public class DeleteFlightEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.NoContent();
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("DeleteFlight")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
|
||||
@ -46,7 +46,7 @@ public class GetAvailableFlightsEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("GetAvailableFlights")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<GetAvailableFlightsResponseDto>()
|
||||
|
||||
@ -39,7 +39,7 @@ public class GetFlightByIdEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("GetFlightById")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<GetFlightByIdResponseDto>()
|
||||
|
||||
@ -56,7 +56,7 @@ public class UpdateFlightEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.NoContent();
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("UpdateFlight")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
|
||||
@ -44,7 +44,7 @@ public class CreateSeatEndpoint : IMinimalEndpoint
|
||||
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapPost($"{EndpointConfig.BaseApiPath}/flight/seat", CreateSeat)
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("CreateSeat")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<CreateSeatResponseDto>()
|
||||
|
||||
@ -34,7 +34,7 @@ public class GetAvailableSeatsEndpoint : IMinimalEndpoint
|
||||
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-seats/{{id}}", GetAvailableSeats)
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("GetAvailableSeats")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<GetAvailableSeatsResponseDto>()
|
||||
|
||||
@ -35,7 +35,7 @@ public class ReserveSeatEndpoint : IMinimalEndpoint
|
||||
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapPost($"{EndpointConfig.BaseApiPath}/flight/reserve-seat", ReserveSeat)
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("ReserveSeat")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
|
||||
.Produces<ReserveSeatResponseDto>()
|
||||
|
||||
@ -25,7 +25,8 @@ public static class Config
|
||||
new(Constants.StandardScopes.FlightApi),
|
||||
new(Constants.StandardScopes.PassengerApi),
|
||||
new(Constants.StandardScopes.BookingApi),
|
||||
new(Constants.StandardScopes.IdentityApi)
|
||||
new(Constants.StandardScopes.IdentityApi),
|
||||
new(Constants.StandardScopes.BookingModularMonolith),
|
||||
};
|
||||
|
||||
|
||||
@ -35,7 +36,8 @@ public static class Config
|
||||
new(Constants.StandardScopes.FlightApi),
|
||||
new(Constants.StandardScopes.PassengerApi),
|
||||
new(Constants.StandardScopes.BookingApi),
|
||||
new(Constants.StandardScopes.IdentityApi)
|
||||
new(Constants.StandardScopes.IdentityApi),
|
||||
new(Constants.StandardScopes.BookingModularMonolith),
|
||||
};
|
||||
|
||||
public static IEnumerable<Client> Clients =>
|
||||
@ -56,7 +58,8 @@ public static class Config
|
||||
Constants.StandardScopes.FlightApi,
|
||||
Constants.StandardScopes.PassengerApi,
|
||||
Constants.StandardScopes.BookingApi,
|
||||
Constants.StandardScopes.IdentityApi
|
||||
Constants.StandardScopes.IdentityApi,
|
||||
Constants.StandardScopes.BookingModularMonolith,
|
||||
},
|
||||
AccessTokenLifetime = 3600, // authorize the client to access protected resources
|
||||
IdentityTokenLifetime = 3600 // authenticate the user
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
using BuildingBlocks.Core;
|
||||
using BuildingBlocks.EFCore;
|
||||
using BuildingBlocks.Mapster;
|
||||
using BuildingBlocks.Web;
|
||||
using FluentValidation;
|
||||
using Identity.Configurations;
|
||||
using Identity.Data;
|
||||
using Identity.Data.Seed;
|
||||
@ -15,6 +18,9 @@ public static class InfrastructureExtensions
|
||||
public static WebApplicationBuilder AddIdentityModules(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddScoped<IEventMapper, EventMapper>();
|
||||
builder.AddMinimalEndpoints(assemblies: typeof(IdentityRoot).Assembly);
|
||||
builder.Services.AddValidatorsFromAssembly(typeof(IdentityRoot).Assembly);
|
||||
builder.Services.AddCustomMapster(typeof(IdentityRoot).Assembly);
|
||||
builder.AddCustomDbContext<IdentityContext>(nameof(Identity));
|
||||
builder.Services.AddScoped<IDataSeeder, IdentityDataSeeder>();
|
||||
builder.AddCustomIdentityServer();
|
||||
|
||||
@ -16,7 +16,7 @@ public static class MediatRExtensions
|
||||
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(typeof(IdentityRoot).Assembly));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
|
||||
// services.AddScoped(typeof(IPipelineBehavior<,>), typeof(EfTxIdentityBehavior<,>));
|
||||
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(EfTxIdentityBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(CachingBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(InvalidateCachingBehavior<,>));
|
||||
|
||||
|
||||
@ -15,5 +15,6 @@ public static class Constants
|
||||
public const string PassengerApi = "passenger-api";
|
||||
public const string BookingApi = "booking-api";
|
||||
public const string IdentityApi = "identity-api";
|
||||
public const string BookingModularMonolith = "booking-modular-monolith";
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ using BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.Core;
|
||||
using BuildingBlocks.Core.CQRS;
|
||||
using BuildingBlocks.Web;
|
||||
using Duende.IdentityServer.EntityFramework.Entities;
|
||||
using Exceptions;
|
||||
using FluentValidation;
|
||||
using Mapster;
|
||||
@ -48,7 +47,7 @@ public class RegisterNewUserEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
// .RequireAuthorization()
|
||||
.RequireAuthorization()
|
||||
.WithName("RegisterUser")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Identity").Build())
|
||||
.Produces<RegisterNewUserResponseDto>()
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
using BuildingBlocks.Core;
|
||||
using BuildingBlocks.EFCore;
|
||||
using BuildingBlocks.Mapster;
|
||||
using BuildingBlocks.Mongo;
|
||||
using BuildingBlocks.Web;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Passenger.Data;
|
||||
@ -13,6 +16,9 @@ public static class InfrastructureExtensions
|
||||
public static WebApplicationBuilder AddPassengerModules(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddScoped<IEventMapper, EventMapper>();
|
||||
builder.AddMinimalEndpoints(assemblies: typeof(PassengerRoot).Assembly);
|
||||
builder.Services.AddValidatorsFromAssembly(typeof(PassengerRoot).Assembly);
|
||||
builder.Services.AddCustomMapster(typeof(PassengerRoot).Assembly);
|
||||
builder.AddCustomDbContext<PassengerDbContext>(nameof(Passenger));
|
||||
builder.AddMongoDbContext<PassengerReadDbContext>();
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ public static class MediatRExtensions
|
||||
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(typeof(PassengerRoot).Assembly));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
|
||||
// services.AddScoped(typeof(IPipelineBehavior<,>), typeof(EfTxPassengerBehavior<,>));
|
||||
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(EfTxPassengerBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(CachingBehavior<,>));
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(InvalidateCachingBehavior<,>));
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ public class CompleteRegisterPassengerEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("CompleteRegisterPassenger")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Passenger").Build())
|
||||
.Produces<CompleteRegisterPassengerResponseDto>()
|
||||
|
||||
@ -36,7 +36,7 @@ public class GetPassengerByIdEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(response);
|
||||
})
|
||||
.RequireAuthorization(nameof(ApiScope))
|
||||
.RequireAuthorization()
|
||||
.WithName("GetPassengerById")
|
||||
.WithApiVersionSet(builder.NewApiVersionSet("Passenger").Build())
|
||||
.Produces<GetPassengerByIdResponseDto>()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" version="26.0.11">
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" version="26.1.2">
|
||||
<diagram name="Page-1" id="LwSOovy8OdwzHFtQ82wI">
|
||||
<mxGraphModel dx="3968" dy="3244" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0">
|
||||
<mxGraphModel dx="3490" dy="2987" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
@ -10,9 +10,6 @@
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-73" value="<span style="color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap-mode: nowrap;">%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bb%26gt%3B%26lt%3Bfont%26gt%3BOutbox%20Processor%26lt%3B%2Ffont%26gt%3B%26lt%3B%2Fb%26gt%3B%22%20style%3D%22text%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Bhtml%3D1%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontSize%3D18%3BfontFamily%3DComic%20Sans%20MS%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%2298%22%20y%3D%22-84%22%20width%3D%22145%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E</span>" style="rounded=1;whiteSpace=wrap;html=1;glass=0;shadow=0;fillColor=#ffe6cc;strokeColor=#d79b00;opacity=50;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="-388" width="310" height="544" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-60" value="" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;fontColor=#333333;labelBackgroundColor=default;fillColor=#f5f5f5;strokeColor=#666666;opacity=80;" parent="1" vertex="1">
|
||||
<mxGeometry x="70" y="-820" width="1680" height="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-6" value="" style="rounded=1;whiteSpace=wrap;html=1;glass=0;shadow=0;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;opacity=10;" parent="1" vertex="1">
|
||||
<mxGeometry x="120" y="-760" width="370" height="220" as="geometry" />
|
||||
</mxCell>
|
||||
@ -110,7 +107,7 @@
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-48" style="edgeStyle=orthogonalEdgeStyle;shape=connector;curved=0;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=0;dashed=1;dashPattern=8 8;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=default;labelBackgroundColor=default;elbow=vertical;startSize=8;endArrow=open;endFill=0;endSize=8;flowAnimation=0;" parent="1" source="PG-S5D8SCmHSsYNVxMVk-34" target="PG-S5D8SCmHSsYNVxMVk-29" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="npFnTr0Nz-ztX7RqOmGq-12" style="edgeStyle=orthogonalEdgeStyle;shape=connector;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#D44E4E;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=default;labelBackgroundColor=default;startSize=8;endArrow=open;endFill=0;endSize=8;entryX=0.253;entryY=0.114;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" target="PG-S5D8SCmHSsYNVxMVk-72">
|
||||
<mxCell id="npFnTr0Nz-ztX7RqOmGq-12" style="edgeStyle=orthogonalEdgeStyle;shape=connector;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#D44E4E;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=default;labelBackgroundColor=default;startSize=8;endArrow=open;endFill=0;endSize=8;entryX=0.253;entryY=0.114;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="PG-S5D8SCmHSsYNVxMVk-72" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="623" y="-643" as="sourcePoint" />
|
||||
<mxPoint x="820" y="-200" as="targetPoint" />
|
||||
@ -211,24 +208,6 @@
|
||||
<mxPoint x="1527.3099999999995" y="-759.0799999999999" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-62" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/ResourceGroup.svg;fontFamily=Helvetica;fontColor=default;labelBackgroundColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="129.5" y="-749" width="36.25" height="29" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-63" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/ResourceGroup.svg;fontFamily=Helvetica;fontColor=default;labelBackgroundColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="1330" y="-749" width="36.25" height="29" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-64" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/ResourceGroup.svg;fontFamily=Helvetica;fontColor=default;labelBackgroundColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="930" y="-748" width="36.25" height="29" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-65" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/ResourceGroup.svg;fontFamily=Helvetica;fontColor=default;labelBackgroundColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="532" y="-748" width="36.25" height="29" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-68" value="<b>MICROSERVICES</b>" style="text;strokeColor=none;fillColor=none;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=15;fontFamily=Comic Sans MS;" parent="1" vertex="1">
|
||||
<mxGeometry x="143" y="-798" width="130" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-70" value="" style="image;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/azure2/ai_machine_learning/Cognitive_Services.svg;fontFamily=Helvetica;fontColor=default;labelBackgroundColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="90" y="-807" width="48.17" height="34" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PG-S5D8SCmHSsYNVxMVk-72" value="" style="shape=image;imageAspect=0;aspect=fixed;verticalLabelPosition=bottom;verticalAlign=top;fontFamily=Helvetica;fontSize=12;fontColor=default;labelBackgroundColor=default;image=data:image/svg+xml,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgLTE4IDI1NiAyNTYiIGhlaWdodD0iODAwcHgiIHdpZHRoPSI4MDBweCI+PHBhdGggZmlsbD0iIzkxMjYyNiIgZD0iTTI0NS45NyAxNjguOTQzYy0xMy42NjIgNy4xMjEtODQuNDM0IDM2LjIyLTk5LjUwMSA0NC4wNzUtMTUuMDY3IDcuODU2LTIzLjQzNyA3Ljc4LTM1LjM0IDIuMDktMTEuOTAyLTUuNjktODcuMjE2LTM2LjExMi0xMDAuNzgzLTQyLjU5N0MzLjU2NiAxNjkuMjcxIDAgMTY2LjUzNSAwIDE2My45NTF2LTI1Ljg3NnM5OC4wNS0yMS4zNDUgMTEzLjg3OS0yNy4wMjRjMTUuODI4LTUuNjc5IDIxLjMyLTUuODg0IDM0Ljc5LS45NSAxMy40NzIgNC45MzYgOTQuMDE4IDE5LjQ2OCAxMDcuMzMxIDI0LjM0NGwtLjAwNiAyNS41MWMuMDAyIDIuNTU4LTMuMDcgNS4zNjQtMTAuMDI0IDguOTg4Ii8+PHBhdGggZmlsbD0iI0M2MzAyQiIgZD0iTTI0NS45NjUgMTQzLjIyYy0xMy42NjEgNy4xMTgtODQuNDMxIDM2LjIxOC05OS40OTggNDQuMDcyLTE1LjA2NiA3Ljg1Ny0yMy40MzYgNy43OC0zNS4zMzggMi4wOS0xMS45MDMtNS42ODYtODcuMjE0LTM2LjExMy0xMDAuNzgtNDIuNTk0LTEzLjU2Ni02LjQ4NS0xMy44NS0xMC45NDgtLjUyNC0xNi4xNjYgMTMuMzI2LTUuMjIgODguMjI0LTM0LjYwNSAxMDQuMDU1LTQwLjI4NCAxNS44MjgtNS42NzcgMjEuMzE5LTUuODg0IDM0Ljc4OS0uOTQ4IDEzLjQ3MSA0LjkzNCA4My44MTkgMzIuOTM1IDk3LjEzIDM3LjgxIDEzLjMxNiA0Ljg4MSAxMy44MjcgOC45LjE2NiAxNi4wMiIvPjxwYXRoIGZpbGw9IiM5MTI2MjYiIGQ9Ik0yNDUuOTcgMTI3LjA3NGMtMTMuNjYyIDcuMTIyLTg0LjQzNCAzNi4yMi05OS41MDEgNDQuMDc4LTE1LjA2NyA3Ljg1My0yMy40MzcgNy43NzctMzUuMzQgMi4wODctMTEuOTAzLTUuNjg3LTg3LjIxNi0zNi4xMTItMTAwLjc4My00Mi41OTdDMy41NjYgMTI3LjQwMiAwIDEyNC42NyAwIDEyMi4wODVWOTYuMjA2czk4LjA1LTIxLjM0NCAxMTMuODc5LTI3LjAyM2MxNS44MjgtNS42NzkgMjEuMzItNS44ODUgMzQuNzktLjk1QzE2Mi4xNDIgNzMuMTY4IDI0Mi42ODggODcuNjk3IDI1NiA5Mi41NzRsLS4wMDYgMjUuNTEzYy4wMDIgMi41NTctMy4wNyA1LjM2My0xMC4wMjQgOC45ODciLz48cGF0aCBmaWxsPSIjQzYzMDJCIiBkPSJNMjQ1Ljk2NSAxMDEuMzUxYy0xMy42NjEgNy4xMi04NC40MzEgMzYuMjE4LTk5LjQ5OCA0NC4wNzUtMTUuMDY2IDcuODU0LTIzLjQzNiA3Ljc3Ny0zNS4zMzggMi4wODctMTEuOTAzLTUuNjg2LTg3LjIxNC0zNi4xMTItMTAwLjc4LTQyLjU5NC0xMy41NjYtNi40ODMtMTMuODUtMTAuOTQ3LS41MjQtMTYuMTY3QzIzLjE1MSA4My41MzUgOTguMDUgNTQuMTQ4IDExMy44OCA0OC40N2MxNS44MjgtNS42NzggMjEuMzE5LTUuODg0IDM0Ljc4OS0uOTQ5IDEzLjQ3MSA0LjkzNCA4My44MTkgMzIuOTMzIDk3LjEzIDM3LjgxIDEzLjMxNiA0Ljg4IDEzLjgyNyA4LjkuMTY2IDE2LjAyIi8+PHBhdGggZmlsbD0iIzkxMjYyNiIgZD0iTTI0NS45NyA4My42NTNjLTEzLjY2MiA3LjEyLTg0LjQzNCAzNi4yMi05OS41MDEgNDQuMDc4LTE1LjA2NyA3Ljg1NC0yMy40MzcgNy43NzctMzUuMzQgMi4wODctMTEuOTAzLTUuNjg3LTg3LjIxNi0zNi4xMTMtMTAwLjc4My00Mi41OTVDMy41NjYgODMuOTggMCA4MS4yNDcgMCA3OC42NjV2LTI1Ljg4czk4LjA1LTIxLjM0MyAxMTMuODc5LTI3LjAyMWMxNS44MjgtNS42OCAyMS4zMi01Ljg4NCAzNC43OS0uOTVDMTYyLjE0MiAyOS43NDkgMjQyLjY4OCA0NC4yNzggMjU2IDQ5LjE1NWwtLjAwNiAyNS41MTJjLjAwMiAyLjU1NS0zLjA3IDUuMzYxLTEwLjAyNCA4Ljk4NiIvPjxwYXRoIGZpbGw9IiNDNjMwMkIiIGQ9Ik0yNDUuOTY1IDU3LjkzYy0xMy42NjEgNy4xMi04NC40MzEgMzYuMjItOTkuNDk4IDQ0LjA3NC0xNS4wNjYgNy44NTQtMjMuNDM2IDcuNzc3LTM1LjMzOCAyLjA5Qzk5LjIyNyA5OC40MDQgMjMuOTE1IDY3Ljk4IDEwLjM1IDYxLjQ5Ny0zLjIxNyA1NS4wMTUtMy41IDUwLjU1IDkuODI1IDQ1LjMzMSAyMy4xNTEgNDAuMTEzIDk4LjA1IDEwLjczIDExMy44OCA1LjA1YzE1LjgyOC01LjY3OSAyMS4zMTktNS44ODMgMzQuNzg5LS45NDggMTMuNDcxIDQuOTM1IDgzLjgxOSAzMi45MzQgOTcuMTMgMzcuODExIDEzLjMxNiA0Ljg3NiAxMy44MjcgOC44OTcuMTY2IDE2LjAxNyIvPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0xNTkuMjgzIDMyLjc1N2wtMjIuMDEgMi4yODUtNC45MjcgMTEuODU2LTcuOTU4LTEzLjIzLTI1LjQxNS0yLjI4NCAxOC45NjQtNi44MzktNS42OS0xMC40OTggMTcuNzU1IDYuOTQ0IDE2LjczOC01LjQ4LTQuNTI0IDEwLjg1NSAxNy4wNjcgNi4zOTFNMTMxLjAzMiA5MC4yNzVMODkuOTU1IDczLjIzOGw1OC44Ni05LjAzNS0xNy43ODMgMjYuMDcyTTc0LjA4MiAzOS4zNDdjMTcuMzc1IDAgMzEuNDYgNS40NiAzMS40NiAxMi4xOTQgMCA2LjczNi0xNC4wODUgMTIuMTk1LTMxLjQ2IDEyLjE5NXMtMzEuNDYtNS40Ni0zMS40Ni0xMi4xOTVjMC02LjczNCAxNC4wODUtMTIuMTk0IDMxLjQ2LTEyLjE5NCIvPjxwYXRoIGZpbGw9IiM2MjFCMUMiIGQ9Ik0xODUuMjk1IDM1Ljk5OGwzNC44MzYgMTMuNzY2LTM0LjgwNiAxMy43NTMtLjAzLTI3LjUyIi8+PHBhdGggZmlsbD0iIzlBMjkyOCIgZD0iTTE0Ni43NTUgNTEuMjQzbDM4LjU0LTE1LjI0NS4wMyAyNy41MTktMy43NzkgMS40NzgtMzQuNzkxLTEzLjc1MiIvPjwvc3ZnPg==;" parent="1" vertex="1">
|
||||
<mxGeometry x="800" y="-169" width="79" height="79" as="geometry" />
|
||||
</mxCell>
|
||||
@ -477,7 +456,7 @@
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="7DCv9Lc5Xf6xtuzZQ5PP-6" style="edgeStyle=orthogonalEdgeStyle;shape=connector;curved=0;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=0;strokeColor=#d79b00;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=default;labelBackgroundColor=default;elbow=vertical;startSize=8;endArrow=none;endFill=0;endSize=8;flowAnimation=0;fillColor=#ffe6cc;startArrow=open;startFill=0;" edge="1" parent="1">
|
||||
<mxCell id="7DCv9Lc5Xf6xtuzZQ5PP-6" style="edgeStyle=orthogonalEdgeStyle;shape=connector;curved=0;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=0;strokeColor=#d79b00;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=default;labelBackgroundColor=default;elbow=vertical;startSize=8;endArrow=none;endFill=0;endSize=8;flowAnimation=0;fillColor=#ffe6cc;startArrow=open;startFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="390" y="-126.59" as="targetPoint" />
|
||||
<mxPoint x="610" y="-126.59" as="sourcePoint" />
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 558 KiB After Width: | Height: | Size: 541 KiB |
@ -45,7 +45,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
"firstName": "John",
|
||||
"lastName": "Do",
|
||||
"username": "admin",
|
||||
"passportNumber": "412900000000",
|
||||
"passportNumber": "412900000",
|
||||
"email": "admin@admin.com",
|
||||
"password": "Admin@12345",
|
||||
"confirmPassword": "Admin@12345"
|
||||
|
||||
@ -13,33 +13,40 @@ public static class JwtExtensions
|
||||
{
|
||||
var jwtOptions = services.GetOptions<JwtBearerOptions>("Jwt");
|
||||
|
||||
services.AddAuthentication(o =>
|
||||
{
|
||||
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddCookie(cfg => cfg.SlidingExpiration = true)
|
||||
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
|
||||
{
|
||||
options.Authority = jwtOptions.Authority;
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
services.AddAuthentication(
|
||||
o =>
|
||||
{
|
||||
ValidateAudience = false,
|
||||
ClockSkew = TimeSpan.FromSeconds(2) // For prevent add default value (5min) to life time token!
|
||||
};
|
||||
options.RequireHttpsMetadata = jwtOptions.RequireHttpsMetadata;
|
||||
options.MetadataAddress = jwtOptions.MetadataAddress;
|
||||
});
|
||||
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddCookie(cfg => cfg.SlidingExpiration = true)
|
||||
.AddJwtBearer(
|
||||
JwtBearerDefaults.AuthenticationScheme,
|
||||
options =>
|
||||
{
|
||||
options.Authority = jwtOptions.Authority;
|
||||
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateAudience = false,
|
||||
ClockSkew = TimeSpan.FromSeconds(2) // For prevent add default value (5min) to life time token!
|
||||
};
|
||||
|
||||
options.RequireHttpsMetadata = jwtOptions.RequireHttpsMetadata;
|
||||
options.MetadataAddress = jwtOptions.MetadataAddress;
|
||||
});
|
||||
|
||||
if (!string.IsNullOrEmpty(jwtOptions.Audience))
|
||||
{
|
||||
services.AddAuthorization(options =>
|
||||
options.AddPolicy(nameof(ApiScope), policy =>
|
||||
{
|
||||
policy.RequireAuthenticatedUser();
|
||||
policy.RequireClaim("scope", jwtOptions.Audience);
|
||||
})
|
||||
);
|
||||
services.AddAuthorization(
|
||||
options =>
|
||||
options.AddPolicy(
|
||||
nameof(ApiScope),
|
||||
policy =>
|
||||
{
|
||||
policy.RequireAuthenticatedUser();
|
||||
policy.RequireClaim("scope", jwtOptions.Audience);
|
||||
}));
|
||||
}
|
||||
|
||||
return services;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user