From fafb665cd283e336b725fd7be04e43d683c03b10 Mon Sep 17 00:00:00 2001 From: cuqmbr Date: Wed, 28 May 2025 12:33:49 +0300 Subject: [PATCH] rewrite identity system --- TravelGuide.sln | 6 - .../AddAddress/AddAddressCommandAuthorizer.cs | 4 +- .../AddAddress/AddAddressCommandHandler.cs | 2 +- .../AddAddress/AddAddressCommandValidator.cs | 2 +- .../DeleteAddressCommandAuthorizer.cs | 4 +- .../DeleteAddressCommandHandler.cs | 2 +- .../UpdateAddressCommandAuthorizer.cs | 4 +- .../UpdateAddressCommandHandler.cs | 2 +- .../UpdateAddressCommandValidator.cs | 2 +- .../GetAddress/GetAddressQueryAuthorizer.cs | 4 +- .../GetAddress/GetAddressQueryHandler.cs | 2 +- .../GetAddressesPageQueryAuthorizer.cs | 4 +- .../GetAddressesPageQueryHandler.cs | 2 +- .../GetAddressesPageQueryValidator.cs | 2 +- .../AddAircraftCommandAuthorizer.cs | 4 +- .../AddAircraft/AddAircraftCommandHandler.cs | 2 +- .../AddAircraftCommandValidator.cs | 2 +- .../DeleteAircraftCommandAuthorizer.cs | 4 +- .../DeleteAircraftCommandHandler.cs | 2 +- .../UpdateAircraftCommandAuthorizer.cs | 4 +- .../UpdateAircraftCommandHandler.cs | 2 +- .../UpdateAircraftCommandValidator.cs | 2 +- .../GetAircraft/GetAircraftQueryAuthorizer.cs | 4 +- .../GetAircraft/GetAircraftQueryHandler.cs | 2 +- .../GetAircraftsPageQueryAuthorizer.cs | 4 +- .../GetAircraftsPageQueryHandler.cs | 2 +- .../GetAircraftsPageQueryValidator.cs | 2 +- src/Application/Application.csproj | 3 + .../Commands/Register/RegisterCommand.cs | 2 + .../Register/RegisterCommandAuthorizer.cs | 13 + .../Register/RegisterCommandHandler.cs | 78 +- .../Register/RegisterCommandValidator.cs | 55 +- .../RenewAccessTokenCommandAuthorizer.cs | 23 +- .../RenewAccessTokenCommandHandler.cs | 85 +- .../RenewAccessTokenWithCookieCommand.cs | 6 - ...wAccessTokenWithCookieCommandAuthorizer.cs | 26 - ...enewAccessTokenWithCookieCommandHandler.cs | 28 - ...ewAccessTokenWithCookieCommandValidator.cs | 10 - .../RevokeRefreshTokenCommandAuthorizer.cs | 13 +- .../RevokeRefreshTokenCommandHandler.cs | 32 +- .../RevokeRefreshTokenWithCookieCommand.cs | 6 - ...RefreshTokenWithCookieCommandAuthorizer.cs | 26 - ...okeRefreshTokenWithCookieCommandHandler.cs | 28 - ...eRefreshTokenWithCookieCommandValidator.cs | 10 - .../Queries/Login/LoginQuery.cs | 2 +- .../Queries/Login/LoginQueryAuthorizer.cs | 12 + .../Queries/Login/LoginQueryHandler.cs | 131 +- .../Queries/Login/LoginQueryValidator.cs | 11 +- .../AddBus/AddBusCommandAuthorizer.cs | 4 +- .../Commands/AddBus/AddBusCommandHandler.cs | 2 +- .../Commands/AddBus/AddBusCommandValidator.cs | 2 +- .../DeleteBus/DeleteBusCommandAuthorizer.cs | 4 +- .../DeleteBus/DeleteBusCommandHandler.cs | 2 +- .../UpdateBus/UpdateBusCommandAuthorizer.cs | 4 +- .../UpdateBus/UpdateBusCommandHandler.cs | 2 +- .../UpdateBus/UpdateBusCommandValidator.cs | 2 +- .../Queries/GetBus/GetBusQueryAuthorizer.cs | 4 +- .../Queries/GetBus/GetBusQueryHandler.cs | 2 +- .../GetBusesPageQueryAuthorizer.cs | 4 +- .../GetBusesPage/GetBusesPageQueryHandler.cs | 2 +- .../GetBusesPageQueryValidator.cs | 2 +- .../AddCity/AddCityCommandAuthorizer.cs | 4 +- .../Commands/AddCity/AddCityCommandHandler.cs | 2 +- .../AddCity/AddCityCommandValidator.cs | 2 +- .../DeleteCity/DeleteCityCommandAuthorizer.cs | 4 +- .../DeleteCity/DeleteCityCommandHandler.cs | 2 +- .../UpdateCity/UpdateCityCommandAuthorizer.cs | 4 +- .../UpdateCity/UpdateCityCommandHandler.cs | 2 +- .../UpdateCity/UpdateCityCommandValidator.cs | 2 +- .../GetCitiesPageQueryAuthorizer.cs | 4 +- .../GetCitiesPageQueryHandler.cs | 2 +- .../GetCitiesPageQueryValidator.cs | 2 +- .../Queries/GetCity/GetCityQueryAuthorizer.cs | 4 +- .../Queries/GetCity/GetCityQueryHandler.cs | 2 +- .../Authorization/MustBeInRolesRequirement.cs | 2 +- .../FluentValidation/CustomValidators.cs | 8 + .../Services/AuthenticationService.cs | 18 - .../Interfaces/Services/SessionUserService.cs | 22 - .../Resolvers/DateTimeOffsetResolver.cs | 2 +- .../Repositories/AccountRepository.cs | 5 + .../Repositories/AccountRoleRepository.cs | 5 + .../Repositories/AddressRepository.cs | 3 +- .../Repositories/AircraftRepository.cs | 3 +- .../Repositories/BaseRepository.cs | 3 +- .../Persistence/Repositories/BusRepository.cs | 3 +- .../Repositories/CityRepository.cs | 3 +- .../Repositories/CompanyRepository.cs | 2 +- .../Repositories/CountryRepository.cs | 3 +- .../Repositories/EmployeeRepository.cs | 2 +- .../Repositories/RefreshTokenRepository.cs | 5 + .../Repositories/RegionRepository.cs | 3 +- .../Repositories/RoleRepository.cs | 5 + .../RouteAddressDetailRepository.cs | 2 +- .../Repositories/RouteAddressRepository.cs | 3 +- .../Repositories/RouteRepository.cs | 3 +- .../Repositories/TicketGroupRepository.cs | 2 +- .../Repositories/TicketRepository.cs | 2 +- .../Repositories/TrainRepository.cs | 3 +- .../VehicleEnrollmentEmployeeRepository.cs | 3 +- .../VehicleEnrollmentRepository.cs | 3 +- .../Repositories/VehicleRepository.cs | 3 +- .../Persistence/UnitOfWork.cs | 16 +- .../Services/CurrencyConverterService.cs | 2 +- .../Services/LiqPayPaymentService.cs | 2 +- .../Common/Services/PasswordHasherService.cs | 10 + .../Services/SessionCurrencyService.cs | 2 +- .../Services/SessionTimeZoneService.cs | 2 +- .../Common/Services/SessionUserService.cs | 22 + .../Services/SessoionCultureService.cs | 2 +- .../AddCompany/AddCompanyCommandAuthorizer.cs | 4 +- .../AddCompany/AddCompanyCommandHandler.cs | 2 +- .../AddCompany/AddCompanyCommandValidator.cs | 2 +- .../DeleteCompanyCommandAuthorizer.cs | 4 +- .../DeleteCompanyCommandHandler.cs | 2 +- .../UpdateCompanyCommandAuthorizer.cs | 4 +- .../UpdateCompanyCommandHandler.cs | 2 +- .../UpdateCompanyCommandValidator.cs | 2 +- .../GetCompaniesPageQueryAuthorizer.cs | 4 +- .../GetCompaniesPageQueryHandler.cs | 2 +- .../GetCompaniesPageQueryValidator.cs | 2 +- .../GetCompany/GetCompanyQueryAuthorizer.cs | 4 +- .../GetCompany/GetCompanyQueryHandler.cs | 2 +- src/Application/ConfigurationOptions.cs | 15 + .../AddCountry/AddCountryCommandAuthorizer.cs | 4 +- .../AddCountry/AddCountryCommandHandler.cs | 2 +- .../AddCountry/AddCountryCommandValidator.cs | 2 +- .../DeleteCountryCommandAuthorizer.cs | 4 +- .../DeleteCountryCommandHandler.cs | 2 +- .../UpdateCountryCommandAuthorizer.cs | 4 +- .../UpdateCountryCommandHandler.cs | 2 +- .../UpdateCountryCommandValidator.cs | 2 +- .../GetCountriesPageQueryAuthorizer.cs | 4 +- .../GetCountriesPageQueryHandler.cs | 2 +- .../GetCountriesPageQueryValidator.cs | 2 +- .../GetCountry/GetCountryQueryAuthorizer.cs | 4 +- .../GetCountry/GetCountryQueryHandler.cs | 2 +- .../AddEmployeeCommandAuthorizer.cs | 4 +- .../AddEmployee/AddEmployeeCommandHandler.cs | 2 +- .../AddEmployeeCommandValidator.cs | 2 +- .../DeleteEmployeeCommandAuthorizer.cs | 4 +- .../DeleteEmployeeCommandHandler.cs | 2 +- .../UpdateEmployeeCommandAuthorizer.cs | 4 +- .../UpdateEmployeeCommandHandler.cs | 2 +- .../UpdateEmployeeCommandValidator.cs | 2 +- .../GetEmployee/GetEmployeeQueryAuthorizer.cs | 4 +- .../GetEmployee/GetEmployeeQueryHandler.cs | 2 +- .../GetEmployeesPageQueryAuthorizer.cs | 4 +- .../GetEmployeesPageQueryHandler.cs | 2 +- .../GetEmployeesPageQueryValidator.cs | 2 +- .../Identity/Accounts/AccountDto.cs | 27 + .../Commands/AddAccount/AddAccountCommand.cs | 13 + .../AddAccount/AddAccountCommandAuthorizer.cs | 31 + .../AddAccount/AddAccountCommandHandler.cs | 77 + .../AddAccount/AddAccountCommandValidator.cs | 36 + .../ViewModels/AddAccountViewModel.cs | 10 + .../Queries/GetRolesPage/GetRolesPageQuery.cs | 13 + .../GetRolesPageQueryAuthorizer.cs | 31 + .../GetRolesPage/GetRolesPageQueryHandler.cs | 25 + .../GetRolesPageQueryValidator.cs | 43 + .../GetPaymentLinkCommandAuthorizer.cs | 4 +- .../GetPaymentLinkCommandHandler.cs | 4 +- .../GetPaymentLinkCommandValidator.cs | 2 +- .../ProcessCallbackCommandHandler.cs | 4 +- .../ProcessCallbackCommandValidator.cs | 2 +- .../AddRegion/AddRegionCommandAuthorizer.cs | 4 +- .../AddRegion/AddRegionCommandHandler.cs | 2 +- .../AddRegion/AddRegionCommandValidator.cs | 2 +- .../DeleteRegionCommandAuthorizer.cs | 4 +- .../DeleteRegionCommandHandler.cs | 2 +- .../UpdateRegionCommandAuthorizer.cs | 4 +- .../UpdateRegionCommandHandler.cs | 2 +- .../UpdateRegionCommandValidator.cs | 2 +- .../GetRegion/GetRegionQueryAuthorizer.cs | 4 +- .../GetRegion/GetRegionQueryHandler.cs | 2 +- .../GetRegionsPageQueryAuthorizer.cs | 4 +- .../GetRegionsPageQueryHandler.cs | 2 +- .../GetRegionsPageQueryValidator.cs | 2 +- .../Resources/Localization/en-US.json | 6 +- .../AddRoute/AddRouteCommandAuthorizer.cs | 4 +- .../AddRoute/AddRouteCommandHandler.cs | 2 +- .../AddRoute/AddRouteCommandValidator.cs | 2 +- .../DeleteRouteCommandAuthorizer.cs | 4 +- .../DeleteRoute/DeleteRouteCommandHandler.cs | 2 +- .../UpdateRouteCommandAuthorizer.cs | 4 +- .../UpdateRoute/UpdateRouteCommandHandler.cs | 2 +- .../UpdateRouteCommandValidator.cs | 2 +- .../GetRoute/GetRouteQueryAuthorizer.cs | 4 +- .../Queries/GetRoute/GetRouteQueryHandler.cs | 2 +- .../GetRoutesPageQueryAuthorizer.cs | 4 +- .../GetRoutesPageQueryHandler.cs | 2 +- .../GetRoutesPageQueryValidator.cs | 2 +- .../AddTicketGroupCommandAuthorizer.cs | 4 +- .../AddTicketGroupCommandHandler.cs | 4 +- .../AddTicketGroupCommandValidator.cs | 2 +- ...veOldReservedTicketGroupsCommandHandler.cs | 2 +- .../AddTrain/AddTrainCommandAuthorizer.cs | 4 +- .../AddTrain/AddTrainCommandHandler.cs | 2 +- .../AddTrain/AddTrainCommandValidator.cs | 2 +- .../DeleteTrainCommandAuthorizer.cs | 4 +- .../DeleteTrain/DeleteTrainCommandHandler.cs | 2 +- .../UpdateTrainCommandAuthorizer.cs | 4 +- .../UpdateTrain/UpdateTrainCommandHandler.cs | 2 +- .../UpdateTrainCommandValidator.cs | 2 +- .../GetTrain/GetTrainQueryAuthorizer.cs | 4 +- .../Queries/GetTrain/GetTrainQueryHandler.cs | 2 +- .../GetTrainsPageQueryAuthorizer.cs | 4 +- .../GetTrainsPageQueryHandler.cs | 2 +- .../GetTrainsPageQueryValidator.cs | 2 +- .../SearchAll/SearchAllQueryAuthorizer.cs | 4 +- .../SearchAll/SearchAllQueryHandler.cs | 4 +- .../SearchAll/SearchAllQueryValidator.cs | 2 +- .../SearchShortestQueryAuthorizer.cs | 4 +- .../SearchShortestQueryHandler.cs | 4 +- .../SearchShortestQueryValidator.cs | 2 +- .../AddVehicleEnrollmentCommandAuthorizer.cs | 4 +- .../AddVehicleEnrollmentCommandHandler.cs | 2 +- .../AddVehicleEnrollmentCommandValidator.cs | 2 +- ...eleteVehicleEnrollmentCommandAuthorizer.cs | 4 +- .../DeleteVehicleEnrollmentCommandHandler.cs | 2 +- ...pdateVehicleEnrollmentCommandAuthorizer.cs | 4 +- .../UpdateVehicleEnrollmentCommandHandler.cs | 2 +- ...UpdateVehicleEnrollmentCommandValidator.cs | 2 +- .../GetVehicleEnrollmentQueryAuthorizer.cs | 4 +- .../GetVehicleEnrollmentQueryHandler.cs | 4 +- ...etVehicleEnrollmentsPageQueryAuthorizer.cs | 4 +- .../GetVehicleEnrollmentsPageQueryHandler.cs | 4 +- ...GetVehicleEnrollmentsPageQueryValidator.cs | 2 +- src/Application/packages.lock.json | 67 + .../Application/Configuration.cs | 47 +- .../Configuration/Configuration.cs | 6 - src/Configuration/Identity/Configuration.cs | 99 -- .../Infrastructure/Configuration.cs | 7 +- .../Persistence/Configuration.cs | 9 +- src/Configuration/packages.lock.json | 89 +- src/Domain/Entities/Account.cs | 16 + src/Domain/Entities/AccountRole.cs | 12 + src/Domain/Entities/RefreshToken.cs | 20 + src/Domain/Entities/Role.cs | 10 + .../Models => Domain/Enums}/IdentityRole.cs | 16 +- .../Controllers/AuthenticationController.cs | 43 - src/HttpApi/Controllers/IdentityController.cs | 242 +++ src/HttpApi/Controllers/TestsController.cs | 4 +- .../ThreadCultureSetterMiddleware.cs | 2 +- src/HttpApi/Program.cs | 7 +- .../Services/AspNetSessionCultureService.cs | 2 +- .../Services/AspNetSessionCurrencyService.cs | 2 +- .../Services/AspNetSessionTimeZoneService.cs | 2 +- .../Services/AspNetSessionUserService.cs | 17 +- src/HttpApi/appsettings.Development.json | 20 +- src/HttpApi/appsettings.json | 20 +- src/HttpApi/packages.lock.json | 90 +- src/Identity/ConfigurationOptions.cs | 34 - .../UnSupportedDatastoreException.cs | 11 - src/Identity/Identity.csproj | 27 - src/Identity/IdentitySeeder.cs | 85 -- src/Identity/Models/IdentityRole.cs | 6 - src/Identity/Models/IdentityUser.cs | 8 - src/Identity/Models/RefreshToken.cs | 23 - .../IdentityRoleClaimConfiguration.cs | 30 - .../IdentityRoleConfiguration.cs | 34 - .../IdentityUserClaimConfiguration.cs | 30 - .../IdentityUserConfiguration.cs | 128 -- .../IdentityUserLoginConfiguration.cs | 30 - .../IdentityUserRoleConfiguration.cs | 22 - .../IdentityUserTokenConfiguration.cs | 30 - ...250423194315_Initial_migration.Designer.cs | 355 ----- .../20250423194315_Initial_migration.cs | 281 ---- ...ostgreSqlIdentityDbContextModelSnapshot.cs | 352 ----- .../PostgreSql/PostgreSqlIdentityDbContext.cs | 35 - .../PostgreSql/PostgreSqlInitializer.cs | 28 - .../Services/JwtAuthenticationService.cs | 210 --- src/Identity/packages.lock.json | 612 -------- .../ExchangeApiCurrencyConverterService.cs | 2 +- .../Services/LiqPayPaymentService.cs | 2 +- .../Services/Pbkdf2PasswordHasherService.cs | 32 + src/Infrastructure/packages.lock.json | 67 + src/Persistence/DbSeeder.cs | 99 +- src/Persistence/InMemory/InMemoryDbContext.cs | 6 + .../InMemory/InMemoryUnitOfWork.cs | 18 +- .../Repositories/InMemoryAccountRepository.cs | 11 + .../InMemoryAccountRoleRepository.cs | 11 + .../Repositories/InMemoryAddressRepository.cs | 2 +- .../InMemoryAircraftRepository.cs | 2 +- .../Repositories/InMemoryBaseRepository.cs | 2 +- .../Repositories/InMemoryBusRepository.cs | 2 +- .../Repositories/InMemoryCityRepository.cs | 2 +- .../Repositories/InMemoryCompanyRepository.cs | 2 +- .../Repositories/InMemoryCountryRepository.cs | 2 +- .../InMemoryEmployeeRepository.cs | 2 +- .../InMemoryRefreshTokenRepository.cs | 11 + .../Repositories/InMemoryRegionRepository.cs | 2 +- .../Repositories/InMemoryRoleRepository.cs | 11 + .../InMemoryRouteAddressDetailRepository.cs | 2 +- .../InMemoryRouteAddressRepository.cs | 2 +- .../Repositories/InMemoryRouteRepository.cs | 2 +- .../InMemoryTicketGroupRepository.cs | 2 +- .../Repositories/InMemoryTicketRepository.cs | 2 +- .../Repositories/InMemoryTrainRepository.cs | 2 +- ...moryVehicleEnrollmentEmployeeRepository.cs | 2 +- .../InMemoryVehicleEnrollmentRepository.cs | 2 +- .../Repositories/InMemoryVehicleRepository.cs | 2 +- .../Configurations/AccountConfiguration.cs | 48 + .../AccountRoleConfiguration.cs | 64 + .../Configurations/BaseConfiguration.cs | 2 - .../RefreshTokenConfiguration.cs | 67 + .../Configurations/RoleConfiguration.cs | 32 + ...d_Account_Role_and_AccountRole.Designer.cs | 1294 +++++++++++++++++ ...083243_Add_Account_Role_and_AccountRole.cs | 175 +++ .../PostgreSqlDbContextModelSnapshot.cs | 211 +++ .../PostgreSql/PostgreSqlDbContext.cs | 6 + .../PostgreSql/PostgreSqlUnitOfWork.cs | 18 +- .../PostgreSqlAccountRepository.cs | 11 + .../PostgreSqlAccountRoleRepository.cs | 11 + .../PostgreSqlAddressRepository.cs | 2 +- .../PostgreSqlAircraftRepository.cs | 2 +- .../Repositories/PostgreSqlBaseRepository.cs | 2 +- .../Repositories/PostgreSqlBusRepository.cs | 2 +- .../Repositories/PostgreSqlCityRepository.cs | 2 +- .../PostgreSqlCompanyRepository.cs | 2 +- .../PostgreSqlCountryRepository.cs | 2 +- .../PostgreSqlEmployeeRepository.cs | 2 +- .../PostgreSqlRefreshTokenRepository.cs | 11 + .../PostgreSqlRegionRepository.cs | 2 +- .../Repositories/PostgreSqlRoleRepository.cs | 11 + .../PostgreSqlRouteAddressDetailRepository.cs | 2 +- .../PostgreSqlRouteAddressRepository.cs | 2 +- .../Repositories/PostgreSqlRouteRepository.cs | 2 +- .../PostgreSqlTicketGroupRepository.cs | 2 +- .../PostgreSqlTicketRepository.cs | 2 +- .../Repositories/PostgreSqlTrainRepository.cs | 2 +- ...eSqlVehicleEnrollmentEmployeeRepository.cs | 2 +- .../PostgreSqlVehicleEnrollmentRepository.cs | 2 +- .../PostgreSqlVehicleRepository.cs | 2 +- .../TypeConverters/RoleConverter.cs | 13 + src/Persistence/packages.lock.json | 67 + tst/Application.IntegrationTests/BaseTest.cs | 9 +- .../CitiesTests.cs | 3 +- .../CountriesTests.cs | 3 +- .../RegionsTests.cs | 3 +- .../packages.lock.json | 90 +- 340 files changed, 3945 insertions(+), 3326 deletions(-) create mode 100644 src/Application/Authentication/Commands/Register/RegisterCommandAuthorizer.cs delete mode 100644 src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommand.cs delete mode 100644 src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandAuthorizer.cs delete mode 100644 src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandHandler.cs delete mode 100644 src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandValidator.cs delete mode 100644 src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommand.cs delete mode 100644 src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandAuthorizer.cs delete mode 100644 src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandHandler.cs delete mode 100644 src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandValidator.cs create mode 100644 src/Application/Authentication/Queries/Login/LoginQueryAuthorizer.cs delete mode 100644 src/Application/Common/Interfaces/Services/AuthenticationService.cs delete mode 100644 src/Application/Common/Interfaces/Services/SessionUserService.cs create mode 100644 src/Application/Common/Persistence/Repositories/AccountRepository.cs create mode 100644 src/Application/Common/Persistence/Repositories/AccountRoleRepository.cs rename src/Application/Common/{Interfaces => }/Persistence/Repositories/AddressRepository.cs (54%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/AircraftRepository.cs (55%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/BaseRepository.cs (94%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/BusRepository.cs (52%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/CityRepository.cs (53%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/CompanyRepository.cs (70%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/CountryRepository.cs (54%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/EmployeeRepository.cs (70%) create mode 100644 src/Application/Common/Persistence/Repositories/RefreshTokenRepository.cs rename src/Application/Common/{Interfaces => }/Persistence/Repositories/RegionRepository.cs (54%) create mode 100644 src/Application/Common/Persistence/Repositories/RoleRepository.cs rename src/Application/Common/{Interfaces => }/Persistence/Repositories/RouteAddressDetailRepository.cs (73%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/RouteAddressRepository.cs (57%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/RouteRepository.cs (53%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/TicketGroupRepository.cs (71%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/TicketRepository.cs (70%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/TrainRepository.cs (53%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs (62%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/VehicleEnrollmentRepository.cs (59%) rename src/Application/Common/{Interfaces => }/Persistence/Repositories/VehicleRepository.cs (54%) rename src/Application/Common/{Interfaces => }/Persistence/UnitOfWork.cs (73%) rename src/Application/Common/{Interfaces => }/Services/CurrencyConverterService.cs (83%) rename src/Application/Common/{Interfaces => }/Services/LiqPayPaymentService.cs (82%) create mode 100644 src/Application/Common/Services/PasswordHasherService.cs rename src/Application/Common/{Interfaces => }/Services/SessionCurrencyService.cs (64%) rename src/Application/Common/{Interfaces => }/Services/SessionTimeZoneService.cs (55%) create mode 100644 src/Application/Common/Services/SessionUserService.cs rename src/Application/Common/{Interfaces => }/Services/SessoionCultureService.cs (62%) create mode 100644 src/Application/Identity/Accounts/AccountDto.cs create mode 100644 src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommand.cs create mode 100644 src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandAuthorizer.cs create mode 100644 src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandHandler.cs create mode 100644 src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandValidator.cs create mode 100644 src/Application/Identity/Accounts/ViewModels/AddAccountViewModel.cs create mode 100644 src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQuery.cs create mode 100644 src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryAuthorizer.cs create mode 100644 src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryHandler.cs create mode 100644 src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryValidator.cs delete mode 100644 src/Configuration/Identity/Configuration.cs create mode 100644 src/Domain/Entities/Account.cs create mode 100644 src/Domain/Entities/AccountRole.cs create mode 100644 src/Domain/Entities/RefreshToken.cs create mode 100644 src/Domain/Entities/Role.cs rename src/{Application/Common/Models => Domain/Enums}/IdentityRole.cs (52%) create mode 100644 src/HttpApi/Controllers/IdentityController.cs delete mode 100644 src/Identity/ConfigurationOptions.cs delete mode 100644 src/Identity/Exceptions/UnSupportedDatastoreException.cs delete mode 100644 src/Identity/Identity.csproj delete mode 100644 src/Identity/IdentitySeeder.cs delete mode 100644 src/Identity/Models/IdentityRole.cs delete mode 100644 src/Identity/Models/IdentityUser.cs delete mode 100644 src/Identity/Models/RefreshToken.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleClaimConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityUserClaimConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityUserConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityUserLoginConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityUserRoleConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Configurations/IdentityUserTokenConfiguration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.Designer.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.cs delete mode 100644 src/Identity/Persistence/PostgreSql/Migrations/PostgreSqlIdentityDbContextModelSnapshot.cs delete mode 100644 src/Identity/Persistence/PostgreSql/PostgreSqlIdentityDbContext.cs delete mode 100644 src/Identity/Persistence/PostgreSql/PostgreSqlInitializer.cs delete mode 100644 src/Identity/Services/JwtAuthenticationService.cs delete mode 100644 src/Identity/packages.lock.json create mode 100644 src/Infrastructure/Services/Pbkdf2PasswordHasherService.cs create mode 100644 src/Persistence/InMemory/Repositories/InMemoryAccountRepository.cs create mode 100644 src/Persistence/InMemory/Repositories/InMemoryAccountRoleRepository.cs create mode 100644 src/Persistence/InMemory/Repositories/InMemoryRefreshTokenRepository.cs create mode 100644 src/Persistence/InMemory/Repositories/InMemoryRoleRepository.cs create mode 100644 src/Persistence/PostgreSql/Configurations/AccountConfiguration.cs create mode 100644 src/Persistence/PostgreSql/Configurations/AccountRoleConfiguration.cs create mode 100644 src/Persistence/PostgreSql/Configurations/RefreshTokenConfiguration.cs create mode 100644 src/Persistence/PostgreSql/Configurations/RoleConfiguration.cs create mode 100644 src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.Designer.cs create mode 100644 src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.cs create mode 100644 src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRepository.cs create mode 100644 src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRoleRepository.cs create mode 100644 src/Persistence/PostgreSql/Repositories/PostgreSqlRefreshTokenRepository.cs create mode 100644 src/Persistence/PostgreSql/Repositories/PostgreSqlRoleRepository.cs create mode 100644 src/Persistence/TypeConverters/RoleConverter.cs diff --git a/TravelGuide.sln b/TravelGuide.sln index f012d1c..75d3e9c 100644 --- a/TravelGuide.sln +++ b/TravelGuide.sln @@ -13,8 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "src\Infra EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpApi", "src\HttpApi\HttpApi.csproj", "{4431B3CB-A5F2-447A-8BC7-9DC3DA9E6A6D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity", "src\Identity\Identity.csproj", "{AD3CC01F-0331-44DC-B58E-CCE6ADCB56B6}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Configuration", "src\Configuration\Configuration.csproj", "{1DCFA4EE-A545-42FE-A3BC-A606D2961298}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application.IntegrationTests", "tst\Application.IntegrationTests\Application.IntegrationTests.csproj", "{B52B8651-10B8-488D-8ACF-9C4499F8A723}" @@ -48,10 +46,6 @@ Global {4431B3CB-A5F2-447A-8BC7-9DC3DA9E6A6D}.Debug|Any CPU.Build.0 = Debug|Any CPU {4431B3CB-A5F2-447A-8BC7-9DC3DA9E6A6D}.Release|Any CPU.ActiveCfg = Release|Any CPU {4431B3CB-A5F2-447A-8BC7-9DC3DA9E6A6D}.Release|Any CPU.Build.0 = Release|Any CPU - {AD3CC01F-0331-44DC-B58E-CCE6ADCB56B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD3CC01F-0331-44DC-B58E-CCE6ADCB56B6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD3CC01F-0331-44DC-B58E-CCE6ADCB56B6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD3CC01F-0331-44DC-B58E-CCE6ADCB56B6}.Release|Any CPU.Build.0 = Release|Any CPU {1DCFA4EE-A545-42FE-A3BC-A606D2961298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1DCFA4EE-A545-42FE-A3BC-A606D2961298}.Debug|Any CPU.Build.0 = Debug|Any CPU {1DCFA4EE-A545-42FE-A3BC-A606D2961298}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/Application/Addresses/Commands/AddAddress/AddAddressCommandAuthorizer.cs b/src/Application/Addresses/Commands/AddAddress/AddAddressCommandAuthorizer.cs index eb8ae61..6c88c27 100644 --- a/src/Application/Addresses/Commands/AddAddress/AddAddressCommandAuthorizer.cs +++ b/src/Application/Addresses/Commands/AddAddress/AddAddressCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Addresses.Commands.AddAddress; diff --git a/src/Application/Addresses/Commands/AddAddress/AddAddressCommandHandler.cs b/src/Application/Addresses/Commands/AddAddress/AddAddressCommandHandler.cs index 5aaf4f9..189c8d0 100644 --- a/src/Application/Addresses/Commands/AddAddress/AddAddressCommandHandler.cs +++ b/src/Application/Addresses/Commands/AddAddress/AddAddressCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Addresses/Commands/AddAddress/AddAddressCommandValidator.cs b/src/Application/Addresses/Commands/AddAddress/AddAddressCommandValidator.cs index 59adff1..e1c38c8 100644 --- a/src/Application/Addresses/Commands/AddAddress/AddAddressCommandValidator.cs +++ b/src/Application/Addresses/Commands/AddAddress/AddAddressCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandAuthorizer.cs b/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandAuthorizer.cs index e8e04ca..7b5bb31 100644 --- a/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandAuthorizer.cs +++ b/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Addresses.Commands.DeleteAddress; diff --git a/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandHandler.cs b/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandHandler.cs index 428b7fa..fc6ea4c 100644 --- a/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandHandler.cs +++ b/src/Application/Addresses/Commands/DeleteAddress/DeleteAddressCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Addresses.Commands.DeleteAddress; diff --git a/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandAuthorizer.cs b/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandAuthorizer.cs index 1063a38..80860d1 100644 --- a/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandAuthorizer.cs +++ b/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Addresses.Commands.UpdateAddress; diff --git a/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandHandler.cs b/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandHandler.cs index eba7089..17ab45f 100644 --- a/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandHandler.cs +++ b/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandValidator.cs b/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandValidator.cs index ceae48d..adf0322 100644 --- a/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandValidator.cs +++ b/src/Application/Addresses/Commands/UpdateAddress/UpdateAddressCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Addresses/Queries/GetAddress/GetAddressQueryAuthorizer.cs b/src/Application/Addresses/Queries/GetAddress/GetAddressQueryAuthorizer.cs index 545dd25..d6cfa6c 100644 --- a/src/Application/Addresses/Queries/GetAddress/GetAddressQueryAuthorizer.cs +++ b/src/Application/Addresses/Queries/GetAddress/GetAddressQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Addresses.Queries.GetAddress; diff --git a/src/Application/Addresses/Queries/GetAddress/GetAddressQueryHandler.cs b/src/Application/Addresses/Queries/GetAddress/GetAddressQueryHandler.cs index f0f5a86..730b248 100644 --- a/src/Application/Addresses/Queries/GetAddress/GetAddressQueryHandler.cs +++ b/src/Application/Addresses/Queries/GetAddress/GetAddressQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryAuthorizer.cs b/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryAuthorizer.cs index b8d21da..6521dde 100644 --- a/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryAuthorizer.cs +++ b/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Addresses.Queries.GetAddressesPage; diff --git a/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryHandler.cs b/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryHandler.cs index 9b4cd25..4fcce04 100644 --- a/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryHandler.cs +++ b/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryValidator.cs b/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryValidator.cs index b1eb480..ce7adfe 100644 --- a/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryValidator.cs +++ b/src/Application/Addresses/Queries/GetAddressesPage/GetAddressesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandAuthorizer.cs b/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandAuthorizer.cs index 8c98851..46621fb 100644 --- a/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandAuthorizer.cs +++ b/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Aircrafts.Commands.AddAircraft; diff --git a/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandHandler.cs b/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandHandler.cs index a210946..fdb46dd 100644 --- a/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandHandler.cs +++ b/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandValidator.cs b/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandValidator.cs index b37dbac..15253f2 100644 --- a/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandValidator.cs +++ b/src/Application/Aircrafts/Commands/AddAircraft/AddAircraftCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandAuthorizer.cs b/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandAuthorizer.cs index 97f1463..1aeae2a 100644 --- a/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandAuthorizer.cs +++ b/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Aircrafts.Commands.DeleteAircraft; diff --git a/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandHandler.cs b/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandHandler.cs index 2188c03..1d3d867 100644 --- a/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandHandler.cs +++ b/src/Application/Aircrafts/Commands/DeleteAircraft/DeleteAircraftCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Aircrafts.Commands.DeleteAircraft; diff --git a/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandAuthorizer.cs b/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandAuthorizer.cs index c7036f5..b15c281 100644 --- a/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandAuthorizer.cs +++ b/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Aircrafts.Commands.UpdateAircraft; diff --git a/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandHandler.cs b/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandHandler.cs index d046aa9..9d16e38 100644 --- a/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandHandler.cs +++ b/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandValidator.cs b/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandValidator.cs index fb9dbc8..8060418 100644 --- a/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandValidator.cs +++ b/src/Application/Aircrafts/Commands/UpdateAircraft/UpdateAircraftCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryAuthorizer.cs b/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryAuthorizer.cs index 121cf58..a0cc4e2 100644 --- a/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryAuthorizer.cs +++ b/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Aircrafts.Queries.GetAircraft; diff --git a/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryHandler.cs b/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryHandler.cs index 01e7454..2977272 100644 --- a/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryHandler.cs +++ b/src/Application/Aircrafts/Queries/GetAircraft/GetAircraftQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryAuthorizer.cs b/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryAuthorizer.cs index 79a0546..41b94bb 100644 --- a/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryAuthorizer.cs +++ b/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Aircrafts.Queries.GetAircraftsPage; diff --git a/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryHandler.cs b/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryHandler.cs index e4a59c3..586d197 100644 --- a/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryHandler.cs +++ b/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryValidator.cs b/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryValidator.cs index 49c58b3..c564c40 100644 --- a/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryValidator.cs +++ b/src/Application/Aircrafts/Queries/GetAircraftsPage/GetAircraftsPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Application.csproj b/src/Application/Application.csproj index 0e77ba6..e6484da 100644 --- a/src/Application/Application.csproj +++ b/src/Application/Application.csproj @@ -16,7 +16,10 @@ + + + diff --git a/src/Application/Authentication/Commands/Register/RegisterCommand.cs b/src/Application/Authentication/Commands/Register/RegisterCommand.cs index 51edec4..41a1dbc 100644 --- a/src/Application/Authentication/Commands/Register/RegisterCommand.cs +++ b/src/Application/Authentication/Commands/Register/RegisterCommand.cs @@ -4,6 +4,8 @@ namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.Register; public record RegisterCommand : IRequest { + public string Username { get; set; } + public string Email { get; set; } public string Password { get; set; } diff --git a/src/Application/Authentication/Commands/Register/RegisterCommandAuthorizer.cs b/src/Application/Authentication/Commands/Register/RegisterCommandAuthorizer.cs new file mode 100644 index 0000000..d3fc40f --- /dev/null +++ b/src/Application/Authentication/Commands/Register/RegisterCommandAuthorizer.cs @@ -0,0 +1,13 @@ +using cuqmbr.TravelGuide.Application.Common.Authorization; +using MediatR.Behaviors.Authorization; + +namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.Register; + +public class RegisterCommandAuthorizer : + AbstractRequestAuthorizer +{ + public override void BuildPolicy(RegisterCommand request) + { + UseRequirement(new AllowAllRequirement()); + } +} diff --git a/src/Application/Authentication/Commands/Register/RegisterCommandHandler.cs b/src/Application/Authentication/Commands/Register/RegisterCommandHandler.cs index 99ca0f1..f84b3e5 100644 --- a/src/Application/Authentication/Commands/Register/RegisterCommandHandler.cs +++ b/src/Application/Authentication/Commands/Register/RegisterCommandHandler.cs @@ -1,21 +1,83 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using System.Security.Cryptography; +using System.Text; +using cuqmbr.TravelGuide.Application.Common.Exceptions; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Entities; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR; namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.Register; public class RegisterCommandHandler : IRequestHandler { - private readonly AuthenticationService _authenticationService; + private readonly IReadOnlyCollection DefaultRoles = + new IdentityRole[] { IdentityRole.User }; - public RegisterCommandHandler(AuthenticationService authenticationService) + private readonly UnitOfWork _unitOfWork; + private readonly PasswordHasherService _passwordHasher; + + public RegisterCommandHandler(UnitOfWork unitOfWork, + PasswordHasherService passwordHasher) { - _authenticationService = authenticationService; + _unitOfWork = unitOfWork; + _passwordHasher = passwordHasher; } - public async Task Handle( - RegisterCommand request, CancellationToken cancellationToken) + public async Task Handle(RegisterCommand request, + CancellationToken cancellationToken) { - await _authenticationService.RegisterAsync( - request.Email, request.Password, cancellationToken); + var datastoreAccount = await _unitOfWork.AccountRepository + .GetOneAsync( + e => + e.Email == request.Email || + e.Username == request.Username, + cancellationToken); + + if (datastoreAccount != null) + { + throw new RegistrationException( + "User with given email or username already registered."); + } + + + var defaultRoleIds = (await _unitOfWork.RoleRepository + .GetPageAsync( + r => DefaultRoles.Contains(r.Value), + 1, DefaultRoles.Count, cancellationToken)) + .Items + .Select(r => r.Id); + + + var password = Encoding.UTF8.GetBytes(request.Password); + + var salt = RandomNumberGenerator.GetBytes(128 / 8); + var hash = await _passwordHasher + .HashAsync(password, salt, cancellationToken); + + var saltBase64 = Convert.ToBase64String(salt); + var hashBase64 = Convert.ToBase64String(hash); + + + var newAccount = new Account + { + Username = request.Username, + Email = request.Email, + PasswordHash = hashBase64, + PasswordSalt = saltBase64, + AccountRoles = defaultRoleIds.Select(id => + new AccountRole() + { + RoleId = id + }) + .ToArray() + }; + + + await _unitOfWork.AccountRepository + .AddOneAsync(newAccount, cancellationToken); + + await _unitOfWork.SaveAsync(cancellationToken); + _unitOfWork.Dispose(); } } diff --git a/src/Application/Authentication/Commands/Register/RegisterCommandValidator.cs b/src/Application/Authentication/Commands/Register/RegisterCommandValidator.cs index 13afc23..f009284 100644 --- a/src/Application/Authentication/Commands/Register/RegisterCommandValidator.cs +++ b/src/Application/Authentication/Commands/Register/RegisterCommandValidator.cs @@ -1,31 +1,54 @@ +using cuqmbr.TravelGuide.Application.Common.FluentValidation; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; +using Microsoft.Extensions.Localization; namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.Register; public class RegisterCommandValidator : AbstractValidator { - public RegisterCommandValidator() + public RegisterCommandValidator( + IStringLocalizer localizer, + SessionCultureService cultureService) { + RuleFor(v => v.Username) + .NotEmpty() + .WithMessage(localizer["FluentValidation.NotEmpty"]) + .MinimumLength(1) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MinimumLength"], + 1)) + .MaximumLength(32) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MaximumLength"], + 32)) + .IsUsername() + .WithMessage(localizer["FluentValidation.IsUsername"]); + RuleFor(v => v.Email) .NotEmpty() - .WithMessage("Email address is required.") - .Matches(@"\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b") - .WithMessage("Email address is invalid."); + .WithMessage(localizer["FluentValidation.NotEmpty"]) + .IsEmail() + .WithMessage(localizer["FluentValidation.IsEmail"]); RuleFor(v => v.Password) .NotEmpty() - .WithMessage("Password is required.") + .WithMessage(localizer["FluentValidation.NotEmpty"]) .MinimumLength(8) - .WithMessage("Password must be at least 8 characters long.") - .MaximumLength(64) - .WithMessage("Password must be at most 64 characters long.") - .Matches(@"(?=.*[A-Z]).*") - .WithMessage("Password must contain at least one uppercase letter.") - .Matches(@"(?=.*[a-z]).*") - .WithMessage("Password must contain at least one lowercase letter.") - .Matches(@"(?=.*[\d]).*") - .WithMessage("Password must contain at least one digit.") - .Matches(@"(?=.*[!@#$%^&*()]).*") - .WithMessage("Password must contain at least one of the following special charactters: !@#$%^&*()."); + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MinimumLength"], + 8)) + .MaximumLength(256) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MaximumLength"], + 256)); } } diff --git a/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandAuthorizer.cs b/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandAuthorizer.cs index e5237e1..3d102fc 100644 --- a/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandAuthorizer.cs +++ b/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandAuthorizer.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +// using cuqmbr.TravelGuide.Application.Common.Services; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RenewAccessToken; @@ -7,18 +7,19 @@ namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RenewAccessToken public class RenewAccessTokenCommandAuthorizer : AbstractRequestAuthorizer { - private readonly SessionUserService _sessionUserService; - - public RenewAccessTokenCommandAuthorizer(SessionUserService currentUserService) - { - _sessionUserService = currentUserService; - } + // private readonly SessionUserService _sessionUserService; + // + // public RenewAccessTokenCommandAuthorizer(SessionUserService currentUserService) + // { + // _sessionUserService = currentUserService; + // } public override void BuildPolicy(RenewAccessTokenCommand request) { - UseRequirement(new MustBeAuthenticatedRequirement - { - IsAuthenticated = _sessionUserService.IsAuthenticated - }); + UseRequirement(new AllowAllRequirement()); + // UseRequirement(new MustBeAuthenticatedRequirement + // { + // IsAuthenticated = _sessionUserService.IsAuthenticated + // }); } } diff --git a/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs b/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs index 0cb9016..b6f47c4 100644 --- a/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs +++ b/src/Application/Authentication/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs @@ -1,22 +1,95 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using cuqmbr.TravelGuide.Application.Common.Exceptions; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Domain.Entities; using MediatR; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RenewAccessToken; public class RenewAccessTokenCommandHandler : IRequestHandler { - private readonly AuthenticationService _authenticationService; + private readonly UnitOfWork _unitOfWork; + private readonly JsonWebTokenConfigurationOptions _jwtConfiguration; - public RenewAccessTokenCommandHandler(AuthenticationService authenticationService) + public RenewAccessTokenCommandHandler(UnitOfWork unitOfWork, + IOptions configurationOptions) { - _authenticationService = authenticationService; + _unitOfWork = unitOfWork; + _jwtConfiguration = configurationOptions.Value.JsonWebToken; } public async Task Handle( RenewAccessTokenCommand request, CancellationToken cancellationToken) { - return await _authenticationService.RenewAccessTokenAsync( - request.RefreshToken, cancellationToken); + var refreshToken = (await _unitOfWork.RefreshTokenRepository + .GetOneAsync(e => e.Value == request.RefreshToken, + cancellationToken)); + + if (refreshToken == null) + { + throw new AuthenticationException($"Refresh token was not found."); + } + + if (!refreshToken.IsActive) + { + throw new AuthenticationException("Refresh token is inactive."); + } + + var account = await _unitOfWork.AccountRepository.GetOneAsync( + a => a.RefreshTokens.Contains(refreshToken), + a => a.AccountRoles, cancellationToken); + + var jwtSecurityToken = await CreateJwtAsync(account, cancellationToken); + var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); + + return new TokensModel(accessToken, refreshToken.Value); + } + + private async Task CreateJwtAsync( + Account account, CancellationToken cancellationToken) + { + var roleIds = account.AccountRoles.Select(ar => ar.RoleId); + + var roles = (await _unitOfWork.RoleRepository + .GetPageAsync( + r => roleIds.Contains(r.Id), + 1, roleIds.Count(), cancellationToken)) + .Items.Select(r => r.Value); + + var roleClaims = new List(); + foreach (var role in roles) + { + roleClaims.Add(new Claim("roles", role.Name)); + } + + var claims = new List() + { + new Claim(JwtRegisteredClaimNames.Sub, account.Guid.ToString()), + new Claim(JwtRegisteredClaimNames.Nickname, account.Username), + new Claim(JwtRegisteredClaimNames.Email, account.Email) + } + .Union(roleClaims); + + var expirationDateTimeUtc = DateTime.UtcNow.Add( + _jwtConfiguration.AccessTokenValidity); + + var symmetricSecurityKey = new SymmetricSecurityKey( + Encoding.UTF8.GetBytes(_jwtConfiguration.IssuerSigningKey)); + var signingCredentials = new SigningCredentials( + symmetricSecurityKey, SecurityAlgorithms.HmacSha256); + + var jwtSecurityToken = new JwtSecurityToken( + issuer: _jwtConfiguration.Issuer, + audience: _jwtConfiguration.Audience, + claims: claims, + expires: expirationDateTimeUtc, + signingCredentials: signingCredentials); + + return jwtSecurityToken; } } diff --git a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommand.cs b/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommand.cs deleted file mode 100644 index 93f2031..0000000 --- a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommand.cs +++ /dev/null @@ -1,6 +0,0 @@ -using MediatR; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RenewAccessTokenWithCookie; - -public record RenewAccessTokenWithCookieCommand : IRequest { } diff --git a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandAuthorizer.cs b/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandAuthorizer.cs deleted file mode 100644 index 481c916..0000000 --- a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandAuthorizer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using MediatR.Behaviors.Authorization; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RenewAccessTokenWithCookie; - -public class RenewAccessTokenWithCookieCommandAuthorizer : - AbstractRequestAuthorizer -{ - private readonly SessionUserService _sessionUserService; - - public RenewAccessTokenWithCookieCommandAuthorizer( - SessionUserService currentUserService) - { - _sessionUserService = currentUserService; - } - - public override void BuildPolicy(RenewAccessTokenWithCookieCommand request) - { - UseRequirement(new MustBeAuthenticatedRequirement - { - IsAuthenticated = _sessionUserService.IsAuthenticated - }); - } -} diff --git a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandHandler.cs b/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandHandler.cs deleted file mode 100644 index 797b289..0000000 --- a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandHandler.cs +++ /dev/null @@ -1,28 +0,0 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using MediatR; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RenewAccessTokenWithCookie; - -public class RenewAccessTokenWithCookieCommandHandler : - IRequestHandler -{ - private readonly AuthenticationService _authenticationService; - private readonly SessionUserService _sessionUserService; - - public RenewAccessTokenWithCookieCommandHandler( - AuthenticationService authenticationService, - SessionUserService sessionUserService) - { - _authenticationService = authenticationService; - _sessionUserService = sessionUserService; - } - - public async Task Handle( - RenewAccessTokenWithCookieCommand request, - CancellationToken cancellationToken) - { - return await _authenticationService.RenewAccessTokenAsync( - _sessionUserService.RefreshToken, cancellationToken); - } -} diff --git a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandValidator.cs b/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandValidator.cs deleted file mode 100644 index a49e1ef..0000000 --- a/src/Application/Authentication/Commands/RenewAccessTokenWithCookieWithCookie/RenewAccessTokenWithCookieCommandValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -using FluentValidation; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RenewAccessTokenWithCookie; - -public class RenewAccessTokenWithCookieCommandValidator : - AbstractValidator -{ - public RenewAccessTokenWithCookieCommandValidator() { } -} diff --git a/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandAuthorizer.cs b/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandAuthorizer.cs index d298795..c0fe1d9 100644 --- a/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandAuthorizer.cs +++ b/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandAuthorizer.cs @@ -1,5 +1,4 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RevokeRefreshToken; @@ -7,18 +6,8 @@ namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RevokeRefreshTok public class RevokeRefreshTokenCommandAuthorizer : AbstractRequestAuthorizer { - private readonly SessionUserService _sessionUserService; - - public RevokeRefreshTokenCommandAuthorizer(SessionUserService currentUserService) - { - _sessionUserService = currentUserService; - } - public override void BuildPolicy(RevokeRefreshTokenCommand request) { - UseRequirement(new MustBeAuthenticatedRequirement - { - IsAuthenticated = _sessionUserService.IsAuthenticated - }); + UseRequirement(new AllowAllRequirement()); } } diff --git a/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs b/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs index 1c0f322..2e9dee5 100644 --- a/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs +++ b/src/Application/Authentication/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs @@ -1,4 +1,5 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Exceptions; +using cuqmbr.TravelGuide.Application.Common.Persistence; using MediatR; namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RevokeRefreshToken; @@ -6,17 +7,36 @@ namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands.RevokeRefreshTok public class RevokeRefreshTokenCommandHandler : IRequestHandler { - private readonly AuthenticationService _authenticationService; + private readonly UnitOfWork _unitOfWork; - public RevokeRefreshTokenCommandHandler(AuthenticationService authenticationService) + public RevokeRefreshTokenCommandHandler(UnitOfWork unitOfWork) { - _authenticationService = authenticationService; + _unitOfWork = unitOfWork; } public async Task Handle( RevokeRefreshTokenCommand request, CancellationToken cancellationToken) { - await _authenticationService.RevokeRefreshTokenAsync( - request.RefreshToken, cancellationToken); + var refreshToken = (await _unitOfWork.RefreshTokenRepository + .GetOneAsync(e => e.Value == request.RefreshToken, + cancellationToken)); + + if (refreshToken == null) + { + throw new AuthenticationException("Invalid refreshToken"); + } + + if (!refreshToken.IsActive) + { + throw new AuthenticationException("RefreshToken already revoked"); + } + + refreshToken.RevocationTime = DateTimeOffset.UtcNow; + + await _unitOfWork.RefreshTokenRepository + .UpdateOneAsync(refreshToken, cancellationToken); + + await _unitOfWork.SaveAsync(cancellationToken); + _unitOfWork.Dispose(); } } diff --git a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommand.cs b/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommand.cs deleted file mode 100644 index f277cc8..0000000 --- a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommand.cs +++ /dev/null @@ -1,6 +0,0 @@ -using MediatR; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RevokeRefreshTokenWithCookie; - -public record RevokeRefreshTokenWithCookieCommand : IRequest { } diff --git a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandAuthorizer.cs b/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandAuthorizer.cs deleted file mode 100644 index eb2f8e2..0000000 --- a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandAuthorizer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using MediatR.Behaviors.Authorization; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RevokeRefreshTokenWithCookie; - -public class RevokeRefreshTokenWithCookieCommandAuthorizer : - AbstractRequestAuthorizer -{ - private readonly SessionUserService _sessionUserService; - - public RevokeRefreshTokenWithCookieCommandAuthorizer( - SessionUserService currentUserService) - { - _sessionUserService = currentUserService; - } - - public override void BuildPolicy(RevokeRefreshTokenWithCookieCommand request) - { - UseRequirement(new MustBeAuthenticatedRequirement - { - IsAuthenticated = _sessionUserService.IsAuthenticated - }); - } -} diff --git a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandHandler.cs b/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandHandler.cs deleted file mode 100644 index 27a8339..0000000 --- a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandHandler.cs +++ /dev/null @@ -1,28 +0,0 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using MediatR; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RevokeRefreshTokenWithCookie; - -public class RevokeRefreshTokenWithCookieCommandHandler : - IRequestHandler -{ - private readonly AuthenticationService _authenticationService; - private readonly SessionUserService _sessionUserService; - - public RevokeRefreshTokenWithCookieCommandHandler( - AuthenticationService authenticationService, - SessionUserService sessionUserService) - { - _authenticationService = authenticationService; - _sessionUserService = sessionUserService; - } - - public async Task Handle( - RevokeRefreshTokenWithCookieCommand request, - CancellationToken cancellationToken) - { - await _authenticationService.RevokeRefreshTokenAsync( - _sessionUserService.RefreshToken, cancellationToken); - } -} diff --git a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandValidator.cs b/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandValidator.cs deleted file mode 100644 index c378206..0000000 --- a/src/Application/Authentication/Commands/RevokeRefreshTokenWithCookie/RevokeRefreshTokenWithCookieCommandValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -using FluentValidation; - -namespace cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RevokeRefreshTokenWithCookie; - -public class RevokeRefreshTokenWithCookieCommandValidator : - AbstractValidator -{ - public RevokeRefreshTokenWithCookieCommandValidator() { } -} diff --git a/src/Application/Authentication/Queries/Login/LoginQuery.cs b/src/Application/Authentication/Queries/Login/LoginQuery.cs index 905347c..3a2c4dd 100644 --- a/src/Application/Authentication/Queries/Login/LoginQuery.cs +++ b/src/Application/Authentication/Queries/Login/LoginQuery.cs @@ -4,7 +4,7 @@ namespace cuqmbr.TravelGuide.Application.Authenticaion.Queries.Login; public record LoginQuery : IRequest { - public string Email { get; set; } + public string EmailOrUsername { get; set; } public string Password { get; set; } } diff --git a/src/Application/Authentication/Queries/Login/LoginQueryAuthorizer.cs b/src/Application/Authentication/Queries/Login/LoginQueryAuthorizer.cs new file mode 100644 index 0000000..eb5ab38 --- /dev/null +++ b/src/Application/Authentication/Queries/Login/LoginQueryAuthorizer.cs @@ -0,0 +1,12 @@ +using cuqmbr.TravelGuide.Application.Common.Authorization; +using MediatR.Behaviors.Authorization; + +namespace cuqmbr.TravelGuide.Application.Authenticaion.Queries.Login; + +public class LoginQueryAuthorizer : AbstractRequestAuthorizer +{ + public override void BuildPolicy(LoginQuery request) + { + UseRequirement(new AllowAllRequirement()); + } +} diff --git a/src/Application/Authentication/Queries/Login/LoginQueryHandler.cs b/src/Application/Authentication/Queries/Login/LoginQueryHandler.cs index 693a5bb..00e360b 100644 --- a/src/Application/Authentication/Queries/Login/LoginQueryHandler.cs +++ b/src/Application/Authentication/Queries/Login/LoginQueryHandler.cs @@ -1,21 +1,140 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using cuqmbr.TravelGuide.Application.Common.Exceptions; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Entities; using MediatR; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; namespace cuqmbr.TravelGuide.Application.Authenticaion.Queries.Login; public class LoginQueryHandler : IRequestHandler { - private readonly AuthenticationService _authenticationService; + private readonly UnitOfWork _unitOfWork; + private readonly PasswordHasherService _passwordHasher; + private readonly JsonWebTokenConfigurationOptions _jwtConfiguration; - public LoginQueryHandler(AuthenticationService authenticationService) + public LoginQueryHandler(UnitOfWork unitOfWork, + PasswordHasherService passwordHasher, + IOptions configurationOptions) { - _authenticationService = authenticationService; + _unitOfWork = unitOfWork; + _passwordHasher = passwordHasher; + _jwtConfiguration = configurationOptions.Value.JsonWebToken; } public async Task Handle( LoginQuery request, CancellationToken cancellationToken) { - return await _authenticationService.LoginAsync( - request.Email, request.Password, cancellationToken); + var account = await _unitOfWork.AccountRepository + .GetOneAsync( + a => + a.Email == request.EmailOrUsername || + a.Username == request.EmailOrUsername, + a => a.AccountRoles, cancellationToken); + + if (account == null) + { + throw new LoginException("No users registered with given email."); + } + + var hash = Convert.FromBase64String(account.PasswordHash); + var salt = Convert.FromBase64String(account.PasswordSalt); + var password = Encoding.UTF8.GetBytes(request.Password); + + var isValidPassword = await _passwordHasher + .IsValidHashAsync(hash, password, salt, cancellationToken); + + if (!isValidPassword) + { + throw new LoginException("Given password is incorrect."); + } + + var jwtSecurityToken = await CreateJwtAsync(account, cancellationToken); + var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); + + var refreshToken = (await _unitOfWork.RefreshTokenRepository + .GetPageAsync( + e => + e.AccountId == account.Id && + e.RevocationTime == null && + e.ExpirationTime > DateTimeOffset.UtcNow, + 1, int.MaxValue, cancellationToken)) + .Items.FirstOrDefault(); + + if (refreshToken == null) + { + refreshToken = CreateRefreshToken(); + refreshToken.AccountId = account.Id; + + await _unitOfWork.RefreshTokenRepository + .AddOneAsync(refreshToken, cancellationToken); + } + + await _unitOfWork.SaveAsync(cancellationToken); + _unitOfWork.Dispose(); + + return new TokensModel(accessToken, refreshToken.Value); + } + + private async Task CreateJwtAsync( + Account account, CancellationToken cancellationToken) + { + var roleIds = account.AccountRoles.Select(ar => ar.RoleId); + + var roles = (await _unitOfWork.RoleRepository + .GetPageAsync( + r => roleIds.Contains(r.Id), + 1, roleIds.Count(), cancellationToken)) + .Items.Select(r => r.Value); + + var roleClaims = new List(); + foreach (var role in roles) + { + roleClaims.Add(new Claim("roles", role.Name)); + } + + var claims = new List() + { + new Claim(JwtRegisteredClaimNames.Sub, account.Guid.ToString()), + new Claim(JwtRegisteredClaimNames.Nickname, account.Username), + new Claim(JwtRegisteredClaimNames.Email, account.Email) + } + .Union(roleClaims); + + var expirationDateTimeUtc = DateTime.UtcNow.Add( + _jwtConfiguration.AccessTokenValidity); + + var symmetricSecurityKey = new SymmetricSecurityKey( + Encoding.UTF8.GetBytes(_jwtConfiguration.IssuerSigningKey)); + var signingCredentials = new SigningCredentials( + symmetricSecurityKey, SecurityAlgorithms.HmacSha256); + + var jwtSecurityToken = new JwtSecurityToken( + issuer: _jwtConfiguration.Issuer, + audience: _jwtConfiguration.Audience, + claims: claims, + expires: expirationDateTimeUtc, + signingCredentials: signingCredentials); + + return jwtSecurityToken; + } + + private RefreshToken CreateRefreshToken() + { + var token = RandomNumberGenerator.GetBytes(128 / 8); + + return new RefreshToken + { + Guid = Guid.NewGuid(), + Value = Convert.ToBase64String(token), + CreationTime = DateTimeOffset.UtcNow, + ExpirationTime = DateTimeOffset.UtcNow.Add( + _jwtConfiguration.RefreshTokenValidity) + }; } } diff --git a/src/Application/Authentication/Queries/Login/LoginQueryValidator.cs b/src/Application/Authentication/Queries/Login/LoginQueryValidator.cs index 9f3fb38..7a0ed0b 100644 --- a/src/Application/Authentication/Queries/Login/LoginQueryValidator.cs +++ b/src/Application/Authentication/Queries/Login/LoginQueryValidator.cs @@ -1,15 +1,18 @@ using FluentValidation; +using Microsoft.Extensions.Localization; namespace cuqmbr.TravelGuide.Application.Authenticaion.Queries.Login; public class LoginQueryValidator : AbstractValidator { - public LoginQueryValidator() + public LoginQueryValidator(IStringLocalizer localizer) { - RuleFor(v => v.Email) - .NotEmpty().WithMessage("Email address is required."); + RuleFor(v => v.EmailOrUsername) + .NotEmpty() + .WithMessage(localizer["FluentValidation.NotEmpty"]); RuleFor(v => v.Password) - .NotEmpty().WithMessage("Password is required."); + .NotEmpty() + .WithMessage(localizer["FluentValidation.NotEmpty"]); } } diff --git a/src/Application/Buses/Commands/AddBus/AddBusCommandAuthorizer.cs b/src/Application/Buses/Commands/AddBus/AddBusCommandAuthorizer.cs index 60a0581..5e16639 100644 --- a/src/Application/Buses/Commands/AddBus/AddBusCommandAuthorizer.cs +++ b/src/Application/Buses/Commands/AddBus/AddBusCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Buses.Commands.AddBus; diff --git a/src/Application/Buses/Commands/AddBus/AddBusCommandHandler.cs b/src/Application/Buses/Commands/AddBus/AddBusCommandHandler.cs index 346bd4b..3d5c276 100644 --- a/src/Application/Buses/Commands/AddBus/AddBusCommandHandler.cs +++ b/src/Application/Buses/Commands/AddBus/AddBusCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Buses/Commands/AddBus/AddBusCommandValidator.cs b/src/Application/Buses/Commands/AddBus/AddBusCommandValidator.cs index 084cfcc..f16532a 100644 --- a/src/Application/Buses/Commands/AddBus/AddBusCommandValidator.cs +++ b/src/Application/Buses/Commands/AddBus/AddBusCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandAuthorizer.cs b/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandAuthorizer.cs index 2f61edc..f5858c7 100644 --- a/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandAuthorizer.cs +++ b/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Buses.Commands.DeleteBus; diff --git a/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandHandler.cs b/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandHandler.cs index f226338..1755ddd 100644 --- a/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandHandler.cs +++ b/src/Application/Buses/Commands/DeleteBus/DeleteBusCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Buses.Commands.DeleteBus; diff --git a/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandAuthorizer.cs b/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandAuthorizer.cs index 17201fa..1b05021 100644 --- a/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandAuthorizer.cs +++ b/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Buses.Commands.UpdateBus; diff --git a/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandHandler.cs b/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandHandler.cs index 2360617..64e74b8 100644 --- a/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandHandler.cs +++ b/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandValidator.cs b/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandValidator.cs index 74c6b26..4a11102 100644 --- a/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandValidator.cs +++ b/src/Application/Buses/Commands/UpdateBus/UpdateBusCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Buses/Queries/GetBus/GetBusQueryAuthorizer.cs b/src/Application/Buses/Queries/GetBus/GetBusQueryAuthorizer.cs index 372b46e..a22724c 100644 --- a/src/Application/Buses/Queries/GetBus/GetBusQueryAuthorizer.cs +++ b/src/Application/Buses/Queries/GetBus/GetBusQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Buses.Queries.GetBus; diff --git a/src/Application/Buses/Queries/GetBus/GetBusQueryHandler.cs b/src/Application/Buses/Queries/GetBus/GetBusQueryHandler.cs index b1fc747..55c1b86 100644 --- a/src/Application/Buses/Queries/GetBus/GetBusQueryHandler.cs +++ b/src/Application/Buses/Queries/GetBus/GetBusQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryAuthorizer.cs b/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryAuthorizer.cs index f51a43c..8c26e31 100644 --- a/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryAuthorizer.cs +++ b/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Buses.Queries.GetBusesPage; diff --git a/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryHandler.cs b/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryHandler.cs index 28fe46f..9d29d12 100644 --- a/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryHandler.cs +++ b/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryValidator.cs b/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryValidator.cs index 7ab1118..432f9e3 100644 --- a/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryValidator.cs +++ b/src/Application/Buses/Queries/GetBusesPage/GetBusesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Cities/Commands/AddCity/AddCityCommandAuthorizer.cs b/src/Application/Cities/Commands/AddCity/AddCityCommandAuthorizer.cs index 1122f5f..18d5425 100644 --- a/src/Application/Cities/Commands/AddCity/AddCityCommandAuthorizer.cs +++ b/src/Application/Cities/Commands/AddCity/AddCityCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Cities.Commands.AddCity; diff --git a/src/Application/Cities/Commands/AddCity/AddCityCommandHandler.cs b/src/Application/Cities/Commands/AddCity/AddCityCommandHandler.cs index 51584b4..13d7708 100644 --- a/src/Application/Cities/Commands/AddCity/AddCityCommandHandler.cs +++ b/src/Application/Cities/Commands/AddCity/AddCityCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Cities/Commands/AddCity/AddCityCommandValidator.cs b/src/Application/Cities/Commands/AddCity/AddCityCommandValidator.cs index 6b20606..4dd216c 100644 --- a/src/Application/Cities/Commands/AddCity/AddCityCommandValidator.cs +++ b/src/Application/Cities/Commands/AddCity/AddCityCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandAuthorizer.cs b/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandAuthorizer.cs index ed62a53..f966a4e 100644 --- a/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandAuthorizer.cs +++ b/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity; diff --git a/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandHandler.cs b/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandHandler.cs index 700334d..c5ebf61 100644 --- a/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandHandler.cs +++ b/src/Application/Cities/Commands/DeleteCity/DeleteCityCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity; diff --git a/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandAuthorizer.cs b/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandAuthorizer.cs index ed1e198..263feaa 100644 --- a/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandAuthorizer.cs +++ b/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Cities.Commands.UpdateCity; diff --git a/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandHandler.cs b/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandHandler.cs index 5fecbc5..8e71fb3 100644 --- a/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandHandler.cs +++ b/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandValidator.cs b/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandValidator.cs index bdc49c0..6d1ef78 100644 --- a/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandValidator.cs +++ b/src/Application/Cities/Commands/UpdateCity/UpdateCityCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryAuthorizer.cs b/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryAuthorizer.cs index 84872fe..e52cd0d 100644 --- a/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryAuthorizer.cs +++ b/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage; diff --git a/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryHandler.cs b/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryHandler.cs index 3d4d568..f3b45af 100644 --- a/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryHandler.cs +++ b/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryValidator.cs b/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryValidator.cs index 53e5264..9bc82fa 100644 --- a/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryValidator.cs +++ b/src/Application/Cities/Queries/GetCitiesPage/GetCitiesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Cities/Queries/GetCity/GetCityQueryAuthorizer.cs b/src/Application/Cities/Queries/GetCity/GetCityQueryAuthorizer.cs index 55f927d..875847f 100644 --- a/src/Application/Cities/Queries/GetCity/GetCityQueryAuthorizer.cs +++ b/src/Application/Cities/Queries/GetCity/GetCityQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCity; diff --git a/src/Application/Cities/Queries/GetCity/GetCityQueryHandler.cs b/src/Application/Cities/Queries/GetCity/GetCityQueryHandler.cs index 68e3aec..49827e2 100644 --- a/src/Application/Cities/Queries/GetCity/GetCityQueryHandler.cs +++ b/src/Application/Cities/Queries/GetCity/GetCityQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Common/Authorization/MustBeInRolesRequirement.cs b/src/Application/Common/Authorization/MustBeInRolesRequirement.cs index e1368d1..8035dd0 100644 --- a/src/Application/Common/Authorization/MustBeInRolesRequirement.cs +++ b/src/Application/Common/Authorization/MustBeInRolesRequirement.cs @@ -1,6 +1,6 @@ using MediatR.Behaviors.Authorization; using Microsoft.Extensions.Localization; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.Application.Common.Authorization; diff --git a/src/Application/Common/FluentValidation/CustomValidators.cs b/src/Application/Common/FluentValidation/CustomValidators.cs index f7b1de1..0dfbce8 100644 --- a/src/Application/Common/FluentValidation/CustomValidators.cs +++ b/src/Application/Common/FluentValidation/CustomValidators.cs @@ -4,6 +4,14 @@ namespace cuqmbr.TravelGuide.Application.Common.FluentValidation; public static class CustomValidators { + public static IRuleBuilderOptions IsUsername( + this IRuleBuilder ruleBuilder) + { + return + ruleBuilder + .Matches(@"^[a-z0-9-_.]*$"); + } + // According to RFC 5321. public static IRuleBuilderOptions IsEmail( this IRuleBuilder ruleBuilder) diff --git a/src/Application/Common/Interfaces/Services/AuthenticationService.cs b/src/Application/Common/Interfaces/Services/AuthenticationService.cs deleted file mode 100644 index 6f8932b..0000000 --- a/src/Application/Common/Interfaces/Services/AuthenticationService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using cuqmbr.TravelGuide.Application.Authenticaion; - -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; - -public interface AuthenticationService -{ - Task RegisterAsync(string email, string password, - CancellationToken cancellationToken); - - Task LoginAsync(string email, string password, - CancellationToken cancellationToken); - - Task RenewAccessTokenAsync(string refreshToken, - CancellationToken cancellationToken); - - Task RevokeRefreshTokenAsync(string refreshToken, - CancellationToken cancellationToken); -} diff --git a/src/Application/Common/Interfaces/Services/SessionUserService.cs b/src/Application/Common/Interfaces/Services/SessionUserService.cs deleted file mode 100644 index 0ffb78d..0000000 --- a/src/Application/Common/Interfaces/Services/SessionUserService.cs +++ /dev/null @@ -1,22 +0,0 @@ -using cuqmbr.TravelGuide.Application.Common.Models; - -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; - -public interface SessionUserService -{ - public int? Id { get; } - - public Guid? Uuid { get; } - - public string? Email { get; } - - public ICollection Roles { get; } - - - public bool IsAuthenticated => Id != null; - - - public string? AccessToken { get; } - - public string? RefreshToken { get; } -} diff --git a/src/Application/Common/Mappings/Resolvers/DateTimeOffsetResolver.cs b/src/Application/Common/Mappings/Resolvers/DateTimeOffsetResolver.cs index 56423e8..8f7797f 100644 --- a/src/Application/Common/Mappings/Resolvers/DateTimeOffsetResolver.cs +++ b/src/Application/Common/Mappings/Resolvers/DateTimeOffsetResolver.cs @@ -1,5 +1,5 @@ using AutoMapper; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; namespace cuqmbr.TravelGuide.Application.Common.Mappings.Resolvers; diff --git a/src/Application/Common/Persistence/Repositories/AccountRepository.cs b/src/Application/Common/Persistence/Repositories/AccountRepository.cs new file mode 100644 index 0000000..57ab40e --- /dev/null +++ b/src/Application/Common/Persistence/Repositories/AccountRepository.cs @@ -0,0 +1,5 @@ +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; + +public interface AccountRepository : BaseRepository { } diff --git a/src/Application/Common/Persistence/Repositories/AccountRoleRepository.cs b/src/Application/Common/Persistence/Repositories/AccountRoleRepository.cs new file mode 100644 index 0000000..42ce1c1 --- /dev/null +++ b/src/Application/Common/Persistence/Repositories/AccountRoleRepository.cs @@ -0,0 +1,5 @@ +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; + +public interface AccountRoleRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/AddressRepository.cs b/src/Application/Common/Persistence/Repositories/AddressRepository.cs similarity index 54% rename from src/Application/Common/Interfaces/Persistence/Repositories/AddressRepository.cs rename to src/Application/Common/Persistence/Repositories/AddressRepository.cs index 3dfcbf4..0280f38 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/AddressRepository.cs +++ b/src/Application/Common/Persistence/Repositories/AddressRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface AddressRepository : BaseRepository
{ } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/AircraftRepository.cs b/src/Application/Common/Persistence/Repositories/AircraftRepository.cs similarity index 55% rename from src/Application/Common/Interfaces/Persistence/Repositories/AircraftRepository.cs rename to src/Application/Common/Persistence/Repositories/AircraftRepository.cs index 8ccd4ca..3d82992 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/AircraftRepository.cs +++ b/src/Application/Common/Persistence/Repositories/AircraftRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface AircraftRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/BaseRepository.cs b/src/Application/Common/Persistence/Repositories/BaseRepository.cs similarity index 94% rename from src/Application/Common/Interfaces/Persistence/Repositories/BaseRepository.cs rename to src/Application/Common/Persistence/Repositories/BaseRepository.cs index e3b78d5..a89c127 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/BaseRepository.cs +++ b/src/Application/Common/Persistence/Repositories/BaseRepository.cs @@ -2,8 +2,7 @@ using System.Linq.Expressions; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface BaseRepository where TEntity : EntityBase diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/BusRepository.cs b/src/Application/Common/Persistence/Repositories/BusRepository.cs similarity index 52% rename from src/Application/Common/Interfaces/Persistence/Repositories/BusRepository.cs rename to src/Application/Common/Persistence/Repositories/BusRepository.cs index 18c76dc..d06a5f3 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/BusRepository.cs +++ b/src/Application/Common/Persistence/Repositories/BusRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface BusRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/CityRepository.cs b/src/Application/Common/Persistence/Repositories/CityRepository.cs similarity index 53% rename from src/Application/Common/Interfaces/Persistence/Repositories/CityRepository.cs rename to src/Application/Common/Persistence/Repositories/CityRepository.cs index beee75b..4db10a0 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/CityRepository.cs +++ b/src/Application/Common/Persistence/Repositories/CityRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface CityRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/CompanyRepository.cs b/src/Application/Common/Persistence/Repositories/CompanyRepository.cs similarity index 70% rename from src/Application/Common/Interfaces/Persistence/Repositories/CompanyRepository.cs rename to src/Application/Common/Persistence/Repositories/CompanyRepository.cs index b65663a..23be434 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/CompanyRepository.cs +++ b/src/Application/Common/Persistence/Repositories/CompanyRepository.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces +namespace cuqmbr.TravelGuide.Application.Common .Persistence.Repositories; public interface CompanyRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/CountryRepository.cs b/src/Application/Common/Persistence/Repositories/CountryRepository.cs similarity index 54% rename from src/Application/Common/Interfaces/Persistence/Repositories/CountryRepository.cs rename to src/Application/Common/Persistence/Repositories/CountryRepository.cs index 2be573d..1e27047 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/CountryRepository.cs +++ b/src/Application/Common/Persistence/Repositories/CountryRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface CountryRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/EmployeeRepository.cs b/src/Application/Common/Persistence/Repositories/EmployeeRepository.cs similarity index 70% rename from src/Application/Common/Interfaces/Persistence/Repositories/EmployeeRepository.cs rename to src/Application/Common/Persistence/Repositories/EmployeeRepository.cs index 012cf93..5941838 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/EmployeeRepository.cs +++ b/src/Application/Common/Persistence/Repositories/EmployeeRepository.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces +namespace cuqmbr.TravelGuide.Application.Common .Persistence.Repositories; public interface EmployeeRepository : BaseRepository { } diff --git a/src/Application/Common/Persistence/Repositories/RefreshTokenRepository.cs b/src/Application/Common/Persistence/Repositories/RefreshTokenRepository.cs new file mode 100644 index 0000000..b44ebec --- /dev/null +++ b/src/Application/Common/Persistence/Repositories/RefreshTokenRepository.cs @@ -0,0 +1,5 @@ +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; + +public interface RefreshTokenRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/RegionRepository.cs b/src/Application/Common/Persistence/Repositories/RegionRepository.cs similarity index 54% rename from src/Application/Common/Interfaces/Persistence/Repositories/RegionRepository.cs rename to src/Application/Common/Persistence/Repositories/RegionRepository.cs index 29ecdfe..29ba027 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/RegionRepository.cs +++ b/src/Application/Common/Persistence/Repositories/RegionRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface RegionRepository : BaseRepository { } diff --git a/src/Application/Common/Persistence/Repositories/RoleRepository.cs b/src/Application/Common/Persistence/Repositories/RoleRepository.cs new file mode 100644 index 0000000..72d3640 --- /dev/null +++ b/src/Application/Common/Persistence/Repositories/RoleRepository.cs @@ -0,0 +1,5 @@ +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; + +public interface RoleRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/RouteAddressDetailRepository.cs b/src/Application/Common/Persistence/Repositories/RouteAddressDetailRepository.cs similarity index 73% rename from src/Application/Common/Interfaces/Persistence/Repositories/RouteAddressDetailRepository.cs rename to src/Application/Common/Persistence/Repositories/RouteAddressDetailRepository.cs index 2bac9d4..b0588ba 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/RouteAddressDetailRepository.cs +++ b/src/Application/Common/Persistence/Repositories/RouteAddressDetailRepository.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces +namespace cuqmbr.TravelGuide.Application.Common .Persistence.Repositories; public interface RouteAddressDetailRepository : diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/RouteAddressRepository.cs b/src/Application/Common/Persistence/Repositories/RouteAddressRepository.cs similarity index 57% rename from src/Application/Common/Interfaces/Persistence/Repositories/RouteAddressRepository.cs rename to src/Application/Common/Persistence/Repositories/RouteAddressRepository.cs index 4ff5733..8670b9b 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/RouteAddressRepository.cs +++ b/src/Application/Common/Persistence/Repositories/RouteAddressRepository.cs @@ -1,7 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface RouteAddressRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/RouteRepository.cs b/src/Application/Common/Persistence/Repositories/RouteRepository.cs similarity index 53% rename from src/Application/Common/Interfaces/Persistence/Repositories/RouteRepository.cs rename to src/Application/Common/Persistence/Repositories/RouteRepository.cs index 83249fb..866a0a3 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/RouteRepository.cs +++ b/src/Application/Common/Persistence/Repositories/RouteRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface RouteRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/TicketGroupRepository.cs b/src/Application/Common/Persistence/Repositories/TicketGroupRepository.cs similarity index 71% rename from src/Application/Common/Interfaces/Persistence/Repositories/TicketGroupRepository.cs rename to src/Application/Common/Persistence/Repositories/TicketGroupRepository.cs index ead97c3..9dfe535 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/TicketGroupRepository.cs +++ b/src/Application/Common/Persistence/Repositories/TicketGroupRepository.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces +namespace cuqmbr.TravelGuide.Application.Common .Persistence.Repositories; public interface TicketGroupRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/TicketRepository.cs b/src/Application/Common/Persistence/Repositories/TicketRepository.cs similarity index 70% rename from src/Application/Common/Interfaces/Persistence/Repositories/TicketRepository.cs rename to src/Application/Common/Persistence/Repositories/TicketRepository.cs index 57b96aa..881008c 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/TicketRepository.cs +++ b/src/Application/Common/Persistence/Repositories/TicketRepository.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces +namespace cuqmbr.TravelGuide.Application.Common .Persistence.Repositories; public interface TicketRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/TrainRepository.cs b/src/Application/Common/Persistence/Repositories/TrainRepository.cs similarity index 53% rename from src/Application/Common/Interfaces/Persistence/Repositories/TrainRepository.cs rename to src/Application/Common/Persistence/Repositories/TrainRepository.cs index 640a507..9358316 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/TrainRepository.cs +++ b/src/Application/Common/Persistence/Repositories/TrainRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface TrainRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs b/src/Application/Common/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs similarity index 62% rename from src/Application/Common/Interfaces/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs rename to src/Application/Common/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs index 6c396d2..599dd71 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs +++ b/src/Application/Common/Persistence/Repositories/VehicleEnrollmentEmployeeRepository.cs @@ -1,7 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface VehicleEnrollmentEmployeeRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/VehicleEnrollmentRepository.cs b/src/Application/Common/Persistence/Repositories/VehicleEnrollmentRepository.cs similarity index 59% rename from src/Application/Common/Interfaces/Persistence/Repositories/VehicleEnrollmentRepository.cs rename to src/Application/Common/Persistence/Repositories/VehicleEnrollmentRepository.cs index 1341b74..763cff0 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/VehicleEnrollmentRepository.cs +++ b/src/Application/Common/Persistence/Repositories/VehicleEnrollmentRepository.cs @@ -1,7 +1,6 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface VehicleEnrollmentRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/Repositories/VehicleRepository.cs b/src/Application/Common/Persistence/Repositories/VehicleRepository.cs similarity index 54% rename from src/Application/Common/Interfaces/Persistence/Repositories/VehicleRepository.cs rename to src/Application/Common/Persistence/Repositories/VehicleRepository.cs index db9fde8..7a04b65 100644 --- a/src/Application/Common/Interfaces/Persistence/Repositories/VehicleRepository.cs +++ b/src/Application/Common/Persistence/Repositories/VehicleRepository.cs @@ -1,6 +1,5 @@ using cuqmbr.TravelGuide.Domain.Entities; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces - .Persistence.Repositories; +namespace cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; public interface VehicleRepository : BaseRepository { } diff --git a/src/Application/Common/Interfaces/Persistence/UnitOfWork.cs b/src/Application/Common/Persistence/UnitOfWork.cs similarity index 73% rename from src/Application/Common/Interfaces/Persistence/UnitOfWork.cs rename to src/Application/Common/Persistence/UnitOfWork.cs index 262822a..41bd0aa 100644 --- a/src/Application/Common/Interfaces/Persistence/UnitOfWork.cs +++ b/src/Application/Common/Persistence/UnitOfWork.cs @@ -1,9 +1,11 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +namespace cuqmbr.TravelGuide.Application.Common.Persistence; public interface UnitOfWork : IDisposable { + // Application Logic + CountryRepository CountryRepository { get; } RegionRepository RegionRepository { get; } @@ -38,6 +40,16 @@ public interface UnitOfWork : IDisposable VehicleEnrollmentEmployeeRepository VehicleEnrollmentEmployeeRepository { get; } + // Identity + + AccountRepository AccountRepository { get; } + + RoleRepository RoleRepository { get; } + + AccountRoleRepository AccountRoleRepository { get; } + + RefreshTokenRepository RefreshTokenRepository { get; } + int Save(); Task SaveAsync(CancellationToken cancellationToken); diff --git a/src/Application/Common/Interfaces/Services/CurrencyConverterService.cs b/src/Application/Common/Services/CurrencyConverterService.cs similarity index 83% rename from src/Application/Common/Interfaces/Services/CurrencyConverterService.cs rename to src/Application/Common/Services/CurrencyConverterService.cs index 4f47c30..e8ae6a0 100644 --- a/src/Application/Common/Interfaces/Services/CurrencyConverterService.cs +++ b/src/Application/Common/Services/CurrencyConverterService.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Enums; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +namespace cuqmbr.TravelGuide.Application.Common.Services; public interface CurrencyConverterService { diff --git a/src/Application/Common/Interfaces/Services/LiqPayPaymentService.cs b/src/Application/Common/Services/LiqPayPaymentService.cs similarity index 82% rename from src/Application/Common/Interfaces/Services/LiqPayPaymentService.cs rename to src/Application/Common/Services/LiqPayPaymentService.cs index 768a1c3..238bb84 100644 --- a/src/Application/Common/Interfaces/Services/LiqPayPaymentService.cs +++ b/src/Application/Common/Services/LiqPayPaymentService.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Enums; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +namespace cuqmbr.TravelGuide.Application.Common.Services; public interface LiqPayPaymentService { diff --git a/src/Application/Common/Services/PasswordHasherService.cs b/src/Application/Common/Services/PasswordHasherService.cs new file mode 100644 index 0000000..a3dc22c --- /dev/null +++ b/src/Application/Common/Services/PasswordHasherService.cs @@ -0,0 +1,10 @@ +namespace cuqmbr.TravelGuide.Application.Common.Services; + +public interface PasswordHasherService +{ + Task HashAsync(byte[] password, byte[] salt, + CancellationToken cancellationToken); + + Task IsValidHashAsync(byte[] hash, byte[] password, + byte[] salt, CancellationToken cancellationToken); +} diff --git a/src/Application/Common/Interfaces/Services/SessionCurrencyService.cs b/src/Application/Common/Services/SessionCurrencyService.cs similarity index 64% rename from src/Application/Common/Interfaces/Services/SessionCurrencyService.cs rename to src/Application/Common/Services/SessionCurrencyService.cs index 258a3c0..15e7ce0 100644 --- a/src/Application/Common/Interfaces/Services/SessionCurrencyService.cs +++ b/src/Application/Common/Services/SessionCurrencyService.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Domain.Enums; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +namespace cuqmbr.TravelGuide.Application.Common.Services; public interface SessionCurrencyService { diff --git a/src/Application/Common/Interfaces/Services/SessionTimeZoneService.cs b/src/Application/Common/Services/SessionTimeZoneService.cs similarity index 55% rename from src/Application/Common/Interfaces/Services/SessionTimeZoneService.cs rename to src/Application/Common/Services/SessionTimeZoneService.cs index ed60d8b..4b2faaa 100644 --- a/src/Application/Common/Interfaces/Services/SessionTimeZoneService.cs +++ b/src/Application/Common/Services/SessionTimeZoneService.cs @@ -1,4 +1,4 @@ -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +namespace cuqmbr.TravelGuide.Application.Common.Services; public interface SessionTimeZoneService { diff --git a/src/Application/Common/Services/SessionUserService.cs b/src/Application/Common/Services/SessionUserService.cs new file mode 100644 index 0000000..7a868ab --- /dev/null +++ b/src/Application/Common/Services/SessionUserService.cs @@ -0,0 +1,22 @@ +using cuqmbr.TravelGuide.Domain.Enums; + +namespace cuqmbr.TravelGuide.Application.Common.Services; + +public interface SessionUserService +{ + public Guid? Guid { get; } + + public string? Username { get; } + + public string? Email { get; } + + public ICollection Roles { get; } + + + public bool IsAuthenticated => Guid != null; + + + public string? AccessToken { get; } + + public string? RefreshToken { get; } +} diff --git a/src/Application/Common/Interfaces/Services/SessoionCultureService.cs b/src/Application/Common/Services/SessoionCultureService.cs similarity index 62% rename from src/Application/Common/Interfaces/Services/SessoionCultureService.cs rename to src/Application/Common/Services/SessoionCultureService.cs index 23d7389..32a1aa0 100644 --- a/src/Application/Common/Interfaces/Services/SessoionCultureService.cs +++ b/src/Application/Common/Services/SessoionCultureService.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +namespace cuqmbr.TravelGuide.Application.Common.Services; public interface SessionCultureService { diff --git a/src/Application/Companies/Commands/AddCompany/AddCompanyCommandAuthorizer.cs b/src/Application/Companies/Commands/AddCompany/AddCompanyCommandAuthorizer.cs index 7d77ac2..ea238b8 100644 --- a/src/Application/Companies/Commands/AddCompany/AddCompanyCommandAuthorizer.cs +++ b/src/Application/Companies/Commands/AddCompany/AddCompanyCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany; diff --git a/src/Application/Companies/Commands/AddCompany/AddCompanyCommandHandler.cs b/src/Application/Companies/Commands/AddCompany/AddCompanyCommandHandler.cs index 07b4270..2605a86 100644 --- a/src/Application/Companies/Commands/AddCompany/AddCompanyCommandHandler.cs +++ b/src/Application/Companies/Commands/AddCompany/AddCompanyCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Companies/Commands/AddCompany/AddCompanyCommandValidator.cs b/src/Application/Companies/Commands/AddCompany/AddCompanyCommandValidator.cs index 209a093..5e522a4 100644 --- a/src/Application/Companies/Commands/AddCompany/AddCompanyCommandValidator.cs +++ b/src/Application/Companies/Commands/AddCompany/AddCompanyCommandValidator.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.FluentValidation; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandAuthorizer.cs b/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandAuthorizer.cs index bfd16e8..446421d 100644 --- a/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandAuthorizer.cs +++ b/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany; diff --git a/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandHandler.cs b/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandHandler.cs index 9ceae16..da0a471 100644 --- a/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandHandler.cs +++ b/src/Application/Companies/Commands/DeleteCompany/DeleteCompanyCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany; diff --git a/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandAuthorizer.cs b/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandAuthorizer.cs index 5f93add..a3f754b 100644 --- a/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandAuthorizer.cs +++ b/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Companies.Commands.UpdateCompany; diff --git a/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandHandler.cs b/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandHandler.cs index 78e408e..e57cda5 100644 --- a/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandHandler.cs +++ b/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandValidator.cs b/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandValidator.cs index a5bb800..c79afb9 100644 --- a/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandValidator.cs +++ b/src/Application/Companies/Commands/UpdateCompany/UpdateCompanyCommandValidator.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.FluentValidation; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryAuthorizer.cs b/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryAuthorizer.cs index 979329c..3ed1e1a 100644 --- a/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryAuthorizer.cs +++ b/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompaniesPage; diff --git a/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryHandler.cs b/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryHandler.cs index 49724c2..3749deb 100644 --- a/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryHandler.cs +++ b/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryValidator.cs b/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryValidator.cs index 9f9143c..5fb0088 100644 --- a/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryValidator.cs +++ b/src/Application/Companies/Queries/GetCompaniesPage/GetCompaniesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Companies/Queries/GetCompany/GetCompanyQueryAuthorizer.cs b/src/Application/Companies/Queries/GetCompany/GetCompanyQueryAuthorizer.cs index ce96fe7..f83a0b8 100644 --- a/src/Application/Companies/Queries/GetCompany/GetCompanyQueryAuthorizer.cs +++ b/src/Application/Companies/Queries/GetCompany/GetCompanyQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompany; diff --git a/src/Application/Companies/Queries/GetCompany/GetCompanyQueryHandler.cs b/src/Application/Companies/Queries/GetCompany/GetCompanyQueryHandler.cs index 61cc0eb..a625857 100644 --- a/src/Application/Companies/Queries/GetCompany/GetCompanyQueryHandler.cs +++ b/src/Application/Companies/Queries/GetCompany/GetCompanyQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/ConfigurationOptions.cs b/src/Application/ConfigurationOptions.cs index e80d048..7a6edea 100644 --- a/src/Application/ConfigurationOptions.cs +++ b/src/Application/ConfigurationOptions.cs @@ -7,6 +7,8 @@ public sealed class ConfigurationOptions public LocalizationConfigurationOptions Localization { get; set; } = new(); public LoggingConfigurationOptions Logging { get; set; } = new(); + + public JsonWebTokenConfigurationOptions JsonWebToken { get; set; } = new(); } public sealed class LocalizationConfigurationOptions @@ -26,3 +28,16 @@ public sealed class LoggingConfigurationOptions public bool UseUtcTimestamp { get; set; } = true; } + +public sealed class JsonWebTokenConfigurationOptions +{ + public string Issuer { get; set; } = "localhost"; + + public string Audience { get; set; } = "localhost"; + + public string IssuerSigningKey { get; set; } = "change-me"; + + public TimeSpan AccessTokenValidity { get; set; } = TimeSpan.FromMinutes(15); + + public TimeSpan RefreshTokenValidity { get; set; } = TimeSpan.FromDays(3); +} diff --git a/src/Application/Countries/Commands/AddCountry/AddCountryCommandAuthorizer.cs b/src/Application/Countries/Commands/AddCountry/AddCountryCommandAuthorizer.cs index 3ba50fd..930de98 100644 --- a/src/Application/Countries/Commands/AddCountry/AddCountryCommandAuthorizer.cs +++ b/src/Application/Countries/Commands/AddCountry/AddCountryCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Countries.Commands.AddCountry; diff --git a/src/Application/Countries/Commands/AddCountry/AddCountryCommandHandler.cs b/src/Application/Countries/Commands/AddCountry/AddCountryCommandHandler.cs index 91ad72c..fc7399b 100644 --- a/src/Application/Countries/Commands/AddCountry/AddCountryCommandHandler.cs +++ b/src/Application/Countries/Commands/AddCountry/AddCountryCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Countries/Commands/AddCountry/AddCountryCommandValidator.cs b/src/Application/Countries/Commands/AddCountry/AddCountryCommandValidator.cs index ec854f3..34fcdae 100644 --- a/src/Application/Countries/Commands/AddCountry/AddCountryCommandValidator.cs +++ b/src/Application/Countries/Commands/AddCountry/AddCountryCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandAuthorizer.cs b/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandAuthorizer.cs index 73b8422..1c327b1 100644 --- a/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandAuthorizer.cs +++ b/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Countries.Commands.DeleteCountry; diff --git a/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandHandler.cs b/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandHandler.cs index 8f3b55a..39fc2db 100644 --- a/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandHandler.cs +++ b/src/Application/Countries/Commands/DeleteCountry/DeleteCountryCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Countries.Commands.DeleteCountry; diff --git a/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandAuthorizer.cs b/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandAuthorizer.cs index dc4994c..dcdfbe7 100644 --- a/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandAuthorizer.cs +++ b/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Countries.Commands.UpdateCountry; diff --git a/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandHandler.cs b/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandHandler.cs index 7d3d822..22fe5fd 100644 --- a/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandHandler.cs +++ b/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandValidator.cs b/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandValidator.cs index 6809cb9..52e7d12 100644 --- a/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandValidator.cs +++ b/src/Application/Countries/Commands/UpdateCountry/UpdateCountryCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryAuthorizer.cs b/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryAuthorizer.cs index 67796d8..24ac4df 100644 --- a/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryAuthorizer.cs +++ b/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Countries.Queries.GetCountriesPage; diff --git a/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryHandler.cs b/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryHandler.cs index 2ab565d..74b3eeb 100644 --- a/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryHandler.cs +++ b/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryValidator.cs b/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryValidator.cs index ceeea99..00ac279 100644 --- a/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryValidator.cs +++ b/src/Application/Countries/Queries/GetCountriesPage/GetCountriesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Countries/Queries/GetCountry/GetCountryQueryAuthorizer.cs b/src/Application/Countries/Queries/GetCountry/GetCountryQueryAuthorizer.cs index 699f958..f158344 100644 --- a/src/Application/Countries/Queries/GetCountry/GetCountryQueryAuthorizer.cs +++ b/src/Application/Countries/Queries/GetCountry/GetCountryQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Countries.Queries.GetCountry; diff --git a/src/Application/Countries/Queries/GetCountry/GetCountryQueryHandler.cs b/src/Application/Countries/Queries/GetCountry/GetCountryQueryHandler.cs index 49851a9..cdd06a2 100644 --- a/src/Application/Countries/Queries/GetCountry/GetCountryQueryHandler.cs +++ b/src/Application/Countries/Queries/GetCountry/GetCountryQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandAuthorizer.cs b/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandAuthorizer.cs index 8e2f0d1..1255c27 100644 --- a/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandAuthorizer.cs +++ b/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Employees.Commands.AddEmployee; diff --git a/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandHandler.cs b/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandHandler.cs index 1d528b6..adb5fa0 100644 --- a/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandHandler.cs +++ b/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandValidator.cs b/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandValidator.cs index 149bc95..3a9348e 100644 --- a/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandValidator.cs +++ b/src/Application/Employees/Commands/AddEmployee/AddEmployeeCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandAuthorizer.cs b/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandAuthorizer.cs index e2f0478..f5b826f 100644 --- a/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandAuthorizer.cs +++ b/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Employees.Commands.DeleteEmployee; diff --git a/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandHandler.cs b/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandHandler.cs index 2e7c8c3..539ebcf 100644 --- a/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandHandler.cs +++ b/src/Application/Employees/Commands/DeleteEmployee/DeleteEmployeeCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Employees.Commands.DeleteEmployee; diff --git a/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandAuthorizer.cs b/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandAuthorizer.cs index e3ff38e..52bd256 100644 --- a/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandAuthorizer.cs +++ b/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Employees.Commands.UpdateEmployee; diff --git a/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandHandler.cs b/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandHandler.cs index 80d3d26..293fb38 100644 --- a/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandHandler.cs +++ b/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; using Microsoft.Extensions.Localization; diff --git a/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandValidator.cs b/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandValidator.cs index e6cf45e..ac4fdb0 100644 --- a/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandValidator.cs +++ b/src/Application/Employees/Commands/UpdateEmployee/UpdateEmployeeCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryAuthorizer.cs b/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryAuthorizer.cs index 6011990..5334ff2 100644 --- a/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryAuthorizer.cs +++ b/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Employees.Queries.GetEmployee; diff --git a/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryHandler.cs b/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryHandler.cs index 2e3edcb..f8f7517 100644 --- a/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryHandler.cs +++ b/src/Application/Employees/Queries/GetEmployee/GetEmployeeQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryAuthorizer.cs b/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryAuthorizer.cs index 775eeb3..b86a3cb 100644 --- a/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryAuthorizer.cs +++ b/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Employees.Queries.GetEmployeesPage; diff --git a/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryHandler.cs b/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryHandler.cs index 21a5a81..ba18ac0 100644 --- a/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryHandler.cs +++ b/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryValidator.cs b/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryValidator.cs index c85edf2..5b3e464 100644 --- a/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryValidator.cs +++ b/src/Application/Employees/Queries/GetEmployeesPage/GetEmployeesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Identity/Accounts/AccountDto.cs b/src/Application/Identity/Accounts/AccountDto.cs new file mode 100644 index 0000000..38dfe57 --- /dev/null +++ b/src/Application/Identity/Accounts/AccountDto.cs @@ -0,0 +1,27 @@ +using cuqmbr.TravelGuide.Domain.Entities; +using cuqmbr.TravelGuide.Application.Common.Mappings; + +namespace cuqmbr.TravelGuide.Application.Identity.Accounts; + +public sealed class AccountDto : IMapFrom +{ + public Guid Uuid { get; set; } + + public string Username { get; set; } + + public string Email { get; set; } + + public ICollection Roles { get; set; } + + public void Mapping(MappingProfile profile) + { + profile.CreateMap() + .ForMember( + d => d.Uuid, + opt => opt.MapFrom(s => s.Guid)) + .ForMember( + d => d.Roles, + opt => opt.MapFrom(s => + s.AccountRoles.Select(ar => ar.Role.Value.Name))); + } +} diff --git a/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommand.cs b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommand.cs new file mode 100644 index 0000000..cf5ea4f --- /dev/null +++ b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommand.cs @@ -0,0 +1,13 @@ +using cuqmbr.TravelGuide.Domain.Enums; +using MediatR; + +namespace cuqmbr.TravelGuide.Application.Identity.Accounts.Commands.AddAccount; + +public record AddAccountCommand : IRequest +{ + public string Email { get; set; } + + public string Password { get; set; } + + public ICollection Roles { get; set; } +} diff --git a/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandAuthorizer.cs b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandAuthorizer.cs new file mode 100644 index 0000000..07ff887 --- /dev/null +++ b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandAuthorizer.cs @@ -0,0 +1,31 @@ +using cuqmbr.TravelGuide.Application.Common.Authorization; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; +using MediatR.Behaviors.Authorization; + +namespace cuqmbr.TravelGuide.Application.Identity.Accounts.Commands.AddAccount; + +public class AddAccountCommandAuthorizer : + AbstractRequestAuthorizer +{ + private readonly SessionUserService _sessionAccountService; + + public AddAccountCommandAuthorizer(SessionUserService sessionAccountService) + { + _sessionAccountService = sessionAccountService; + } + + public override void BuildPolicy(AddAccountCommand request) + { + UseRequirement(new MustBeAuthenticatedRequirement + { + IsAuthenticated= _sessionAccountService.IsAuthenticated + }); + + UseRequirement(new MustBeInRolesRequirement + { + RequiredRoles = [IdentityRole.Administrator], + UserRoles = _sessionAccountService.Roles + }); + } +} diff --git a/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandHandler.cs b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandHandler.cs new file mode 100644 index 0000000..0d54557 --- /dev/null +++ b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandHandler.cs @@ -0,0 +1,77 @@ +using MediatR; +using AutoMapper; +using cuqmbr.TravelGuide.Application.Common.Exceptions; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Domain.Entities; +using cuqmbr.TravelGuide.Application.Common.Services; +using System.Security.Cryptography; +using System.Text; + +namespace cuqmbr.TravelGuide.Application.Identity.Accounts.Commands.AddAccount; + +public class AddAccountCommandHandler : + IRequestHandler +{ + private readonly UnitOfWork _unitOfWork; + private readonly IMapper _mapper; + private readonly PasswordHasherService _passwordHasherService; + + public AddAccountCommandHandler( + UnitOfWork unitOfWork, + IMapper mapper, + PasswordHasherService passwordHasherService) + { + _unitOfWork = unitOfWork; + _mapper = mapper; + _passwordHasherService = passwordHasherService; + } + + public async Task Handle( + AddAccountCommand request, + CancellationToken cancellationToken) + { + var user = await _unitOfWork.AccountRepository.GetOneAsync( + e => e.Email == request.Email, + cancellationToken); + + if (user != null) + { + throw new DuplicateEntityException(); + } + + + var roles = (await _unitOfWork.RoleRepository + .GetPageAsync( + e => request.Roles.Contains(e.Value), + 1, request.Roles.Count, cancellationToken)) + .Items; + + var salt = RandomNumberGenerator.GetBytes(128 / 8); + var hash = await _passwordHasherService.HashAsync( + Encoding.UTF8.GetBytes(request.Password), + salt, cancellationToken); + + var saltBase64 = Convert.ToBase64String(salt); + var hashBase64 = Convert.ToBase64String(hash); + + user = new Account() + { + Email = request.Email, + PasswordHash = hashBase64, + PasswordSalt = saltBase64, + AccountRoles = roles.Select(r => new AccountRole() + { + RoleId = r.Id + }) + .ToArray() + }; + + user = await _unitOfWork.AccountRepository.AddOneAsync( + user, cancellationToken); + + await _unitOfWork.SaveAsync(cancellationToken); + _unitOfWork.Dispose(); + + return _mapper.Map(user); + } +} diff --git a/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandValidator.cs b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandValidator.cs new file mode 100644 index 0000000..62586db --- /dev/null +++ b/src/Application/Identity/Accounts/Commands/AddAccount/AddAccountCommandValidator.cs @@ -0,0 +1,36 @@ +using cuqmbr.TravelGuide.Application.Common.FluentValidation; +using cuqmbr.TravelGuide.Application.Common.Services; +using FluentValidation; +using Microsoft.Extensions.Localization; + +namespace cuqmbr.TravelGuide.Application.Identity.Accounts.Commands.AddAccount; + +public class AddAccountCommandValidator : AbstractValidator +{ + public AddAccountCommandValidator( + IStringLocalizer localizer, + SessionCultureService cultureService) + { + RuleFor(v => v.Email) + .NotEmpty() + .WithMessage(localizer["FluentValidation.NotEmpty"]) + .IsEmail() + .WithMessage(localizer["FluentValidation.IsEmail"]); + + RuleFor(v => v.Password) + .NotEmpty() + .WithMessage(localizer["FluentValidation.NotEmpty"]) + .MinimumLength(8) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MinimumLength"], + 8)) + .MaximumLength(64) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MaximumLength"], + 64)); + } +} diff --git a/src/Application/Identity/Accounts/ViewModels/AddAccountViewModel.cs b/src/Application/Identity/Accounts/ViewModels/AddAccountViewModel.cs new file mode 100644 index 0000000..c8c8bc3 --- /dev/null +++ b/src/Application/Identity/Accounts/ViewModels/AddAccountViewModel.cs @@ -0,0 +1,10 @@ +namespace cuqmbr.TravelGuide.Application.Identity.Accounts.ViewModels; + +public sealed class AddAccountViewModel +{ + public string Email { get; set; } + + public string Password { get; set; } + + public ICollection Roles { get; set; } +} diff --git a/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQuery.cs b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQuery.cs new file mode 100644 index 0000000..47936af --- /dev/null +++ b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQuery.cs @@ -0,0 +1,13 @@ +using cuqmbr.TravelGuide.Application.Common.Models; +using MediatR; + +namespace cuqmbr.TravelGuide.Application.Identity.Roles.Queries.GetRolesPage; + +public record GetRolesPageQuery : IRequest> +{ + public int PageNumber { get; set; } = 1; + + public int PageSize { get; set; } = 10; + + public string Search { get; set; } = String.Empty; +} diff --git a/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryAuthorizer.cs b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryAuthorizer.cs new file mode 100644 index 0000000..cc167f7 --- /dev/null +++ b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryAuthorizer.cs @@ -0,0 +1,31 @@ +using cuqmbr.TravelGuide.Application.Common.Authorization; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; +using MediatR.Behaviors.Authorization; + +namespace cuqmbr.TravelGuide.Application.Identity.Roles.Queries.GetRolesPage; + +public class GetRolesPageQueryAuthorizer : + AbstractRequestAuthorizer +{ + private readonly SessionUserService _sessionUserService; + + public GetRolesPageQueryAuthorizer(SessionUserService sessionUserService) + { + _sessionUserService = sessionUserService; + } + + public override void BuildPolicy(GetRolesPageQuery request) + { + UseRequirement(new MustBeAuthenticatedRequirement + { + IsAuthenticated= _sessionUserService.IsAuthenticated + }); + + UseRequirement(new MustBeInRolesRequirement + { + RequiredRoles = [IdentityRole.Administrator], + UserRoles = _sessionUserService.Roles + }); + } +} diff --git a/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryHandler.cs b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryHandler.cs new file mode 100644 index 0000000..718ccd0 --- /dev/null +++ b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryHandler.cs @@ -0,0 +1,25 @@ +using MediatR; +using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Domain.Enums; + +namespace cuqmbr.TravelGuide.Application.Identity.Roles.Queries.GetRolesPage; + +public class GetRolesPageQueryHandler : + IRequestHandler> +{ + public async Task> Handle( + GetRolesPageQuery request, + CancellationToken cancellationToken) + { + var roleStrings = IdentityRole.Enumerations.Select(e => e.Value.Name); + + var roleCount = roleStrings.Count(); + + var filteredRoles = roleStrings + .Where(r => r.Contains(request.Search)) + .ToArray(); + + return new PaginatedList( + filteredRoles, roleCount, request.PageNumber, request.PageSize); + } +} diff --git a/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryValidator.cs b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryValidator.cs new file mode 100644 index 0000000..cbcd22b --- /dev/null +++ b/src/Application/Identity/Roles/Queries/GetRolesPage/GetRolesPageQueryValidator.cs @@ -0,0 +1,43 @@ +using cuqmbr.TravelGuide.Application.Common.Services; +using FluentValidation; +using Microsoft.Extensions.Localization; + +namespace cuqmbr.TravelGuide.Application.Identity.Roles.Queries.GetRolesPage; + +public class GetRolesPageQueryValidator : AbstractValidator +{ + public GetRolesPageQueryValidator( + IStringLocalizer localizer, + SessionCultureService cultureService) + { + RuleFor(v => v.PageNumber) + .GreaterThanOrEqualTo(1) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.GreaterThanOrEqualTo"], + 1)); + + RuleFor(v => v.PageSize) + .GreaterThanOrEqualTo(1) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.GreaterThanOrEqualTo"], + 1)) + .LessThanOrEqualTo(50) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.LessThanOrEqualTo"], + 50)); + + RuleFor(v => v.Search) + .MaximumLength(64) + .WithMessage( + String.Format( + cultureService.Culture, + localizer["FluentValidation.MaximumLength"], + 64)); + } +} diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs index a1ad297..15e36c4 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Payments.LiqPay diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs index 94fcde6..d5ac855 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs @@ -1,8 +1,8 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using cuqmbr.TravelGuide.Application.Common.Exceptions; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation.Results; using Microsoft.Extensions.Localization; diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandValidator.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandValidator.cs index 7fbc8eb..fa1f227 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandValidator.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandValidator.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.FluentValidation; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandHandler.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandHandler.cs index 1f3d54b..ade9098 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandHandler.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandHandler.cs @@ -1,6 +1,6 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Application.Common.Exceptions; using System.Text; using Newtonsoft.Json; diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandValidator.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandValidator.cs index 70faa59..ccec5f5 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandValidator.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/ProcessCallback/ProcessCallbackCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Regions/Commands/AddRegion/AddRegionCommandAuthorizer.cs b/src/Application/Regions/Commands/AddRegion/AddRegionCommandAuthorizer.cs index 05be471..7accab4 100644 --- a/src/Application/Regions/Commands/AddRegion/AddRegionCommandAuthorizer.cs +++ b/src/Application/Regions/Commands/AddRegion/AddRegionCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Regions.Commands.AddRegion; diff --git a/src/Application/Regions/Commands/AddRegion/AddRegionCommandHandler.cs b/src/Application/Regions/Commands/AddRegion/AddRegionCommandHandler.cs index 0b5000e..a2acfcc 100644 --- a/src/Application/Regions/Commands/AddRegion/AddRegionCommandHandler.cs +++ b/src/Application/Regions/Commands/AddRegion/AddRegionCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Regions/Commands/AddRegion/AddRegionCommandValidator.cs b/src/Application/Regions/Commands/AddRegion/AddRegionCommandValidator.cs index 9d3de32..d94ecf2 100644 --- a/src/Application/Regions/Commands/AddRegion/AddRegionCommandValidator.cs +++ b/src/Application/Regions/Commands/AddRegion/AddRegionCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandAuthorizer.cs b/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandAuthorizer.cs index 593eb3b..07f9266 100644 --- a/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandAuthorizer.cs +++ b/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Regions.Commands.DeleteRegion; diff --git a/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandHandler.cs b/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandHandler.cs index aba2cf7..2688c20 100644 --- a/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandHandler.cs +++ b/src/Application/Regions/Commands/DeleteRegion/DeleteRegionCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Regions.Commands.DeleteRegion; diff --git a/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandAuthorizer.cs b/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandAuthorizer.cs index d36cd2d..2ef62f7 100644 --- a/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandAuthorizer.cs +++ b/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Regions.Commands.UpdateRegion; diff --git a/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandHandler.cs b/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandHandler.cs index 5f8d461..44de767 100644 --- a/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandHandler.cs +++ b/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandValidator.cs b/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandValidator.cs index 4366378..dc726ec 100644 --- a/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandValidator.cs +++ b/src/Application/Regions/Commands/UpdateRegion/UpdateRegionCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Regions/Queries/GetRegion/GetRegionQueryAuthorizer.cs b/src/Application/Regions/Queries/GetRegion/GetRegionQueryAuthorizer.cs index 55ebab2..f3fd0f3 100644 --- a/src/Application/Regions/Queries/GetRegion/GetRegionQueryAuthorizer.cs +++ b/src/Application/Regions/Queries/GetRegion/GetRegionQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Regions.Queries.GetRegion; diff --git a/src/Application/Regions/Queries/GetRegion/GetRegionQueryHandler.cs b/src/Application/Regions/Queries/GetRegion/GetRegionQueryHandler.cs index c50a2df..d7c71e2 100644 --- a/src/Application/Regions/Queries/GetRegion/GetRegionQueryHandler.cs +++ b/src/Application/Regions/Queries/GetRegion/GetRegionQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryAuthorizer.cs b/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryAuthorizer.cs index e742d58..248159e 100644 --- a/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryAuthorizer.cs +++ b/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Regions.Queries.GetRegionsPage; diff --git a/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryHandler.cs b/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryHandler.cs index 42c1143..a14c545 100644 --- a/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryHandler.cs +++ b/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryValidator.cs b/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryValidator.cs index b064c3d..8f0ba44 100644 --- a/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryValidator.cs +++ b/src/Application/Regions/Queries/GetRegionsPage/GetRegionsPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Resources/Localization/en-US.json b/src/Application/Resources/Localization/en-US.json index dbec72c..832562f 100644 --- a/src/Application/Resources/Localization/en-US.json +++ b/src/Application/Resources/Localization/en-US.json @@ -1,10 +1,12 @@ { "FluentValidation": { - "MaximumLength": "Must less than {0:G} characters.", "NotEmpty": "Must not be empty.", "GreaterThanOrEqualTo": "Must be greater than or equal to {0}.", "LessThanOrEqualTo": "Must be less than or equal to {0}.", + "MinimumLength": "Length must greater than or equal to {0} characters.", + "MaximumLength": "Length must less than or equal to {0} characters.", "MustBeInEnum": "Must be one of the following: {0}.", + "IsUsername": "May contain lowercase latin characters (a-z), numbers (0-9), hyphens (-), underscores (_) and dots (.).", "IsEmail": "Must be a valid email address according to RFC 5321.", "IsPhoneNumber": "Must be a valid phone number according to ITU-T E.164 with no separator characters.", "IsUnique": "Elements of the collection must be unique." @@ -34,7 +36,7 @@ "Title": "Unauthenticated access prevented.", "Detail": "Request lacks valid authentication credentials for the target resource." }, - "AithenticationException": { + "AuthenticationException": { "Title": "Authentication failed.", "Detail": "Check provided credentials validity." }, diff --git a/src/Application/Routes/Commands/AddRoute/AddRouteCommandAuthorizer.cs b/src/Application/Routes/Commands/AddRoute/AddRouteCommandAuthorizer.cs index 9040482..559ff04 100644 --- a/src/Application/Routes/Commands/AddRoute/AddRouteCommandAuthorizer.cs +++ b/src/Application/Routes/Commands/AddRoute/AddRouteCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Routes.Commands.AddRoute; diff --git a/src/Application/Routes/Commands/AddRoute/AddRouteCommandHandler.cs b/src/Application/Routes/Commands/AddRoute/AddRouteCommandHandler.cs index df3c7cc..7b83fcf 100644 --- a/src/Application/Routes/Commands/AddRoute/AddRouteCommandHandler.cs +++ b/src/Application/Routes/Commands/AddRoute/AddRouteCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Routes/Commands/AddRoute/AddRouteCommandValidator.cs b/src/Application/Routes/Commands/AddRoute/AddRouteCommandValidator.cs index 79fec33..7c33c13 100644 --- a/src/Application/Routes/Commands/AddRoute/AddRouteCommandValidator.cs +++ b/src/Application/Routes/Commands/AddRoute/AddRouteCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandAuthorizer.cs b/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandAuthorizer.cs index 8978db7..ec3a774 100644 --- a/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandAuthorizer.cs +++ b/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Routes.Commands.DeleteRoute; diff --git a/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandHandler.cs b/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandHandler.cs index d1fde57..bc14a6c 100644 --- a/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandHandler.cs +++ b/src/Application/Routes/Commands/DeleteRoute/DeleteRouteCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Routes.Commands.DeleteRoute; diff --git a/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandAuthorizer.cs b/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandAuthorizer.cs index 611b7ae..b4f32e6 100644 --- a/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandAuthorizer.cs +++ b/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Routes.Commands.UpdateRoute; diff --git a/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandHandler.cs b/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandHandler.cs index df48877..f4e1cea 100644 --- a/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandHandler.cs +++ b/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; using FluentValidation.Results; diff --git a/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandValidator.cs b/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandValidator.cs index 60b8485..49314d8 100644 --- a/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandValidator.cs +++ b/src/Application/Routes/Commands/UpdateRoute/UpdateRouteCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Routes/Queries/GetRoute/GetRouteQueryAuthorizer.cs b/src/Application/Routes/Queries/GetRoute/GetRouteQueryAuthorizer.cs index 7ca5727..16ec495 100644 --- a/src/Application/Routes/Queries/GetRoute/GetRouteQueryAuthorizer.cs +++ b/src/Application/Routes/Queries/GetRoute/GetRouteQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Routes.Queries.GetRoute; diff --git a/src/Application/Routes/Queries/GetRoute/GetRouteQueryHandler.cs b/src/Application/Routes/Queries/GetRoute/GetRouteQueryHandler.cs index 0f8f2db..07e1f16 100644 --- a/src/Application/Routes/Queries/GetRoute/GetRouteQueryHandler.cs +++ b/src/Application/Routes/Queries/GetRoute/GetRouteQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; using cuqmbr.TravelGuide.Domain.Entities; diff --git a/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryAuthorizer.cs b/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryAuthorizer.cs index dc64fa3..57e0d8e 100644 --- a/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryAuthorizer.cs +++ b/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Routes.Queries.GetRoutesPage; diff --git a/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryHandler.cs b/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryHandler.cs index 15e3304..38faa54 100644 --- a/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryHandler.cs +++ b/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryValidator.cs b/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryValidator.cs index e38376d..945bebc 100644 --- a/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryValidator.cs +++ b/src/Application/Routes/Queries/GetRoutesPage/GetRoutesPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandAuthorizer.cs b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandAuthorizer.cs index b2c5deb..256e9a3 100644 --- a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandAuthorizer.cs +++ b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.TicketGroups.Commands.AddTicketGroup; diff --git a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs index 25d4092..d3edfc0 100644 --- a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs +++ b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs @@ -1,10 +1,10 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; using Microsoft.Extensions.Localization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation.Results; diff --git a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandValidator.cs b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandValidator.cs index 58a8029..03c95c6 100644 --- a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandValidator.cs +++ b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandValidator.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.FluentValidation; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/TicketGroups/Commands/RemoveOldReservedTicketGroups/RemoveOldReservedTicketGroupsCommandHandler.cs b/src/Application/TicketGroups/Commands/RemoveOldReservedTicketGroups/RemoveOldReservedTicketGroupsCommandHandler.cs index 37373af..e14af8a 100644 --- a/src/Application/TicketGroups/Commands/RemoveOldReservedTicketGroups/RemoveOldReservedTicketGroupsCommandHandler.cs +++ b/src/Application/TicketGroups/Commands/RemoveOldReservedTicketGroups/RemoveOldReservedTicketGroupsCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.Application.TicketGroups diff --git a/src/Application/Trains/Commands/AddTrain/AddTrainCommandAuthorizer.cs b/src/Application/Trains/Commands/AddTrain/AddTrainCommandAuthorizer.cs index 36fdbf4..256c7ea 100644 --- a/src/Application/Trains/Commands/AddTrain/AddTrainCommandAuthorizer.cs +++ b/src/Application/Trains/Commands/AddTrain/AddTrainCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Trains.Commands.AddTrain; diff --git a/src/Application/Trains/Commands/AddTrain/AddTrainCommandHandler.cs b/src/Application/Trains/Commands/AddTrain/AddTrainCommandHandler.cs index 4644d93..b420c50 100644 --- a/src/Application/Trains/Commands/AddTrain/AddTrainCommandHandler.cs +++ b/src/Application/Trains/Commands/AddTrain/AddTrainCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Trains/Commands/AddTrain/AddTrainCommandValidator.cs b/src/Application/Trains/Commands/AddTrain/AddTrainCommandValidator.cs index 092bbc9..52e38e8 100644 --- a/src/Application/Trains/Commands/AddTrain/AddTrainCommandValidator.cs +++ b/src/Application/Trains/Commands/AddTrain/AddTrainCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandAuthorizer.cs b/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandAuthorizer.cs index df31b90..9e888b6 100644 --- a/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandAuthorizer.cs +++ b/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Trains.Commands.DeleteTrain; diff --git a/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandHandler.cs b/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandHandler.cs index 94d3ab0..b3cc70b 100644 --- a/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandHandler.cs +++ b/src/Application/Trains/Commands/DeleteTrain/DeleteTrainCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.Trains.Commands.DeleteTrain; diff --git a/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandAuthorizer.cs b/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandAuthorizer.cs index c4dd607..6a5f59c 100644 --- a/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandAuthorizer.cs +++ b/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Trains.Commands.UpdateTrain; diff --git a/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandHandler.cs b/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandHandler.cs index e7be03f..0607955 100644 --- a/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandHandler.cs +++ b/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandValidator.cs b/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandValidator.cs index b23fb12..6a2c65e 100644 --- a/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandValidator.cs +++ b/src/Application/Trains/Commands/UpdateTrain/UpdateTrainCommandValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/Trains/Queries/GetTrain/GetTrainQueryAuthorizer.cs b/src/Application/Trains/Queries/GetTrain/GetTrainQueryAuthorizer.cs index 7416f04..dc417e7 100644 --- a/src/Application/Trains/Queries/GetTrain/GetTrainQueryAuthorizer.cs +++ b/src/Application/Trains/Queries/GetTrain/GetTrainQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Trains.Queries.GetTrain; diff --git a/src/Application/Trains/Queries/GetTrain/GetTrainQueryHandler.cs b/src/Application/Trains/Queries/GetTrain/GetTrainQueryHandler.cs index afe796b..fe3788e 100644 --- a/src/Application/Trains/Queries/GetTrain/GetTrainQueryHandler.cs +++ b/src/Application/Trains/Queries/GetTrain/GetTrainQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; diff --git a/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryAuthorizer.cs b/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryAuthorizer.cs index 2a68aaa..5ce63f8 100644 --- a/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryAuthorizer.cs +++ b/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Trains.Queries.GetTrainsPage; diff --git a/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryHandler.cs b/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryHandler.cs index 49a0c7d..39892ae 100644 --- a/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryHandler.cs +++ b/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryValidator.cs b/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryValidator.cs index a4d9410..087a2b1 100644 --- a/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryValidator.cs +++ b/src/Application/Trains/Queries/GetTrainsPage/GetTrainsPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryAuthorizer.cs b/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryAuthorizer.cs index 19ba695..fbc4307 100644 --- a/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryAuthorizer.cs +++ b/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application diff --git a/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryHandler.cs b/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryHandler.cs index f25ba6c..ee286ee 100644 --- a/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryHandler.cs +++ b/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryHandler.cs @@ -1,10 +1,10 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using QuikGraph; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using cuqmbr.TravelGuide.Application.Common.Extensions; diff --git a/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryValidator.cs b/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryValidator.cs index e12f958..9ed2b6f 100644 --- a/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryValidator.cs +++ b/src/Application/VehicleEnrollmentSearch/Queries/SearchAll/SearchAllQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryAuthorizer.cs b/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryAuthorizer.cs index 97eda14..055a5d4 100644 --- a/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryAuthorizer.cs +++ b/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application diff --git a/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryHandler.cs b/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryHandler.cs index afbcc45..17318b5 100644 --- a/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryHandler.cs +++ b/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryHandler.cs @@ -1,11 +1,11 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using QuikGraph; using QuikGraph.Algorithms; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.Application diff --git a/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryValidator.cs b/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryValidator.cs index 19bb4c4..674e636 100644 --- a/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryValidator.cs +++ b/src/Application/VehicleEnrollmentSearch/Queries/SearchShortest/SearchShortestQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandAuthorizer.cs b/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandAuthorizer.cs index dbaeae9..38f64d6 100644 --- a/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandAuthorizer.cs +++ b/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments diff --git a/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandHandler.cs b/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandHandler.cs index b5d8d9c..dc82b55 100644 --- a/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandHandler.cs +++ b/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Domain.Entities; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; diff --git a/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandValidator.cs b/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandValidator.cs index 1df07c1..415a15d 100644 --- a/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandValidator.cs +++ b/src/Application/VehicleEnrollments/Commands/AddVehicleEnrollment/AddVehicleEnrollmentCommandValidator.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.FluentValidation; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandAuthorizer.cs b/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandAuthorizer.cs index ecc544b..4f9c61f 100644 --- a/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandAuthorizer.cs +++ b/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments.Commands.DeleteVehicleEnrollment; diff --git a/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandHandler.cs b/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandHandler.cs index 0dbb95b..b743321 100644 --- a/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandHandler.cs +++ b/src/Application/VehicleEnrollments/Commands/DeleteVehicleEnrollment/DeleteVehicleEnrollmentCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments.Commands.DeleteVehicleEnrollment; diff --git a/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandAuthorizer.cs b/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandAuthorizer.cs index 9831597..ad1f9d1 100644 --- a/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandAuthorizer.cs +++ b/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments diff --git a/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandHandler.cs b/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandHandler.cs index fb3aed7..0251fef 100644 --- a/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandHandler.cs +++ b/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandHandler.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Exceptions; using FluentValidation.Results; diff --git a/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandValidator.cs b/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandValidator.cs index 2530e8c..9e33153 100644 --- a/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandValidator.cs +++ b/src/Application/VehicleEnrollments/Commands/UpdateVehicleEnrollment/UpdateVehicleEnrollmentCommandValidator.cs @@ -1,5 +1,5 @@ using cuqmbr.TravelGuide.Application.Common.FluentValidation; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryAuthorizer.cs b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryAuthorizer.cs index 58fe68f..a026fff 100644 --- a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryAuthorizer.cs +++ b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments diff --git a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryHandler.cs b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryHandler.cs index 3b1ad69..f41760e 100644 --- a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryHandler.cs +++ b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollment/GetVehicleEnrollmentQueryHandler.cs @@ -1,8 +1,8 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using AutoMapper; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments diff --git a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryAuthorizer.cs b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryAuthorizer.cs index fc83c92..4d69da0 100644 --- a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryAuthorizer.cs +++ b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryAuthorizer.cs @@ -1,6 +1,6 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments.Queries.GetVehicleEnrollmentsPage; diff --git a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryHandler.cs b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryHandler.cs index 70cfc40..af32246 100644 --- a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryHandler.cs +++ b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryHandler.cs @@ -1,9 +1,9 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Application.Common.Extensions; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.Application.VehicleEnrollments diff --git a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryValidator.cs b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryValidator.cs index 5e0ba41..2d1d71b 100644 --- a/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryValidator.cs +++ b/src/Application/VehicleEnrollments/Queries/GetVehicleEnrollmentsPage/GetVehicleEnrollmentsPageQueryValidator.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using FluentValidation; using Microsoft.Extensions.Localization; diff --git a/src/Application/packages.lock.json b/src/Application/packages.lock.json index 14b60f0..43c1312 100644 --- a/src/Application/packages.lock.json +++ b/src/Application/packages.lock.json @@ -48,6 +48,15 @@ "MediatR.Contracts": "2.0.1" } }, + "Microsoft.AspNetCore.Authentication.JwtBearer": { + "type": "Direct", + "requested": "[9.0.5, )", + "resolved": "9.0.5", + "contentHash": "8J04KPX5NCo6j5AjY/rgeLTceMBJ8Sq4k+YNxN/7hCrbCH1iwHVw7VGGvlCscj615ewMX3jYDmxxLdutbSPOcA==", + "dependencies": { + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" + } + }, "Microsoft.Extensions.Logging": { "type": "Direct", "requested": "[9.0.4, )", @@ -59,6 +68,25 @@ "Microsoft.Extensions.Options": "9.0.4" } }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Direct", + "requested": "[8.11.0, )", + "resolved": "8.11.0", + "contentHash": "rLvApg2vqs/Kz5kVHwHUMAe3owInYrsPX8QP8CQktubX9R63P+J47nR/IOS4n6ddJCvGInUGRBKqcBGJtuA4Rw==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.11.0" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Direct", + "requested": "[8.11.0, )", + "resolved": "8.11.0", + "contentHash": "E0iKSD9vv9X+tbHGriMTLkSNK/OOjxOPuf1dt9q32d25Ig+OZaidUqDoUTSS3mWTvPw+x5oXrCTHtDatbzRzTQ==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.11.0" + } + }, "Newtonsoft.Json": { "type": "Direct", "requested": "[13.0.3, )", @@ -182,6 +210,45 @@ "resolved": "9.0.4", "contentHash": "SPFyMjyku1nqTFFJ928JAMd0QnRe4xjE7KeKnZMWXf3xk+6e0WiOZAluYtLdbJUXtsl2cCRSi8cBquJ408k8RA==" }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "X92UuBmvHYtsVrD+R+senFn6wOtSVtliSZNTZI8oHD+WqhYLmLNlHH6avYcbXqEznozxshSYzD/DVAuz54jjtg==" + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "/JNOMdYOQ4Tgbdwu9GbEcRJEpzakizuECCE8dCgY5lKXyqZUdAKXyeq4zITgS81eZYThqjhQZUYaJxOPofbmrg==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.11.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.0.1" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "8.0.1", + "System.IdentityModel.Tokens.Jwt": "8.0.1" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "GJw3bYkWpOgvN3tJo5X4lYUeIFA2HD293FPUhKmp7qxS+g5ywAb34Dnd3cDAFLkcMohy5XTpoaZ4uAHuw0uSPQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.0.1", + "Microsoft.IdentityModel.Tokens": "8.0.1" + } + }, "domain": { "type": "Project" } diff --git a/src/Configuration/Application/Configuration.cs b/src/Configuration/Application/Configuration.cs index cfbd70c..4f078cb 100644 --- a/src/Configuration/Application/Configuration.cs +++ b/src/Configuration/Application/Configuration.cs @@ -10,6 +10,8 @@ using MediatR.Behaviors.Authorization.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using cuqmbr.TravelGuide.Application.Common.Authorization; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; namespace cuqmbr.TravelGuide.Configuration.Application; @@ -18,15 +20,16 @@ public static class Configuration public static IServiceCollection ConfigureApplication( this IServiceCollection services) { - var configurationOptions = services.BuildServiceProvider().GetService< + var configuration = services.BuildServiceProvider().GetService< IOptions>() .Value; return services - .AddLocalization(configurationOptions.Localization) + .AddLocalization(configuration.Localization) .AddFluentValidation() .AddAutoMapper() - .AddMediatR(); + .AddMediatR() + .AddAuthentication(configuration.JsonWebToken); } private static IServiceCollection AddFluentValidation( @@ -91,4 +94,42 @@ public static class Configuration .Assembly); }); } + + private static IServiceCollection AddAuthentication( + this IServiceCollection services, + JsonWebTokenConfigurationOptions configuration) + { + services + .AddAuthentication(options => + { + options.DefaultAuthenticateScheme = + JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = + JwtBearerDefaults.AuthenticationScheme; + options.DefaultScheme = + JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(options => + { + options.IncludeErrorDetails = true; + options.SaveToken = true; + options.RequireHttpsMetadata = false; + options.TokenValidationParameters = + new TokenValidationParameters() + { + ValidateIssuer = false, + ValidateAudience = false, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidAudience = configuration.Audience, + ValidIssuer = configuration.Issuer, + ClockSkew = TimeSpan.Zero, + IssuerSigningKey = new SymmetricSecurityKey( + Encoding.UTF8.GetBytes( + configuration.IssuerSigningKey)) + }; + }); + + return services; + } } diff --git a/src/Configuration/Configuration/Configuration.cs b/src/Configuration/Configuration/Configuration.cs index 5a8d825..923b7f8 100644 --- a/src/Configuration/Configuration/Configuration.cs +++ b/src/Configuration/Configuration/Configuration.cs @@ -6,8 +6,6 @@ using ApplicationConfigurationOptions = cuqmbr.TravelGuide.Application.ConfigurationOptions; using InfrastructureConfigurationOptions = cuqmbr.TravelGuide.Infrastructure.ConfigurationOptions; -using IdentityConfigurationOptions = - cuqmbr.TravelGuide.Identity.ConfigurationOptions; namespace cuqmbr.TravelGuide.Configuration.Configuration; @@ -39,10 +37,6 @@ public static class Configuration configuration.GetSection( InfrastructureConfigurationOptions.SectionName)); - services.AddOptions().Bind( - configuration.GetSection( - IdentityConfigurationOptions.SectionName)); - return services; } } diff --git a/src/Configuration/Identity/Configuration.cs b/src/Configuration/Identity/Configuration.cs deleted file mode 100644 index 0aba448..0000000 --- a/src/Configuration/Identity/Configuration.cs +++ /dev/null @@ -1,99 +0,0 @@ -using cuqmbr.TravelGuide.Identity.Persistence.PostgreSql; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using IdentityUser = cuqmbr.TravelGuide.Identity.Models.IdentityUser; -using IdentityRole = cuqmbr.TravelGuide.Identity.Models.IdentityRole; -using Microsoft.EntityFrameworkCore; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Identity.Services; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.IdentityModel.Tokens; -using System.Text; -using cuqmbr.TravelGuide.Identity.Exceptions; -using Microsoft.EntityFrameworkCore.Diagnostics; - -namespace cuqmbr.TravelGuide.Configuration.Identity; - -public static class Configuration -{ - public static IServiceCollection ConfigureIdentity( - this IServiceCollection services) - { - using var configurationServiceProvider = services.BuildServiceProvider(); - var configuration = configurationServiceProvider.GetService< - IOptions>() - .Value; - - // TODO: Make enum from available datastore types - - if (configuration.Datastore.Type.ToLower().Equals("postgresql")) - { - services.AddDbContext(options => - { - options.UseNpgsql( - configuration.Datastore.ConnectionString, - options => - { - options.MigrationsHistoryTable( - "ef_migrations_history", - configuration.Datastore.PartitionName); - }); - options.ConfigureWarnings(w => w.Ignore( - RelationalEventId.PendingModelChangesWarning)); - }); - - services - .AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); - - if (configuration.Datastore.Migrate) - { - using var dbContextServiceProvider = services.BuildServiceProvider(); - PostgreSqlInitializer.Initialize(dbContextServiceProvider); - } - } - else - { - throw new UnSupportedDatastoreException( - $"{configuration.Datastore.Type} datastore is not supported."); - } - - services - .AddScoped(); - - services - .AddAuthentication(options => - { - options.DefaultAuthenticateScheme = - JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = - JwtBearerDefaults.AuthenticationScheme; - options.DefaultScheme = - JwtBearerDefaults.AuthenticationScheme; - }) - .AddJwtBearer(options => - { - options.IncludeErrorDetails = true; - options.SaveToken = true; - options.RequireHttpsMetadata = false; - options.TokenValidationParameters = - new TokenValidationParameters() - { - ValidateIssuer = false, - ValidateAudience = false, - ValidateLifetime = true, - ValidateIssuerSigningKey = true, - ValidAudience = configuration.JsonWebToken.Audience, - ValidIssuer = configuration.JsonWebToken.Issuer, - ClockSkew = TimeSpan.Zero, - IssuerSigningKey = new SymmetricSecurityKey( - Encoding.UTF8.GetBytes( - configuration.JsonWebToken.IssuerSigningKey)) - }; - }); - - return services; - } -} diff --git a/src/Configuration/Infrastructure/Configuration.cs b/src/Configuration/Infrastructure/Configuration.cs index 3df6bb0..1c35fe6 100644 --- a/src/Configuration/Infrastructure/Configuration.cs +++ b/src/Configuration/Infrastructure/Configuration.cs @@ -1,5 +1,5 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; using cuqmbr.TravelGuide.Infrastructure.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using Microsoft.Extensions.DependencyInjection; namespace cuqmbr.TravelGuide.Configuration.Infrastructure; @@ -13,11 +13,14 @@ public static class Configuration .AddHttpClient(); services + .AddScoped< + PasswordHasherService, + Pbkdf2PasswordHasherService>() .AddScoped< CurrencyConverterService, ExchangeApiCurrencyConverterService>() .AddScoped< - cuqmbr.TravelGuide.Application.Common.Interfaces.Services.LiqPayPaymentService, + cuqmbr.TravelGuide.Application.Common.Services.LiqPayPaymentService, cuqmbr.TravelGuide.Infrastructure.Services.LiqPayPaymentService>(); return services; diff --git a/src/Configuration/Persistence/Configuration.cs b/src/Configuration/Persistence/Configuration.cs index a506520..4ab16fb 100644 --- a/src/Configuration/Persistence/Configuration.cs +++ b/src/Configuration/Persistence/Configuration.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Persistence; using cuqmbr.TravelGuide.Persistence.Exceptions; using Microsoft.EntityFrameworkCore; @@ -45,10 +45,10 @@ public static class Configuration if (configuration.Migrate) { - using var dbContextServiceProvider = + using var serviceProvider = services.BuildServiceProvider(); var dbContext = - dbContextServiceProvider.GetService(); + serviceProvider.GetService(); PostgreSqlDbInitializer.Initialize(dbContext); } } @@ -79,8 +79,7 @@ public static class Configuration if (configuration.Seed) { using var serviceProvider = services.BuildServiceProvider(); - var unitOfWork = serviceProvider.GetService(); - DbSeeder.Seed(unitOfWork); + DbSeeder.Seed(serviceProvider); } return services; diff --git a/src/Configuration/packages.lock.json b/src/Configuration/packages.lock.json index f253c37..bba215c 100644 --- a/src/Configuration/packages.lock.json +++ b/src/Configuration/packages.lock.json @@ -236,8 +236,8 @@ }, "Microsoft.AspNetCore.Authentication.JwtBearer": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0HgfWPfnjlzWFbW4pw6FYNuIMV8obVU+MUkiZ33g4UOpvZcmdWzdayfheKPZ5+EUly8SvfgW0dJwwIrW4IVLZQ==", + "resolved": "9.0.5", + "contentHash": "8J04KPX5NCo6j5AjY/rgeLTceMBJ8Sq4k+YNxN/7hCrbCH1iwHVw7VGGvlCscj615ewMX3jYDmxxLdutbSPOcA==", "dependencies": { "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" } @@ -268,15 +268,15 @@ }, "Microsoft.AspNetCore.Cryptography.Internal": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "E4pHyEb2Ul5a6bIwraGtw9TN39a/C2asyVPEJoyItc0reV4Y26FsPcEdcXyKjBbP4kSz9iU1Cz4Yhx/aOFPpqA==" + "resolved": "2.3.0", + "contentHash": "/qy5r0CD40OccajzDmX3gBfqqxpAJkcXoqlVz0YR70x3gTRq/VuseDU/lZ5eh8vM+KCdmPFAtyGcRWxTyXxuYg==" }, "Microsoft.AspNetCore.Cryptography.KeyDerivation": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "5v9Kj2arRrCftLKW80Hfj31HkNnjcKyw57lQhF84drvGxJlCR63J0zMM1sMM+Hc+KCQjuoDmHtjwN0uOT+X3ag==", + "resolved": "2.3.0", + "contentHash": "S7pph0JuBkgNqtyiIdLtQ5icZxmpX502zxxvHuMtM5W7IR3CKl1r/Cup+i6+E6B7IF3BeZYF4O3RbcA108syig==", "dependencies": { - "Microsoft.AspNetCore.Cryptography.Internal": "9.0.4" + "Microsoft.AspNetCore.Cryptography.Internal": "2.3.0" } }, "Microsoft.AspNetCore.DataProtection": { @@ -359,15 +359,6 @@ "Microsoft.Extensions.Primitives": "8.0.0" } }, - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "IC3X6Db6H0cXdE2zGtyk/jmSwXhHbJZaiNpg7TNFV/Biu/NgO6l/GuwgE0D1U6U9pca00WsqxESkNov+WA77CA==", - "dependencies": { - "Microsoft.EntityFrameworkCore.Relational": "9.0.4", - "Microsoft.Extensions.Identity.Stores": "9.0.4" - } - }, "Microsoft.AspNetCore.Metadata": { "type": "Transitive", "resolved": "9.0.0", @@ -564,22 +555,13 @@ }, "Microsoft.Extensions.Identity.Core": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "KKfCsoIHFGZmmCEjZBPuvDW0pCjboMru/Z3vbEyC/OIwUVeKrdPugFyjc81i7rNSjcPcDxVvGl/Ks8HLelKocg==", + "resolved": "2.3.0", + "contentHash": "yR0eFnUbAM2k+q5QsX0NKinfShIe1B/aiHXEywiNT5Cs2MvEhxQIbIn5rWXnEAfmwW+i+t5D8odPSEHz/taIyQ==", "dependencies": { - "Microsoft.AspNetCore.Cryptography.KeyDerivation": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4" - } - }, - "Microsoft.Extensions.Identity.Stores": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0F6lSngwyXzrv+qtX46nhHYBOlPxEzj0qyCCef1kvlyEYhbj8kBL13FuDk4nEPkzk1yVjZgsnXBG19+TrNdakQ==", - "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "9.0.4", - "Microsoft.Extensions.Identity.Core": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" + "Microsoft.AspNetCore.Cryptography.KeyDerivation": "2.3.0", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Options": "8.0.2", + "System.ComponentModel.Annotations": "5.0.0" } }, "Microsoft.Extensions.Localization": { @@ -651,23 +633,23 @@ }, "Microsoft.IdentityModel.Abstractions": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "0lKw+f3vkmV9t3PLe6sY3xPrYrHYiMRFxuOse5CMkKPxhQYiabpfJsuk6wX2RrVQ86Dn+t/8poHpH0nbp6sFvA==" + "resolved": "8.11.0", + "contentHash": "X92UuBmvHYtsVrD+R+senFn6wOtSVtliSZNTZI8oHD+WqhYLmLNlHH6avYcbXqEznozxshSYzD/DVAuz54jjtg==" }, "Microsoft.IdentityModel.JsonWebTokens": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "lepOkZZTMfJCPSnWITXxV+4Wxb54g+9oIybs9YovlOzZWuR1i2DOpzaDgSe+piDJaGtnSrcUlcB9fZ5Swur7Uw==", + "resolved": "8.11.0", + "contentHash": "rLvApg2vqs/Kz5kVHwHUMAe3owInYrsPX8QP8CQktubX9R63P+J47nR/IOS4n6ddJCvGInUGRBKqcBGJtuA4Rw==", "dependencies": { - "Microsoft.IdentityModel.Tokens": "8.8.0" + "Microsoft.IdentityModel.Tokens": "8.11.0" } }, "Microsoft.IdentityModel.Logging": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "sUyoxzg/WBZobbFLJK8loT9IILKtS9ePmWu5B11ogQqhSHppE6SRZKw0fhI6Fd16X6ey52cbbWc2rvMBC98EQA==", + "resolved": "8.11.0", + "contentHash": "/JNOMdYOQ4Tgbdwu9GbEcRJEpzakizuECCE8dCgY5lKXyqZUdAKXyeq4zITgS81eZYThqjhQZUYaJxOPofbmrg==", "dependencies": { - "Microsoft.IdentityModel.Abstractions": "8.8.0" + "Microsoft.IdentityModel.Abstractions": "8.11.0" } }, "Microsoft.IdentityModel.Protocols": { @@ -689,11 +671,11 @@ }, "Microsoft.IdentityModel.Tokens": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "09hnbUJh/18gUmu5nCVFMvyzAFC4l1qyc4bwSJaKzUBqHN7aNDwmSx8dE3/MMJImbvnKq9rEtkkgnrS/OUBtjA==", + "resolved": "8.11.0", + "contentHash": "E0iKSD9vv9X+tbHGriMTLkSNK/OOjxOPuf1dt9q32d25Ig+OZaidUqDoUTSS3mWTvPw+x5oXrCTHtDatbzRzTQ==", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.IdentityModel.Logging": "8.8.0" + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.11.0" } }, "Microsoft.Net.Http.Headers": { @@ -782,6 +764,11 @@ "resolved": "4.6.0", "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==" + }, "System.IdentityModel.Tokens.Jwt": { "type": "Transitive", "resolved": "8.0.1", @@ -842,7 +829,10 @@ "FluentValidation": "[11.11.0, )", "MediatR": "[12.4.1, )", "MediatR.Behaviors.Authorization": "[12.2.0, )", + "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.5, )", "Microsoft.Extensions.Logging": "[9.0.4, )", + "Microsoft.IdentityModel.JsonWebTokens": "[8.11.0, )", + "Microsoft.IdentityModel.Tokens": "[8.11.0, )", "Newtonsoft.Json": "[13.0.3, )", "QuikGraph": "[2.5.0, )", "System.Linq.Dynamic.Core": "[1.6.2, )" @@ -851,19 +841,6 @@ "domain": { "type": "Project" }, - "identity": { - "type": "Project", - "dependencies": { - "Application": "[1.0.0, )", - "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.4, )", - "Microsoft.AspNetCore.Identity": "[2.3.1, )", - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "[9.0.4, )", - "Microsoft.Extensions.Options": "[9.0.4, )", - "Microsoft.IdentityModel.JsonWebTokens": "[8.8.0, )", - "Microsoft.IdentityModel.Tokens": "[8.8.0, )", - "Npgsql.EntityFrameworkCore.PostgreSQL": "[9.0.4, )" - } - }, "infrastructure": { "type": "Project", "dependencies": { diff --git a/src/Domain/Entities/Account.cs b/src/Domain/Entities/Account.cs new file mode 100644 index 0000000..b477df4 --- /dev/null +++ b/src/Domain/Entities/Account.cs @@ -0,0 +1,16 @@ +namespace cuqmbr.TravelGuide.Domain.Entities; + +public sealed class Account : EntityBase +{ + public string Username { get; set; } + + public string Email { get; set; } + + public string PasswordHash { get; set; } + + public string PasswordSalt { get; set; } + + public ICollection AccountRoles { get; set; } + + public ICollection RefreshTokens { get; set; } +} diff --git a/src/Domain/Entities/AccountRole.cs b/src/Domain/Entities/AccountRole.cs new file mode 100644 index 0000000..fd28b0d --- /dev/null +++ b/src/Domain/Entities/AccountRole.cs @@ -0,0 +1,12 @@ +namespace cuqmbr.TravelGuide.Domain.Entities; + +public sealed class AccountRole : EntityBase +{ + public long AccountId { get; set; } + + public Account Account { get; set; } + + public long RoleId { get; set; } + + public Role Role { get; set; } +} diff --git a/src/Domain/Entities/RefreshToken.cs b/src/Domain/Entities/RefreshToken.cs new file mode 100644 index 0000000..833d0e0 --- /dev/null +++ b/src/Domain/Entities/RefreshToken.cs @@ -0,0 +1,20 @@ +namespace cuqmbr.TravelGuide.Domain.Entities; + +public class RefreshToken : EntityBase +{ + public string Value { get; set; } = null!; + + public DateTimeOffset CreationTime { get; set; } + + public DateTimeOffset ExpirationTime { get; set; } + + public DateTimeOffset? RevocationTime { get; set; } + + public bool IsExpired => DateTimeOffset.UtcNow >= ExpirationTime; + + public bool IsActive => RevocationTime == null && !IsExpired; + + public long AccountId { get; set; } + + public Account Account { get; set; } +} diff --git a/src/Domain/Entities/Role.cs b/src/Domain/Entities/Role.cs new file mode 100644 index 0000000..a0b4539 --- /dev/null +++ b/src/Domain/Entities/Role.cs @@ -0,0 +1,10 @@ +using cuqmbr.TravelGuide.Domain.Enums; + +namespace cuqmbr.TravelGuide.Domain.Entities; + +public sealed class Role : EntityBase +{ + public IdentityRole Value { get; set; } + + public ICollection AccountRoles { get; set; } +} diff --git a/src/Application/Common/Models/IdentityRole.cs b/src/Domain/Enums/IdentityRole.cs similarity index 52% rename from src/Application/Common/Models/IdentityRole.cs rename to src/Domain/Enums/IdentityRole.cs index 5636e3b..4424fb0 100644 --- a/src/Application/Common/Models/IdentityRole.cs +++ b/src/Domain/Enums/IdentityRole.cs @@ -1,11 +1,11 @@ -using cuqmbr.TravelGuide.Domain.Enums; - -namespace cuqmbr.TravelGuide.Application.Common.Models; +namespace cuqmbr.TravelGuide.Domain.Enums; public abstract class IdentityRole : Enumeration { public static readonly IdentityRole Administrator = new AdministratorRole(); public static readonly IdentityRole User = new UserRole(); + public static readonly IdentityRole CompanyOwner = new CompanyOwnerRole(); + public static readonly IdentityRole CompanyEmployee = new CompanyEmployeeRole(); protected IdentityRole(int value, string name) : base(value, name) { } @@ -18,4 +18,14 @@ public abstract class IdentityRole : Enumeration { public UserRole() : base(1, "user") { } } + + private sealed class CompanyOwnerRole : IdentityRole + { + public CompanyOwnerRole() : base(2, "company_owner") { } + } + + private sealed class CompanyEmployeeRole : IdentityRole + { + public CompanyEmployeeRole() : base(3, "company_employee") { } + } } diff --git a/src/HttpApi/Controllers/AuthenticationController.cs b/src/HttpApi/Controllers/AuthenticationController.cs index ecb2a62..6ee61b4 100644 --- a/src/HttpApi/Controllers/AuthenticationController.cs +++ b/src/HttpApi/Controllers/AuthenticationController.cs @@ -4,10 +4,6 @@ using cuqmbr.TravelGuide.Application.Authenticaion.Queries.Login; using cuqmbr.TravelGuide.Application.Authenticaion.Commands.Register; using cuqmbr.TravelGuide.Application.Authenticaion.Commands.RenewAccessToken; using cuqmbr.TravelGuide.Application.Authenticaion.Commands.RevokeRefreshToken; -using cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RenewAccessTokenWithCookie; -using cuqmbr.TravelGuide.Application.Authenticaion.Commands - .RevokeRefreshTokenWithCookie; namespace cuqmbr.TravelGuide.HttpApi.Controllers; @@ -30,28 +26,6 @@ public class AuthenticationController : ControllerBase return await Mediator.Send(query, cancellationToken); } - // [HttpPost("loginWithCookie")] - // public async Task LoginWithCookie( - // [FromBody] LoginQuery query, - // CancellationToken cancellationToken) - // { - // var tokens = await Mediator.Send(query, cancellationToken); - // - // HttpContext.Response.Cookies.Delete("refreshToken"); - // - // var cookieOptions = new CookieOptions() - // { - // Path = "/", - // Expires = DateTimeOffset.MaxValue, - // HttpOnly = true - // }; - // - // HttpContext.Response.Cookies.Append( - // "refreshToken", tokens.RefreshToken, cookieOptions); - // - // return tokens; - // } - [HttpPost("renewAccessToken")] public async Task RenewAccessToken( [FromBody] RenewAccessTokenCommand command, @@ -60,14 +34,6 @@ public class AuthenticationController : ControllerBase return await Mediator.Send(command, cancellationToken); } - // [HttpPost("renewAccessTokenWithCookie")] - // public async Task RenewAccessTokenWithCookie( - // [FromBody] RenewAccessTokenWithCookieCommand command, - // CancellationToken cancellationToken) - // { - // return await Mediator.Send(command, cancellationToken); - // } - [HttpPost("revokeRefreshToken")] public async Task RevokeRefreshToken( [FromBody] RevokeRefreshTokenCommand command, @@ -75,13 +41,4 @@ public class AuthenticationController : ControllerBase { await Mediator.Send(command, cancellationToken); } - - // [HttpPost("revokeRefreshTokenWithCookie")] - // public async Task RevokeRefreshTokenWithCookie( - // [FromBody] RevokeRefreshTokenWithCookieCommand command, - // CancellationToken cancellationToken) - // { - // await Mediator.Send(command, cancellationToken); - // HttpContext.Response.Cookies.Delete("refreshToken"); - // } } diff --git a/src/HttpApi/Controllers/IdentityController.cs b/src/HttpApi/Controllers/IdentityController.cs new file mode 100644 index 0000000..bacb072 --- /dev/null +++ b/src/HttpApi/Controllers/IdentityController.cs @@ -0,0 +1,242 @@ +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; +using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.ViewModels; +using cuqmbr.TravelGuide.Domain.Enums; +using cuqmbr.TravelGuide.Application.Identity.Roles.Queries.GetRolesPage; +using cuqmbr.TravelGuide.Application.Identity.Accounts; +using cuqmbr.TravelGuide.Application.Identity.Accounts.ViewModels; +using cuqmbr.TravelGuide.Application.Identity.Accounts.Commands.AddAccount; +// using cuqmbr.TravelGuide.Application.Identity.Commands.AddIdentity; +// using cuqmbr.TravelGuide.Application.Identity.Queries.GetIdentityPage; +// using cuqmbr.TravelGuide.Application.Identity.Queries.GetIdentity; +// using cuqmbr.TravelGuide.Application.Identity.Commands.UpdateIdentity; +// using cuqmbr.TravelGuide.Application.Identity.Commands.DeleteIdentity; +// using cuqmbr.TravelGuide.Application.Identity.ViewModels; + +namespace cuqmbr.TravelGuide.HttpApi.Controllers; + +[Route("identity")] +public class IdentityController : ControllerBase +{ + [HttpGet("roles")] + [SwaggerOperation("Get a list of all roles")] + [SwaggerResponse( + StatusCodes.Status200OK, "Request successful", + typeof(PaginatedList))] + [SwaggerResponse( + StatusCodes.Status400BadRequest, "Input data validation error", + typeof(HttpValidationProblemDetails))] + [SwaggerResponse( + StatusCodes.Status401Unauthorized, "Unauthorized to perform an action", + typeof(ProblemDetails))] + [SwaggerResponse( + StatusCodes.Status403Forbidden, + "Not enough privileges to perform an action", + typeof(ProblemDetails))] + [SwaggerResponse( + StatusCodes.Status500InternalServerError, "Internal server error", + typeof(ProblemDetails))] + public async Task> GetRolesPage( + [FromQuery] PageQuery pageQuery, [FromQuery] SearchQuery searchQuery, + CancellationToken cancellationToken) + { + return await Mediator.Send( + new GetRolesPageQuery() + { + PageNumber = pageQuery.PageNumber, + PageSize = pageQuery.PageSize, + Search = searchQuery.Search + }, + cancellationToken); + } + + + + + [HttpPost("accounts")] + [SwaggerOperation("Add an account")] + [SwaggerResponse( + StatusCodes.Status201Created, "Object successfuly created", + typeof(AccountDto))] + [SwaggerResponse( + StatusCodes.Status400BadRequest, "Object already exists", + typeof(ProblemDetails))] + [SwaggerResponse( + StatusCodes.Status400BadRequest, "Input data validation error", + typeof(HttpValidationProblemDetails))] + [SwaggerResponse( + StatusCodes.Status401Unauthorized, "Unauthorized to perform an action", + typeof(ProblemDetails))] + [SwaggerResponse( + StatusCodes.Status403Forbidden, + "Not enough privileges to perform an action", + typeof(ProblemDetails))] + [SwaggerResponse( + StatusCodes.Status404NotFound, "Parent object not found", + typeof(ProblemDetails))] + [SwaggerResponse( + StatusCodes.Status500InternalServerError, "Internal server error", + typeof(ProblemDetails))] + public async Task> Add( + [FromBody] AddAccountViewModel viewModel, + CancellationToken cancellationToken) + { + return StatusCode( + StatusCodes.Status201Created, + await Mediator.Send( + new AddAccountCommand() + { + Email = viewModel.Email, + Password = viewModel.Password, + Roles = viewModel.Roles + .Select(s => IdentityRole.FromName(s)) + .ToArray() + }, + cancellationToken)); + } + + + + + // [HttpPost] + // [SwaggerOperation("Add an identity")] + // [SwaggerResponse( + // StatusCodes.Status201Created, "Object successfuly created", + // typeof(IdentityDto))] + // [SwaggerResponse( + // StatusCodes.Status400BadRequest, "Object already exists", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status400BadRequest, "Input data validation error", + // typeof(HttpValidationProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status401Unauthorized, "Unauthorized to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status403Forbidden, + // "Not enough privileges to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status404NotFound, "Parent object not found", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status500InternalServerError, "Internal server error", + // typeof(ProblemDetails))] + // public async Task> Add( + // [FromBody] AddIdentityViewModel viewModel, + // CancellationToken cancellationToken) + // { + // return StatusCode( + // StatusCodes.Status201Created, + // await Mediator.Send( + // new AddIdentityCommand() + // { + // Name = viewModel.Name, + // Longitude = viewModel.Longitude, + // Latitude = viewModel.Latitude, + // VehicleType = VehicleType.FromName(viewModel.VehicleType), + // CityGuid = viewModel.CityUuid + // }, + // cancellationToken)); + // } + // + // [HttpGet("{uuid:guid}")] + // [SwaggerOperation("Get an identity by uuid")] + // [SwaggerResponse( + // StatusCodes.Status200OK, "Request successful", typeof(IdentityDto))] + // [SwaggerResponse( + // StatusCodes.Status400BadRequest, "Input data validation error", + // typeof(HttpValidationProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status401Unauthorized, "Unauthorized to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status403Forbidden, + // "Not enough privileges to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status404NotFound, "Object not found", typeof(IdentityDto))] + // [SwaggerResponse( + // StatusCodes.Status500InternalServerError, "Internal server error", + // typeof(ProblemDetails))] + // public async Task Get( + // [FromRoute] Guid uuid, + // CancellationToken cancellationToken) + // { + // return await Mediator.Send(new GetIdentityQuery() { Guid = uuid }, + // cancellationToken); + // } + // + // [HttpPut("{uuid:guid}")] + // [SwaggerOperation("Update an identity")] + // [SwaggerResponse( + // StatusCodes.Status200OK, "Request successful", typeof(IdentityDto))] + // [SwaggerResponse( + // StatusCodes.Status400BadRequest, "Object already exists", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status400BadRequest, "Input data validation error", + // typeof(HttpValidationProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status401Unauthorized, "Unauthorized to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status403Forbidden, + // "Not enough privileges to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status404NotFound, "Object not found", typeof(IdentityDto))] + // [SwaggerResponse( + // StatusCodes.Status404NotFound, "Parent object not found", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status500InternalServerError, "Internal server error", + // typeof(ProblemDetails))] + // public async Task Update( + // [FromRoute] Guid uuid, + // [FromBody] UpdateIdentityViewModel viewModel, + // CancellationToken cancellationToken) + // { + // return await Mediator.Send( + // new UpdateIdentityCommand() + // { + // Guid = uuid, + // Name = viewModel.Name, + // Longitude = viewModel.Longitude, + // Latitude = viewModel.Latitude, + // VehicleType = VehicleType.FromName(viewModel.VehicleType), + // CityGuid = viewModel.CityUuid + // }, + // cancellationToken); + // } + // + // [HttpDelete("{uuid:guid}")] + // [SwaggerOperation("Delete an identity")] + // [SwaggerResponse(StatusCodes.Status204NoContent, "Request successful")] + // [SwaggerResponse( + // StatusCodes.Status400BadRequest, "Input data validation error", + // typeof(HttpValidationProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status401Unauthorized, "Unauthorized to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status403Forbidden, + // "Not enough privileges to perform an action", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status404NotFound, "Object not found", + // typeof(ProblemDetails))] + // [SwaggerResponse( + // StatusCodes.Status500InternalServerError, "Internal server error", + // typeof(ProblemDetails))] + // public async Task Delete( + // [FromRoute] Guid uuid, + // CancellationToken cancellationToken) + // { + // await Mediator.Send( + // new DeleteIdentityCommand() { Guid = uuid }, + // cancellationToken); + // return StatusCode(StatusCodes.Status204NoContent); + // } +} diff --git a/src/HttpApi/Controllers/TestsController.cs b/src/HttpApi/Controllers/TestsController.cs index be91e8b..3e2abf0 100644 --- a/src/HttpApi/Controllers/TestsController.cs +++ b/src/HttpApi/Controllers/TestsController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Application.Common.Persistence; namespace cuqmbr.TravelGuide.HttpApi.Controllers; diff --git a/src/HttpApi/Middlewares/ThreadCultureSetterMiddleware.cs b/src/HttpApi/Middlewares/ThreadCultureSetterMiddleware.cs index 3f245fb..3f7e4fa 100644 --- a/src/HttpApi/Middlewares/ThreadCultureSetterMiddleware.cs +++ b/src/HttpApi/Middlewares/ThreadCultureSetterMiddleware.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using System.Globalization; namespace cuqmbr.TravelGuide.HttpApi.Middlewares; diff --git a/src/HttpApi/Program.cs b/src/HttpApi/Program.cs index 015f880..c708d32 100644 --- a/src/HttpApi/Program.cs +++ b/src/HttpApi/Program.cs @@ -1,10 +1,9 @@ using cuqmbr.TravelGuide.Configuration.Persistence; using cuqmbr.TravelGuide.Configuration.Application; using cuqmbr.TravelGuide.Configuration.Infrastructure; -using cuqmbr.TravelGuide.Configuration.Identity; using cuqmbr.TravelGuide.Configuration.Configuration; using cuqmbr.TravelGuide.Configuration.Logging; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.HttpApi.Services; using cuqmbr.TravelGuide.HttpApi.HostedServices; using cuqmbr.TravelGuide.HttpApi.Middlewares; @@ -24,11 +23,11 @@ services.ConfigureConfiguration(args); services.ConfigureLogging(); -services.ConfigurePersistence(); -services.ConfigureIdentity(); services.ConfigureInfrastructure(); +services.ConfigurePersistence(); services.ConfigureApplication(); +services.AddHttpContextAccessor(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/HttpApi/Services/AspNetSessionCultureService.cs b/src/HttpApi/Services/AspNetSessionCultureService.cs index 1c4ef7e..7a7d614 100644 --- a/src/HttpApi/Services/AspNetSessionCultureService.cs +++ b/src/HttpApi/Services/AspNetSessionCultureService.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using System.Globalization; namespace cuqmbr.TravelGuide.HttpApi.Services; diff --git a/src/HttpApi/Services/AspNetSessionCurrencyService.cs b/src/HttpApi/Services/AspNetSessionCurrencyService.cs index 8b28990..91e4b68 100644 --- a/src/HttpApi/Services/AspNetSessionCurrencyService.cs +++ b/src/HttpApi/Services/AspNetSessionCurrencyService.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.HttpApi.Services; diff --git a/src/HttpApi/Services/AspNetSessionTimeZoneService.cs b/src/HttpApi/Services/AspNetSessionTimeZoneService.cs index 9feb264..55acb54 100644 --- a/src/HttpApi/Services/AspNetSessionTimeZoneService.cs +++ b/src/HttpApi/Services/AspNetSessionTimeZoneService.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; namespace cuqmbr.TravelGuide.HttpApi.Services; diff --git a/src/HttpApi/Services/AspNetSessionUserService.cs b/src/HttpApi/Services/AspNetSessionUserService.cs index eed5afc..2f9c8fd 100644 --- a/src/HttpApi/Services/AspNetSessionUserService.cs +++ b/src/HttpApi/Services/AspNetSessionUserService.cs @@ -1,6 +1,6 @@ using System.IdentityModel.Tokens.Jwt; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.HttpApi.Services; @@ -13,7 +13,7 @@ public sealed class AspNetSessionUserService : SessionUserService _httpContext = httpContextAccessor.HttpContext; } - public int? Id + public Guid? Guid { get { @@ -22,16 +22,16 @@ public sealed class AspNetSessionUserService : SessionUserService .Any(p => p.Value == JwtRegisteredClaimNames.Sub)) ?.Value; - var parsed = int.TryParse(claimValue, out var id); + var parsed = System.Guid.TryParse(claimValue, out var guid); - return parsed ? id : null; + return parsed ? guid : null; } } - public Guid? Uuid => Guid.Parse(_httpContext.User.Claims + public string? Username => _httpContext.User.Claims .FirstOrDefault(c => c.Properties - .Any(p => p.Value.Equals("uuid"))) - ?.Value); + .Any(p => p.Value == JwtRegisteredClaimNames.Nickname)) + ?.Value; public string? Email => _httpContext.User.Claims .FirstOrDefault(c => c.Properties @@ -48,6 +48,7 @@ public sealed class AspNetSessionUserService : SessionUserService _httpContext.Request.Cookies["accessToken"] ?? _httpContext.Request.Headers["Authorization"] .ToString()?.Replace("Bearer ", ""); + public string? RefreshToken => _httpContext.Request.Cookies["refreshToken"]; } diff --git a/src/HttpApi/appsettings.Development.json b/src/HttpApi/appsettings.Development.json index 8f2afcb..81ff06d 100644 --- a/src/HttpApi/appsettings.Development.json +++ b/src/HttpApi/appsettings.Development.json @@ -14,6 +14,13 @@ "DefaultCultureName": "en-US", "CacheDuration": "00:30:00" }, + "JsonWebToken": { + "Issuer": "https://api.travel-guide.cuqmbr.xyz", + "Audience": "https://travel-guide.cuqmbr.xyz", + "IssuerSigningKey": "a2c98dec80787a4e85ffb5bcbc24f7e4cc014d8a4fe43e9520480a50759164bc", + "AccessTokenValidity": "24:00:00", + "RefreshTokenValidity": "72:00:00" + }, "Infrastructure": { "PaymentProcessing": { "CallbackAddressBase": "https://api.travel-guide.cuqmbr.xyz", @@ -24,18 +31,5 @@ } } } - }, - "Identity": { - "Datastore": { - "Type": "postgresql", - "ConnectionString": "Host=127.0.0.1:5432;Database=travel_guide;Username=postgres;Password=0000" - }, - "JsonWebToken": { - "Issuer": "https://api.travel-guide.cuqmbr.xyz", - "Audience": "https://travel-guide.cuqmbr.xyz", - "IssuerSigningKey": "a2c98dec80787a4e85ffb5bcbc24f7e4cc014d8a4fe43e9520480a50759164bc", - "AccessTokenValidity": "24:00:00", - "RefreshTokenValidity": "72:00:00" - } } } diff --git a/src/HttpApi/appsettings.json b/src/HttpApi/appsettings.json index 8f2afcb..81ff06d 100644 --- a/src/HttpApi/appsettings.json +++ b/src/HttpApi/appsettings.json @@ -14,6 +14,13 @@ "DefaultCultureName": "en-US", "CacheDuration": "00:30:00" }, + "JsonWebToken": { + "Issuer": "https://api.travel-guide.cuqmbr.xyz", + "Audience": "https://travel-guide.cuqmbr.xyz", + "IssuerSigningKey": "a2c98dec80787a4e85ffb5bcbc24f7e4cc014d8a4fe43e9520480a50759164bc", + "AccessTokenValidity": "24:00:00", + "RefreshTokenValidity": "72:00:00" + }, "Infrastructure": { "PaymentProcessing": { "CallbackAddressBase": "https://api.travel-guide.cuqmbr.xyz", @@ -24,18 +31,5 @@ } } } - }, - "Identity": { - "Datastore": { - "Type": "postgresql", - "ConnectionString": "Host=127.0.0.1:5432;Database=travel_guide;Username=postgres;Password=0000" - }, - "JsonWebToken": { - "Issuer": "https://api.travel-guide.cuqmbr.xyz", - "Audience": "https://travel-guide.cuqmbr.xyz", - "IssuerSigningKey": "a2c98dec80787a4e85ffb5bcbc24f7e4cc014d8a4fe43e9520480a50759164bc", - "AccessTokenValidity": "24:00:00", - "RefreshTokenValidity": "72:00:00" - } } } diff --git a/src/HttpApi/packages.lock.json b/src/HttpApi/packages.lock.json index 2d89b37..02503f2 100644 --- a/src/HttpApi/packages.lock.json +++ b/src/HttpApi/packages.lock.json @@ -192,8 +192,8 @@ }, "Microsoft.AspNetCore.Authentication.JwtBearer": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0HgfWPfnjlzWFbW4pw6FYNuIMV8obVU+MUkiZ33g4UOpvZcmdWzdayfheKPZ5+EUly8SvfgW0dJwwIrW4IVLZQ==", + "resolved": "9.0.5", + "contentHash": "8J04KPX5NCo6j5AjY/rgeLTceMBJ8Sq4k+YNxN/7hCrbCH1iwHVw7VGGvlCscj615ewMX3jYDmxxLdutbSPOcA==", "dependencies": { "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" } @@ -224,15 +224,15 @@ }, "Microsoft.AspNetCore.Cryptography.Internal": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "E4pHyEb2Ul5a6bIwraGtw9TN39a/C2asyVPEJoyItc0reV4Y26FsPcEdcXyKjBbP4kSz9iU1Cz4Yhx/aOFPpqA==" + "resolved": "2.3.0", + "contentHash": "/qy5r0CD40OccajzDmX3gBfqqxpAJkcXoqlVz0YR70x3gTRq/VuseDU/lZ5eh8vM+KCdmPFAtyGcRWxTyXxuYg==" }, "Microsoft.AspNetCore.Cryptography.KeyDerivation": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "5v9Kj2arRrCftLKW80Hfj31HkNnjcKyw57lQhF84drvGxJlCR63J0zMM1sMM+Hc+KCQjuoDmHtjwN0uOT+X3ag==", + "resolved": "2.3.0", + "contentHash": "S7pph0JuBkgNqtyiIdLtQ5icZxmpX502zxxvHuMtM5W7IR3CKl1r/Cup+i6+E6B7IF3BeZYF4O3RbcA108syig==", "dependencies": { - "Microsoft.AspNetCore.Cryptography.Internal": "9.0.4" + "Microsoft.AspNetCore.Cryptography.Internal": "2.3.0" } }, "Microsoft.AspNetCore.DataProtection": { @@ -326,15 +326,6 @@ "Microsoft.Extensions.Identity.Core": "2.3.0" } }, - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "IC3X6Db6H0cXdE2zGtyk/jmSwXhHbJZaiNpg7TNFV/Biu/NgO6l/GuwgE0D1U6U9pca00WsqxESkNov+WA77CA==", - "dependencies": { - "Microsoft.EntityFrameworkCore.Relational": "9.0.4", - "Microsoft.Extensions.Identity.Stores": "9.0.4" - } - }, "Microsoft.AspNetCore.Metadata": { "type": "Transitive", "resolved": "9.0.0", @@ -681,22 +672,13 @@ }, "Microsoft.Extensions.Identity.Core": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "KKfCsoIHFGZmmCEjZBPuvDW0pCjboMru/Z3vbEyC/OIwUVeKrdPugFyjc81i7rNSjcPcDxVvGl/Ks8HLelKocg==", + "resolved": "2.3.0", + "contentHash": "yR0eFnUbAM2k+q5QsX0NKinfShIe1B/aiHXEywiNT5Cs2MvEhxQIbIn5rWXnEAfmwW+i+t5D8odPSEHz/taIyQ==", "dependencies": { - "Microsoft.AspNetCore.Cryptography.KeyDerivation": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4" - } - }, - "Microsoft.Extensions.Identity.Stores": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0F6lSngwyXzrv+qtX46nhHYBOlPxEzj0qyCCef1kvlyEYhbj8kBL13FuDk4nEPkzk1yVjZgsnXBG19+TrNdakQ==", - "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "9.0.4", - "Microsoft.Extensions.Identity.Core": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" + "Microsoft.AspNetCore.Cryptography.KeyDerivation": "2.3.0", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Options": "8.0.2", + "System.ComponentModel.Annotations": "5.0.0" } }, "Microsoft.Extensions.Localization": { @@ -793,23 +775,23 @@ }, "Microsoft.IdentityModel.Abstractions": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "0lKw+f3vkmV9t3PLe6sY3xPrYrHYiMRFxuOse5CMkKPxhQYiabpfJsuk6wX2RrVQ86Dn+t/8poHpH0nbp6sFvA==" + "resolved": "8.11.0", + "contentHash": "X92UuBmvHYtsVrD+R+senFn6wOtSVtliSZNTZI8oHD+WqhYLmLNlHH6avYcbXqEznozxshSYzD/DVAuz54jjtg==" }, "Microsoft.IdentityModel.JsonWebTokens": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "lepOkZZTMfJCPSnWITXxV+4Wxb54g+9oIybs9YovlOzZWuR1i2DOpzaDgSe+piDJaGtnSrcUlcB9fZ5Swur7Uw==", + "resolved": "8.11.0", + "contentHash": "rLvApg2vqs/Kz5kVHwHUMAe3owInYrsPX8QP8CQktubX9R63P+J47nR/IOS4n6ddJCvGInUGRBKqcBGJtuA4Rw==", "dependencies": { - "Microsoft.IdentityModel.Tokens": "8.8.0" + "Microsoft.IdentityModel.Tokens": "8.11.0" } }, "Microsoft.IdentityModel.Logging": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "sUyoxzg/WBZobbFLJK8loT9IILKtS9ePmWu5B11ogQqhSHppE6SRZKw0fhI6Fd16X6ey52cbbWc2rvMBC98EQA==", + "resolved": "8.11.0", + "contentHash": "/JNOMdYOQ4Tgbdwu9GbEcRJEpzakizuECCE8dCgY5lKXyqZUdAKXyeq4zITgS81eZYThqjhQZUYaJxOPofbmrg==", "dependencies": { - "Microsoft.IdentityModel.Abstractions": "8.8.0" + "Microsoft.IdentityModel.Abstractions": "8.11.0" } }, "Microsoft.IdentityModel.Protocols": { @@ -831,11 +813,11 @@ }, "Microsoft.IdentityModel.Tokens": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "09hnbUJh/18gUmu5nCVFMvyzAFC4l1qyc4bwSJaKzUBqHN7aNDwmSx8dE3/MMJImbvnKq9rEtkkgnrS/OUBtjA==", + "resolved": "8.11.0", + "contentHash": "E0iKSD9vv9X+tbHGriMTLkSNK/OOjxOPuf1dt9q32d25Ig+OZaidUqDoUTSS3mWTvPw+x5oXrCTHtDatbzRzTQ==", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.IdentityModel.Logging": "8.8.0" + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.11.0" } }, "Microsoft.Net.Http.Headers": { @@ -947,6 +929,11 @@ "resolved": "7.0.0", "contentHash": "dQPcs0U1IKnBdRDBkrCTi1FoajSTBzLcVTpjO4MBCMC7f4pDOIPzgBoX8JjG7X6uZRJ8EBxsi8+DR1JuwjnzOQ==" }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==" + }, "System.Composition": { "type": "Transitive", "resolved": "7.0.0", @@ -1083,7 +1070,10 @@ "FluentValidation": "[11.11.0, )", "MediatR": "[12.4.1, )", "MediatR.Behaviors.Authorization": "[12.2.0, )", + "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.5, )", "Microsoft.Extensions.Logging": "[9.0.4, )", + "Microsoft.IdentityModel.JsonWebTokens": "[8.11.0, )", + "Microsoft.IdentityModel.Tokens": "[8.11.0, )", "Newtonsoft.Json": "[13.0.3, )", "QuikGraph": "[2.5.0, )", "System.Linq.Dynamic.Core": "[1.6.2, )" @@ -1096,7 +1086,6 @@ "AspNetCore.Localizer.Json": "[1.0.1, )", "Domain": "[1.0.0, )", "FluentValidation.DependencyInjectionExtensions": "[11.11.0, )", - "Identity": "[1.0.0, )", "Infrastructure": "[1.0.0, )", "Microsoft.AspNetCore.Identity": "[2.3.1, )", "Microsoft.EntityFrameworkCore.InMemory": "[9.0.4, )", @@ -1116,19 +1105,6 @@ "domain": { "type": "Project" }, - "identity": { - "type": "Project", - "dependencies": { - "Application": "[1.0.0, )", - "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.4, )", - "Microsoft.AspNetCore.Identity": "[2.3.1, )", - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "[9.0.4, )", - "Microsoft.Extensions.Options": "[9.0.4, )", - "Microsoft.IdentityModel.JsonWebTokens": "[8.8.0, )", - "Microsoft.IdentityModel.Tokens": "[8.8.0, )", - "Npgsql.EntityFrameworkCore.PostgreSQL": "[9.0.4, )" - } - }, "infrastructure": { "type": "Project", "dependencies": { diff --git a/src/Identity/ConfigurationOptions.cs b/src/Identity/ConfigurationOptions.cs deleted file mode 100644 index 9bce7be..0000000 --- a/src/Identity/ConfigurationOptions.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace cuqmbr.TravelGuide.Identity; - -public sealed class ConfigurationOptions -{ - public static string SectionName { get; } = "Identity"; - - public Datastore Datastore { get; set; } = new(); - - public JsonWebToken JsonWebToken { get; set; } = new(); -} - -public sealed class Datastore -{ - public string Type { get; set; } = "inmemory"; - - public string ConnectionString { get; set; } = "InMemory"; - - public string PartitionName { get; set; } = "identity"; - - public bool Migrate { get; set; } = true; -} - -public sealed class JsonWebToken -{ - public string Issuer { get; set; } = "localhost"; - - public string Audience { get; set; } = "localhost"; - - public string IssuerSigningKey { get; set; } = "change-me"; - - public TimeSpan AccessTokenValidity { get; set; } = TimeSpan.FromMinutes(15); - - public TimeSpan RefreshTokenValidity { get; set; } = TimeSpan.FromDays(3); -} diff --git a/src/Identity/Exceptions/UnSupportedDatastoreException.cs b/src/Identity/Exceptions/UnSupportedDatastoreException.cs deleted file mode 100644 index 7366911..0000000 --- a/src/Identity/Exceptions/UnSupportedDatastoreException.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace cuqmbr.TravelGuide.Identity.Exceptions; - -public class UnSupportedDatastoreException : Exception -{ - public UnSupportedDatastoreException() - : base() { } - - public UnSupportedDatastoreException(string message) - : base(message) { } -} - diff --git a/src/Identity/Identity.csproj b/src/Identity/Identity.csproj deleted file mode 100644 index 53c2cb1..0000000 --- a/src/Identity/Identity.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net9.0 - enable - enable - - - - - - - - - - - - - - - - - - true - - - diff --git a/src/Identity/IdentitySeeder.cs b/src/Identity/IdentitySeeder.cs deleted file mode 100644 index 15e7647..0000000 --- a/src/Identity/IdentitySeeder.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using IdentityUser = cuqmbr.TravelGuide.Identity.Models.IdentityUser; -using IdentityRole = cuqmbr.TravelGuide.Identity.Models.IdentityRole; -using Microsoft.Extensions.DependencyInjection; -using IdentityRoleEnum = cuqmbr.TravelGuide.Application.Common.Models - .IdentityRole; - -namespace cuqmbr.TravelGuide.Identity; - -public static class IdentitySeeder -{ - public static void Seed(IServiceProvider serviceProvider) - { - using var userManager = serviceProvider - .GetService>(); - userManager.UserValidators.Clear(); - userManager.PasswordValidators.Clear(); - - using var roleManager = serviceProvider - .GetService>(); - roleManager.RoleValidators.Clear(); - - // Seed Roles - foreach (var role in IdentityRoleEnum.Enumerations) - { - var roleString = role.Value.Name; - - var roleExists = roleManager.RoleExistsAsync(roleString).Result; - - if (roleExists) - { - continue; - } - - roleManager.CreateAsync(new IdentityRole() - { - Name = roleString, - ConcurrencyStamp = Guid.NewGuid().ToString("D") - }).Wait(); - } - - // Seed Identity - var users = new (string Email, string Password, IdentityRoleEnum[] Roles)[] - { - ("admin", "admin", new [] { IdentityRoleEnum.Administrator }), - }; - - foreach (var user in users) - { - - var userExists = userManager - .FindByEmailAsync(user.Email).Result is not null; - - if (userExists) - { - continue; - } - - var newUser = new IdentityUser - { - Email = user.Email, - NormalizedEmail = user.Email.ToUpper(), - EmailConfirmed = true, - SecurityStamp = Guid.NewGuid().ToString("D"), - RefreshTokens = default! - }; - - var hashedPassword - = userManager.PasswordHasher.HashPassword(newUser, user.Password); - newUser.PasswordHash = hashedPassword; - - userManager - .CreateAsync(newUser) - .Wait(); - - var userRoles = user.Roles.Select(x => x.Name); - - userManager - .AddToRolesAsync(newUser, userRoles) - .Wait(); - } - - } -} - diff --git a/src/Identity/Models/IdentityRole.cs b/src/Identity/Models/IdentityRole.cs deleted file mode 100644 index b1d9ee4..0000000 --- a/src/Identity/Models/IdentityRole.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace cuqmbr.TravelGuide.Identity.Models; - -public class IdentityRole : Microsoft.AspNetCore.Identity.IdentityRole -{ - public string Uuid { get; set; } = Guid.NewGuid().ToString(); -} diff --git a/src/Identity/Models/IdentityUser.cs b/src/Identity/Models/IdentityUser.cs deleted file mode 100644 index ce9aad1..0000000 --- a/src/Identity/Models/IdentityUser.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace cuqmbr.TravelGuide.Identity.Models; - -public class IdentityUser : Microsoft.AspNetCore.Identity.IdentityUser -{ - public string Uuid { get; set; } = Guid.NewGuid().ToString(); - - public ICollection RefreshTokens { get; set; } -} diff --git a/src/Identity/Models/RefreshToken.cs b/src/Identity/Models/RefreshToken.cs deleted file mode 100644 index a751096..0000000 --- a/src/Identity/Models/RefreshToken.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace cuqmbr.TravelGuide.Identity.Models; - -public class RefreshToken -{ - public int Id { get; set; } - - public string Value { get; set; } = null!; - - public DateTimeOffset CreationTimestamp { get; set; } - - public DateTimeOffset ExpirationTimestamp { get; set; } - - public DateTimeOffset? RevokationTimestamp { get; set; } - - public bool IsExpired => DateTimeOffset.UtcNow >= ExpirationTimestamp; - - public bool IsActive => RevokationTimestamp is null && !IsExpired; - - public int IdentityUserId { get; set; } - - public IdentityUser IdentityUser { get; set; } -} - diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleClaimConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleClaimConfiguration.cs deleted file mode 100644 index 91c8229..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleClaimConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityRoleClaimConfiguration : IEntityTypeConfiguration> -{ - public void Configure(EntityTypeBuilder> builder) - { - builder - .ToTable("role_claims"); - - builder - .Property(rc => rc.Id) - .HasColumnName("id"); - - builder - .Property(rc => rc.RoleId) - .HasColumnName("role_id"); - - builder - .Property(rc => rc.ClaimType) - .HasColumnName("claim_type"); - - builder - .Property(rc => rc.ClaimValue) - .HasColumnName("claim_value"); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleConfiguration.cs deleted file mode 100644 index e8ee518..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityRoleConfiguration.cs +++ /dev/null @@ -1,34 +0,0 @@ -using cuqmbr.TravelGuide.Identity.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityRoleConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder - .ToTable("roles"); - - builder - .Property(r => r.Id) - .HasColumnName("id"); - - builder - .Property(r => r.Uuid) - .HasColumnName("uuid"); - - builder - .Property(r => r.Name) - .HasColumnName("name"); - - builder - .Property(r => r.NormalizedName) - .HasColumnName("normalized_name"); - - builder - .Property(r => r.ConcurrencyStamp) - .HasColumnName("concurrency_stamp"); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserClaimConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserClaimConfiguration.cs deleted file mode 100644 index 863092f..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserClaimConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityUserClaimConfiguration : IEntityTypeConfiguration> -{ - public void Configure(EntityTypeBuilder> builder) - { - builder - .ToTable("user_claims"); - - builder - .Property(uc => uc.Id) - .HasColumnName("id"); - - builder - .Property(uc => uc.UserId) - .HasColumnName("user_id"); - - builder - .Property(uc => uc.ClaimType) - .HasColumnName("claim_type"); - - builder - .Property(uc => uc.ClaimValue) - .HasColumnName("claim_value"); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserConfiguration.cs deleted file mode 100644 index e99835c..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserConfiguration.cs +++ /dev/null @@ -1,128 +0,0 @@ -using cuqmbr.TravelGuide.Identity.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityUserConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder - .ToTable("users"); - - builder - .Property(u => u.Id) - .HasColumnName("id"); - - builder - .Property(u => u.Uuid) - .HasColumnName("uuid"); - - builder - .Ignore(u => u.UserName); - - builder - .Ignore(u => u.NormalizedUserName); - - builder - .Property(u => u.Email) - .HasColumnName("email"); - - builder - .Property(u => u.NormalizedEmail) - .HasColumnName("normalized_email"); - - builder - .Property(u => u.EmailConfirmed) - .HasColumnName("email_confirmed"); - - builder - .Property(u => u.PasswordHash) - .HasColumnName("password_hash"); - - builder - .Property(u => u.SecurityStamp) - .HasColumnName("security_stamp"); - - builder - .Property(u => u.ConcurrencyStamp) - .HasColumnName("concurrency_stamp"); - - builder - .Ignore(u => u.PhoneNumber); - - builder - .Ignore(u => u.PhoneNumberConfirmed); - - builder - .Property(u => u.TwoFactorEnabled) - .HasColumnName("two_factor_enabled"); - - builder - .Property(u => u.LockoutEnabled) - .HasColumnName("lockout_enabled"); - - builder - .Property(u => u.LockoutEnd) - .HasColumnName("lockout_end"); - - builder - .Property(u => u.AccessFailedCount) - .HasColumnName("access_failed_count"); - - builder - .OwnsMany(u => u.RefreshTokens, - refreshToken => - { - refreshToken - .ToTable("user_refresh_tokens"); - - refreshToken - .HasKey(rt => rt.Id) - .HasName("id"); - - refreshToken - .WithOwner(rt => rt.IdentityUser) - .HasForeignKey(rt => rt.IdentityUserId) - .HasConstraintName("fk_identityUserRefreshTokens_identityUser_userId"); - - refreshToken - .Property(rt => rt.Id) - .HasColumnName("id") - .HasColumnType("int") - .IsRequired(); - - refreshToken - .Property(rt => rt.IdentityUserId) - .HasColumnName("user_id") - .HasColumnType("int") - .IsRequired(); - - refreshToken - .Property(rt => rt.Value) - .HasColumnName("value") - .HasColumnType("varchar(256)") - .IsRequired(); - - refreshToken - .Property(rt => rt.CreationTimestamp) - .HasColumnName("creation_timestamp_utc") - .HasColumnType("timestamptz") - .IsRequired(); - - refreshToken - .Property(rt => rt.ExpirationTimestamp) - .HasColumnName("expiration_timestamp_utc") - .HasColumnType("timestamptz") - .IsRequired(); - - refreshToken - .Property(rt => rt.RevokationTimestamp) - .HasColumnName("revokation_timestamp_utc") - .HasColumnType("timestamptz") - .IsRequired(false); - } - ); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserLoginConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserLoginConfiguration.cs deleted file mode 100644 index 3464a1c..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserLoginConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityUserLoginConfiguration : IEntityTypeConfiguration> -{ - public void Configure(EntityTypeBuilder> builder) - { - builder - .ToTable("user_logins"); - - builder - .Property(ul => ul.LoginProvider) - .HasColumnName("login_provider"); - - builder - .Property(ul => ul.ProviderKey) - .HasColumnName("provider_key"); - - builder - .Property(ul => ul.ProviderDisplayName) - .HasColumnName("provider_display_name"); - - builder - .Property(ul => ul.UserId) - .HasColumnName("user_id"); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserRoleConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserRoleConfiguration.cs deleted file mode 100644 index 70fee96..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserRoleConfiguration.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityUserRoleConfiguration : IEntityTypeConfiguration> -{ - public void Configure(EntityTypeBuilder> builder) - { - builder - .ToTable("user_roles"); - - builder - .Property(ur => ur.UserId) - .HasColumnName("user_id"); - - builder - .Property(ur => ur.RoleId) - .HasColumnName("role_id"); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserTokenConfiguration.cs b/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserTokenConfiguration.cs deleted file mode 100644 index 6b91d44..0000000 --- a/src/Identity/Persistence/PostgreSql/Configurations/IdentityUserTokenConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations; - -public class IdentityUserTokenConfiguration : IEntityTypeConfiguration> -{ - public void Configure(EntityTypeBuilder> builder) - { - builder - .ToTable("user_tokens"); - - builder - .Property(ut => ut.UserId) - .HasColumnName("user_id"); - - builder - .Property(ut => ut.LoginProvider) - .HasColumnName("login_provider"); - - builder - .Property(ut => ut.Name) - .HasColumnName("name"); - - builder - .Property(ut => ut.Value) - .HasColumnName("value"); - } -} diff --git a/src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.Designer.cs b/src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.Designer.cs deleted file mode 100644 index 5fd201a..0000000 --- a/src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.Designer.cs +++ /dev/null @@ -1,355 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using cuqmbr.TravelGuide.Identity.Persistence.PostgreSql; - -#nullable disable - -namespace Identity.Persistence.PostgreSql.Migrations -{ - [DbContext(typeof(PostgreSqlIdentityDbContext))] - [Migration("20250423194315_Initial_migration")] - partial class Initial_migration - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasDefaultSchema("identity") - .HasAnnotation("ProductVersion", "9.0.4") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text") - .HasColumnName("claim_type"); - - b.Property("ClaimValue") - .HasColumnType("text") - .HasColumnName("claim_value"); - - b.Property("RoleId") - .HasColumnType("integer") - .HasColumnName("role_id"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("role_claims", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text") - .HasColumnName("claim_type"); - - b.Property("ClaimValue") - .HasColumnType("text") - .HasColumnName("claim_value"); - - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("user_claims", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text") - .HasColumnName("login_provider"); - - b.Property("ProviderKey") - .HasColumnType("text") - .HasColumnName("provider_key"); - - b.Property("ProviderDisplayName") - .HasColumnType("text") - .HasColumnName("provider_display_name"); - - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("user_logins", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.Property("RoleId") - .HasColumnType("integer") - .HasColumnName("role_id"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("user_roles", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.Property("LoginProvider") - .HasColumnType("text") - .HasColumnName("login_provider"); - - b.Property("Name") - .HasColumnType("text") - .HasColumnName("name"); - - b.Property("Value") - .HasColumnType("text") - .HasColumnName("value"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("user_tokens", "identity"); - }); - - modelBuilder.Entity("cuqmbr.TravelGuide.Identity.Models.IdentityRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text") - .HasColumnName("concurrency_stamp"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("name"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("normalized_name"); - - b.Property("Uuid") - .IsRequired() - .HasColumnType("text") - .HasColumnName("uuid"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("roles", "identity"); - }); - - modelBuilder.Entity("cuqmbr.TravelGuide.Identity.Models.IdentityUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccessFailedCount") - .HasColumnType("integer") - .HasColumnName("access_failed_count"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text") - .HasColumnName("concurrency_stamp"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("email"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean") - .HasColumnName("email_confirmed"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean") - .HasColumnName("lockout_enabled"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone") - .HasColumnName("lockout_end"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("normalized_email"); - - b.Property("PasswordHash") - .HasColumnType("text") - .HasColumnName("password_hash"); - - b.Property("SecurityStamp") - .HasColumnType("text") - .HasColumnName("security_stamp"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean") - .HasColumnName("two_factor_enabled"); - - b.Property("Uuid") - .IsRequired() - .HasColumnType("text") - .HasColumnName("uuid"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.ToTable("users", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("cuqmbr.TravelGuide.Identity.Models.IdentityUser", b => - { - b.OwnsMany("cuqmbr.TravelGuide.Identity.Models.RefreshToken", "RefreshTokens", b1 => - { - b1.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b1.Property("Id")); - - b1.Property("CreationTimestamp") - .HasColumnType("timestamptz") - .HasColumnName("creation_timestamp_utc"); - - b1.Property("ExpirationTimestamp") - .HasColumnType("timestamptz") - .HasColumnName("expiration_timestamp_utc"); - - b1.Property("IdentityUserId") - .HasColumnType("int") - .HasColumnName("user_id"); - - b1.Property("RevokationTimestamp") - .HasColumnType("timestamptz") - .HasColumnName("revokation_timestamp_utc"); - - b1.Property("Value") - .IsRequired() - .HasColumnType("varchar(256)") - .HasColumnName("value"); - - b1.HasKey("Id") - .HasName("id"); - - b1.HasIndex("IdentityUserId"); - - b1.ToTable("user_refresh_tokens", "identity"); - - b1.WithOwner("IdentityUser") - .HasForeignKey("IdentityUserId") - .HasConstraintName("fk_identityUserRefreshTokens_identityUser_userId"); - - b1.Navigation("IdentityUser"); - }); - - b.Navigation("RefreshTokens"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.cs b/src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.cs deleted file mode 100644 index 035edce..0000000 --- a/src/Identity/Persistence/PostgreSql/Migrations/20250423194315_Initial_migration.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace Identity.Persistence.PostgreSql.Migrations -{ - /// - public partial class Initial_migration : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.EnsureSchema( - name: "identity"); - - migrationBuilder.CreateTable( - name: "roles", - schema: "identity", - columns: table => new - { - id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - uuid = table.Column(type: "text", nullable: false), - name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - normalized_name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - concurrency_stamp = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_roles", x => x.id); - }); - - migrationBuilder.CreateTable( - name: "users", - schema: "identity", - columns: table => new - { - id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - uuid = table.Column(type: "text", nullable: false), - email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - normalized_email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - email_confirmed = table.Column(type: "boolean", nullable: false), - password_hash = table.Column(type: "text", nullable: true), - security_stamp = table.Column(type: "text", nullable: true), - concurrency_stamp = table.Column(type: "text", nullable: true), - two_factor_enabled = table.Column(type: "boolean", nullable: false), - lockout_end = table.Column(type: "timestamp with time zone", nullable: true), - lockout_enabled = table.Column(type: "boolean", nullable: false), - access_failed_count = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_users", x => x.id); - }); - - migrationBuilder.CreateTable( - name: "role_claims", - schema: "identity", - columns: table => new - { - id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - role_id = table.Column(type: "integer", nullable: false), - claim_type = table.Column(type: "text", nullable: true), - claim_value = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_role_claims", x => x.id); - table.ForeignKey( - name: "FK_role_claims_roles_role_id", - column: x => x.role_id, - principalSchema: "identity", - principalTable: "roles", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_claims", - schema: "identity", - columns: table => new - { - id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - user_id = table.Column(type: "integer", nullable: false), - claim_type = table.Column(type: "text", nullable: true), - claim_value = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_user_claims", x => x.id); - table.ForeignKey( - name: "FK_user_claims_users_user_id", - column: x => x.user_id, - principalSchema: "identity", - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_logins", - schema: "identity", - columns: table => new - { - login_provider = table.Column(type: "text", nullable: false), - provider_key = table.Column(type: "text", nullable: false), - provider_display_name = table.Column(type: "text", nullable: true), - user_id = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_user_logins", x => new { x.login_provider, x.provider_key }); - table.ForeignKey( - name: "FK_user_logins_users_user_id", - column: x => x.user_id, - principalSchema: "identity", - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_refresh_tokens", - schema: "identity", - columns: table => new - { - id = table.Column(type: "int", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - value = table.Column(type: "varchar(256)", nullable: false), - creation_timestamp_utc = table.Column(type: "timestamptz", nullable: false), - expiration_timestamp_utc = table.Column(type: "timestamptz", nullable: false), - revokation_timestamp_utc = table.Column(type: "timestamptz", nullable: true), - user_id = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("id", x => x.id); - table.ForeignKey( - name: "fk_identityUserRefreshTokens_identityUser_userId", - column: x => x.user_id, - principalSchema: "identity", - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_roles", - schema: "identity", - columns: table => new - { - user_id = table.Column(type: "integer", nullable: false), - role_id = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_user_roles", x => new { x.user_id, x.role_id }); - table.ForeignKey( - name: "FK_user_roles_roles_role_id", - column: x => x.role_id, - principalSchema: "identity", - principalTable: "roles", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_user_roles_users_user_id", - column: x => x.user_id, - principalSchema: "identity", - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_tokens", - schema: "identity", - columns: table => new - { - user_id = table.Column(type: "integer", nullable: false), - login_provider = table.Column(type: "text", nullable: false), - name = table.Column(type: "text", nullable: false), - value = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_user_tokens", x => new { x.user_id, x.login_provider, x.name }); - table.ForeignKey( - name: "FK_user_tokens_users_user_id", - column: x => x.user_id, - principalSchema: "identity", - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_role_claims_role_id", - schema: "identity", - table: "role_claims", - column: "role_id"); - - migrationBuilder.CreateIndex( - name: "RoleNameIndex", - schema: "identity", - table: "roles", - column: "normalized_name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_user_claims_user_id", - schema: "identity", - table: "user_claims", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "IX_user_logins_user_id", - schema: "identity", - table: "user_logins", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "IX_user_refresh_tokens_user_id", - schema: "identity", - table: "user_refresh_tokens", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "IX_user_roles_role_id", - schema: "identity", - table: "user_roles", - column: "role_id"); - - migrationBuilder.CreateIndex( - name: "EmailIndex", - schema: "identity", - table: "users", - column: "normalized_email"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "role_claims", - schema: "identity"); - - migrationBuilder.DropTable( - name: "user_claims", - schema: "identity"); - - migrationBuilder.DropTable( - name: "user_logins", - schema: "identity"); - - migrationBuilder.DropTable( - name: "user_refresh_tokens", - schema: "identity"); - - migrationBuilder.DropTable( - name: "user_roles", - schema: "identity"); - - migrationBuilder.DropTable( - name: "user_tokens", - schema: "identity"); - - migrationBuilder.DropTable( - name: "roles", - schema: "identity"); - - migrationBuilder.DropTable( - name: "users", - schema: "identity"); - } - } -} diff --git a/src/Identity/Persistence/PostgreSql/Migrations/PostgreSqlIdentityDbContextModelSnapshot.cs b/src/Identity/Persistence/PostgreSql/Migrations/PostgreSqlIdentityDbContextModelSnapshot.cs deleted file mode 100644 index 6a55357..0000000 --- a/src/Identity/Persistence/PostgreSql/Migrations/PostgreSqlIdentityDbContextModelSnapshot.cs +++ /dev/null @@ -1,352 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using cuqmbr.TravelGuide.Identity.Persistence.PostgreSql; - -#nullable disable - -namespace Identity.Persistence.PostgreSql.Migrations -{ - [DbContext(typeof(PostgreSqlIdentityDbContext))] - partial class PostgreSqlIdentityDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasDefaultSchema("identity") - .HasAnnotation("ProductVersion", "9.0.4") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text") - .HasColumnName("claim_type"); - - b.Property("ClaimValue") - .HasColumnType("text") - .HasColumnName("claim_value"); - - b.Property("RoleId") - .HasColumnType("integer") - .HasColumnName("role_id"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("role_claims", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text") - .HasColumnName("claim_type"); - - b.Property("ClaimValue") - .HasColumnType("text") - .HasColumnName("claim_value"); - - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("user_claims", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text") - .HasColumnName("login_provider"); - - b.Property("ProviderKey") - .HasColumnType("text") - .HasColumnName("provider_key"); - - b.Property("ProviderDisplayName") - .HasColumnType("text") - .HasColumnName("provider_display_name"); - - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("user_logins", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.Property("RoleId") - .HasColumnType("integer") - .HasColumnName("role_id"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("user_roles", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("integer") - .HasColumnName("user_id"); - - b.Property("LoginProvider") - .HasColumnType("text") - .HasColumnName("login_provider"); - - b.Property("Name") - .HasColumnType("text") - .HasColumnName("name"); - - b.Property("Value") - .HasColumnType("text") - .HasColumnName("value"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("user_tokens", "identity"); - }); - - modelBuilder.Entity("cuqmbr.TravelGuide.Identity.Models.IdentityRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text") - .HasColumnName("concurrency_stamp"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("name"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("normalized_name"); - - b.Property("Uuid") - .IsRequired() - .HasColumnType("text") - .HasColumnName("uuid"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("roles", "identity"); - }); - - modelBuilder.Entity("cuqmbr.TravelGuide.Identity.Models.IdentityUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccessFailedCount") - .HasColumnType("integer") - .HasColumnName("access_failed_count"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text") - .HasColumnName("concurrency_stamp"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("email"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean") - .HasColumnName("email_confirmed"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean") - .HasColumnName("lockout_enabled"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone") - .HasColumnName("lockout_end"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("normalized_email"); - - b.Property("PasswordHash") - .HasColumnType("text") - .HasColumnName("password_hash"); - - b.Property("SecurityStamp") - .HasColumnType("text") - .HasColumnName("security_stamp"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean") - .HasColumnName("two_factor_enabled"); - - b.Property("Uuid") - .IsRequired() - .HasColumnType("text") - .HasColumnName("uuid"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.ToTable("users", "identity"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("cuqmbr.TravelGuide.Identity.Models.IdentityUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("cuqmbr.TravelGuide.Identity.Models.IdentityUser", b => - { - b.OwnsMany("cuqmbr.TravelGuide.Identity.Models.RefreshToken", "RefreshTokens", b1 => - { - b1.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasColumnName("id"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b1.Property("Id")); - - b1.Property("CreationTimestamp") - .HasColumnType("timestamptz") - .HasColumnName("creation_timestamp_utc"); - - b1.Property("ExpirationTimestamp") - .HasColumnType("timestamptz") - .HasColumnName("expiration_timestamp_utc"); - - b1.Property("IdentityUserId") - .HasColumnType("int") - .HasColumnName("user_id"); - - b1.Property("RevokationTimestamp") - .HasColumnType("timestamptz") - .HasColumnName("revokation_timestamp_utc"); - - b1.Property("Value") - .IsRequired() - .HasColumnType("varchar(256)") - .HasColumnName("value"); - - b1.HasKey("Id") - .HasName("id"); - - b1.HasIndex("IdentityUserId"); - - b1.ToTable("user_refresh_tokens", "identity"); - - b1.WithOwner("IdentityUser") - .HasForeignKey("IdentityUserId") - .HasConstraintName("fk_identityUserRefreshTokens_identityUser_userId"); - - b1.Navigation("IdentityUser"); - }); - - b.Navigation("RefreshTokens"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Identity/Persistence/PostgreSql/PostgreSqlIdentityDbContext.cs b/src/Identity/Persistence/PostgreSql/PostgreSqlIdentityDbContext.cs deleted file mode 100644 index faca79d..0000000 --- a/src/Identity/Persistence/PostgreSql/PostgreSqlIdentityDbContext.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; -using IdentityUser = cuqmbr.TravelGuide.Identity.Models.IdentityUser; -using IdentityRole = cuqmbr.TravelGuide.Identity.Models.IdentityRole; -using Microsoft.EntityFrameworkCore; -using System.Reflection; -using Microsoft.Extensions.Options; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql; - -public class PostgreSqlIdentityDbContext - : IdentityDbContext -{ - private readonly ConfigurationOptions _configuration; - - public PostgreSqlIdentityDbContext( - DbContextOptions options, - IOptions configurationOptions) - : base(options) - { - _configuration = configurationOptions.Value; - } - - protected override void OnModelCreating(ModelBuilder builder) - { - base.OnModelCreating(builder); - - builder.HasDefaultSchema(_configuration.Datastore.PartitionName); - - builder.ApplyConfigurationsFromAssembly( - Assembly.GetExecutingAssembly(), - t => t.Namespace == - "cuqmbr.TravelGuide.Identity.Persistence.PostgreSql.Configurations" - ); - } -} diff --git a/src/Identity/Persistence/PostgreSql/PostgreSqlInitializer.cs b/src/Identity/Persistence/PostgreSql/PostgreSqlInitializer.cs deleted file mode 100644 index cabb6d7..0000000 --- a/src/Identity/Persistence/PostgreSql/PostgreSqlInitializer.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; - -namespace cuqmbr.TravelGuide.Identity.Persistence.PostgreSql; - -public static class PostgreSqlInitializer -{ - public static void Initialize(IServiceProvider serviceProvider) - { - using var dbContext = serviceProvider - .GetService(); - - var totalMigrationsCount = - dbContext.Database.GetMigrations().Count(); - var appliedMigrationCount = - dbContext.Database.GetAppliedMigrations().Count(); - - if (totalMigrationsCount - appliedMigrationCount > 0) - { - dbContext.Database.Migrate(); - } - - if (appliedMigrationCount == 0) - { - IdentitySeeder.Seed(serviceProvider); - } - } -} diff --git a/src/Identity/Services/JwtAuthenticationService.cs b/src/Identity/Services/JwtAuthenticationService.cs deleted file mode 100644 index f2a8c5d..0000000 --- a/src/Identity/Services/JwtAuthenticationService.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System.Security.Cryptography; -using cuqmbr.TravelGuide.Application.Authenticaion; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Options; -using IdentityUser = cuqmbr.TravelGuide.Identity.Models.IdentityUser; -using IdentityRole = cuqmbr.TravelGuide.Identity.Models.IdentityRole; -using cuqmbr.TravelGuide.Identity.Models; -using System.Security.Claims; -using System.Text; -using Microsoft.IdentityModel.Tokens; -using cuqmbr.TravelGuide.Application.Common.Models; -using System.IdentityModel.Tokens.Jwt; -using cuqmbr.TravelGuide.Application.Common.Exceptions; - -namespace cuqmbr.TravelGuide.Identity.Services; - -public class JwtAuthenticationService : AuthenticationService -{ - private readonly ConfigurationOptions _configuration; - - private readonly UserManager _userManager; - private readonly RoleManager _roleManager; - - public JwtAuthenticationService( - UserManager userManager, - RoleManager roleManager, - IOptions configuration) - { - _userManager = userManager; - _userManager.UserValidators.Clear(); - _userManager.PasswordValidators.Clear(); - - _roleManager = roleManager; - - _configuration = configuration.Value; - } - - public async Task RegisterAsync( - string email, - string password, - CancellationToken cancellationToken) - { - var userWithSameEmail = await _userManager.FindByEmailAsync(email); - if (userWithSameEmail is not null) - { - throw new RegistrationException("User with given email already registered."); - } - - var newUser = new IdentityUser - { - // Id = Guid.NewGuid().ToString(), - Email = email, - RefreshTokens = default! - }; - - var createUserResult = await _userManager.CreateAsync(newUser, password); - - if (createUserResult.Errors.Any()) - { - var errorMessage = String.Join("\n", - createUserResult.Errors.Select(e => e.Description)); - throw new AuthenticationException(errorMessage); - } - - var addToRoleResult = - await _userManager.AddToRoleAsync(newUser, Application.Common.Models.IdentityRole.User.Name); - - if (addToRoleResult.Errors.Any()) - { - var errorMessage = String.Join("\n", - addToRoleResult.Errors.Select(e => e.Description)); - throw new AuthenticationException(errorMessage); - } - } - - public async Task LoginAsync( - string email, - string password, - CancellationToken cancellationToken) - { - var user = await _userManager.FindByEmailAsync(email); - if (user is null) - { - throw new LoginException("No users registered with given email."); - } - - var isPasswordCorrect = await _userManager.CheckPasswordAsync(user, password); - if (!isPasswordCorrect) - { - throw new LoginException("Given password is incorrect."); - } - - var jwtSecurityToken = await CreateJwtAsync(user, cancellationToken); - var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); - - var refreshToken = user.RefreshTokens.FirstOrDefault(t => t.IsActive); - if (refreshToken is null) - { - refreshToken = CreateRefreshToken(); - refreshToken.IdentityUserId = user.Id; - user.RefreshTokens.Add(refreshToken); - var result = await _userManager.UpdateAsync(user); - } - - return new TokensModel(accessToken, refreshToken.Value); - } - - public async Task RenewAccessTokenAsync( - string refreshToken, - CancellationToken cancellationToken) - { - var user = _userManager.Users.SingleOrDefault(u => - u.RefreshTokens.Any(rt => rt.Value == refreshToken)); - if (user is null) - { - throw new AuthenticationException($"Refresh token was not found."); - } - - var refreshTokenObject = user.RefreshTokens.Single(rt => - rt.Value == refreshToken); - if (!refreshTokenObject.IsActive) - { - throw new AuthenticationException("Refresh token is inactive."); - } - - var jwtSecurityToken = await CreateJwtAsync(user, cancellationToken); - var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); - - return new TokensModel(accessToken, refreshToken); - } - - public async Task RevokeRefreshTokenAsync( - string refreshToken, - CancellationToken cancellationToken) - { - var user = _userManager.Users.SingleOrDefault(u => - u.RefreshTokens.Any(t => t.Value == refreshToken)); - if (user is null) - { - throw new AuthenticationException("Invalid refreshToken"); - } - - var refreshTokenObject = user.RefreshTokens.Single(x => - x.Value == refreshToken); - if (!refreshTokenObject.IsActive) - { - throw new AuthenticationException("RefreshToken already revoked"); - } - - refreshTokenObject.RevokationTimestamp = DateTimeOffset.UtcNow; - await _userManager.UpdateAsync(user); - } - - private async Task CreateJwtAsync( - IdentityUser user, - CancellationToken cancellationToken) - { - var userClaims = await _userManager.GetClaimsAsync(user); - - var roles = await _userManager.GetRolesAsync(user); - var roleClaims = new List(); - foreach (var role in roles) - { - roleClaims.Add(new Claim("roles", role)); - } - - var claims = new List() - { - new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()), - new Claim(JwtRegisteredClaimNames.Email, user.Email) - } - .Union(userClaims) - .Union(roleClaims); - - var expirationDateTimeUtc = DateTime.UtcNow.Add( - _configuration.JsonWebToken.AccessTokenValidity); - - var symmetricSecurityKey = new SymmetricSecurityKey( - Encoding.UTF8.GetBytes(_configuration.JsonWebToken.IssuerSigningKey)); - var signingCredentials = new SigningCredentials( - symmetricSecurityKey, SecurityAlgorithms.HmacSha256); - - var jwtSecurityToken = new JwtSecurityToken( - issuer: _configuration.JsonWebToken.Issuer, - audience: _configuration.JsonWebToken.Audience, - claims: claims, - expires: expirationDateTimeUtc, - signingCredentials: signingCredentials); - - return jwtSecurityToken; - } - - private RefreshToken CreateRefreshToken() - { - var randomNumber = new byte[32]; - - using var rng = RandomNumberGenerator.Create(); - rng.GetNonZeroBytes(randomNumber); - - return new RefreshToken - { - // Id = Guid.NewGuid().ToString(), - Value = Convert.ToBase64String(randomNumber), - CreationTimestamp = DateTimeOffset.UtcNow, - ExpirationTimestamp = DateTimeOffset.UtcNow.Add( - _configuration.JsonWebToken.RefreshTokenValidity) - }; - } -} diff --git a/src/Identity/packages.lock.json b/src/Identity/packages.lock.json deleted file mode 100644 index 5c6200a..0000000 --- a/src/Identity/packages.lock.json +++ /dev/null @@ -1,612 +0,0 @@ -{ - "version": 1, - "dependencies": { - "net9.0": { - "Microsoft.AspNetCore.Authentication.JwtBearer": { - "type": "Direct", - "requested": "[9.0.4, )", - "resolved": "9.0.4", - "contentHash": "0HgfWPfnjlzWFbW4pw6FYNuIMV8obVU+MUkiZ33g4UOpvZcmdWzdayfheKPZ5+EUly8SvfgW0dJwwIrW4IVLZQ==", - "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" - } - }, - "Microsoft.AspNetCore.Identity": { - "type": "Direct", - "requested": "[2.3.1, )", - "resolved": "2.3.1", - "contentHash": "JcQ4pNXg+IISfcR95jeO2ZRt38N67MrUEj28HBmwfqD96BUyw4S54tQhrBmCOyPlf2vgNvSz/tsGAG7EgC0yRg==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Cookies": "2.3.0", - "Microsoft.AspNetCore.Cryptography.KeyDerivation": "2.3.0", - "Microsoft.AspNetCore.Hosting.Abstractions": "2.3.0", - "Microsoft.Extensions.Identity.Core": "2.3.0" - } - }, - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": { - "type": "Direct", - "requested": "[9.0.4, )", - "resolved": "9.0.4", - "contentHash": "IC3X6Db6H0cXdE2zGtyk/jmSwXhHbJZaiNpg7TNFV/Biu/NgO6l/GuwgE0D1U6U9pca00WsqxESkNov+WA77CA==", - "dependencies": { - "Microsoft.EntityFrameworkCore.Relational": "9.0.4", - "Microsoft.Extensions.Identity.Stores": "9.0.4" - } - }, - "Microsoft.Extensions.Options": { - "type": "Direct", - "requested": "[9.0.4, )", - "resolved": "9.0.4", - "contentHash": "fiFI2+58kicqVZyt/6obqoFwHiab7LC4FkQ3mmiBJ28Yy4fAvy2+v9MRnSvvlOO8chTOjKsdafFl/K9veCPo5g==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" - } - }, - "Microsoft.IdentityModel.JsonWebTokens": { - "type": "Direct", - "requested": "[8.8.0, )", - "resolved": "8.8.0", - "contentHash": "lepOkZZTMfJCPSnWITXxV+4Wxb54g+9oIybs9YovlOzZWuR1i2DOpzaDgSe+piDJaGtnSrcUlcB9fZ5Swur7Uw==", - "dependencies": { - "Microsoft.IdentityModel.Tokens": "8.8.0" - } - }, - "Microsoft.IdentityModel.Tokens": { - "type": "Direct", - "requested": "[8.8.0, )", - "resolved": "8.8.0", - "contentHash": "09hnbUJh/18gUmu5nCVFMvyzAFC4l1qyc4bwSJaKzUBqHN7aNDwmSx8dE3/MMJImbvnKq9rEtkkgnrS/OUBtjA==", - "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.IdentityModel.Logging": "8.8.0" - } - }, - "Npgsql.EntityFrameworkCore.PostgreSQL": { - "type": "Direct", - "requested": "[9.0.4, )", - "resolved": "9.0.4", - "contentHash": "mw5vcY2IEc7L+IeGrxpp/J5OSnCcjkjAgJYCm/eD52wpZze8zsSifdqV7zXslSMmfJG2iIUGZyo3KuDtEFKwMQ==", - "dependencies": { - "Microsoft.EntityFrameworkCore": "[9.0.1, 10.0.0)", - "Microsoft.EntityFrameworkCore.Relational": "[9.0.1, 10.0.0)", - "Npgsql": "9.0.3" - } - }, - "AspNetCore.Localizer.Json": { - "type": "Transitive", - "resolved": "1.0.1", - "contentHash": "Qfv5l+8X9hLRWt6aB4+fjTzz2Pt4wwrMwwfcyrY4t85sJ+7CuB8Jl9f+yccWfFsAZSODKBAz7yFXidaYslsjlA==", - "dependencies": { - "Microsoft.AspNetCore.Components": "9.0.0", - "Microsoft.Extensions.Caching.Memory": "9.0.0", - "Microsoft.Extensions.Localization": "9.0.0" - } - }, - "AutoMapper": { - "type": "Transitive", - "resolved": "14.0.0", - "contentHash": "OC+1neAPM4oCCqQj3g2GJ2shziNNhOkxmNB9cVS8jtx4JbgmRzLcUOxB9Tsz6cVPHugdkHgCaCrTjjSI0Z5sCQ==", - "dependencies": { - "Microsoft.Extensions.Options": "8.0.0" - } - }, - "FluentValidation": { - "type": "Transitive", - "resolved": "11.11.0", - "contentHash": "cyIVdQBwSipxWG8MA3Rqox7iNbUNUTK5bfJi9tIdm4CAfH71Oo5ABLP4/QyrUwuakqpUEPGtE43BDddvEehuYw==" - }, - "MediatR": { - "type": "Transitive", - "resolved": "12.4.1", - "contentHash": "0tLxCgEC5+r1OCuumR3sWyiVa+BMv3AgiU4+pz8xqTc+2q1WbUEXFOr7Orm96oZ9r9FsldgUtWvB2o7b9jDOaw==", - "dependencies": { - "MediatR.Contracts": "[2.0.1, 3.0.0)", - "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" - } - }, - "MediatR.Behaviors.Authorization": { - "type": "Transitive", - "resolved": "12.2.0", - "contentHash": "/rXuisxwJviu9PIffZlcZ6UY0MafX8dNtRi0bS04KciEVxkln8txJZt+rvKgerW3zKdKHfqt2EwRuiOCN9Aszg==", - "dependencies": { - "MediatR": "12.4.1", - "MediatR.Contracts": "2.0.1" - } - }, - "MediatR.Contracts": { - "type": "Transitive", - "resolved": "2.0.1", - "contentHash": "FYv95bNT4UwcNA+G/J1oX5OpRiSUxteXaUt2BJbRSdRNiIUNbggJF69wy6mnk2wYToaanpdXZdCwVylt96MpwQ==" - }, - "Microsoft.AspNetCore.Authentication": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "Tq6bxTOe65Ikh9dWVTEOqpvNqBGIQueO0J+zl2rQba0yP0YV66iYDkSz9MqTdRZftvJ2I5kMeRUm9Z2mjEAbUQ==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Core": "2.3.0", - "Microsoft.AspNetCore.DataProtection": "2.3.0", - "Microsoft.AspNetCore.Http": "2.3.0", - "Microsoft.AspNetCore.Http.Extensions": "2.3.0", - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.Extensions.Options": "8.0.2", - "Microsoft.Extensions.WebEncoders": "8.0.11" - } - }, - "Microsoft.AspNetCore.Authentication.Abstractions": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "ve6uvLwKNRkfnO/QeN9M8eUJ49lCnWv/6/9p6iTEuiI6Rtsz+myaBAjdMzLuTViQY032xbTF5AdZF5BJzJJyXQ==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.3.0", - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.Extensions.Options": "8.0.2" - } - }, - "Microsoft.AspNetCore.Authentication.Cookies": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "w3JPWHreXJ/Uv9CLkQtGCLwTbxZKY+94QPVi1RxcMuBTyRp+C9SdynznHEjnHWnw6QFNEHnBuHmWW3OYrvbpEQ==", - "dependencies": { - "Microsoft.AspNetCore.Authentication": "2.3.0" - } - }, - "Microsoft.AspNetCore.Authentication.Core": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "gnLnKGawBjqBnU9fEuel3VcYAARkjyONAliaGDfMc8o8HBtfh+HrOPEoR8Xx4b2RnMb7uxdBDOvEAC7sul79ig==", - "dependencies": { - "Microsoft.AspNetCore.Authentication.Abstractions": "2.3.0", - "Microsoft.AspNetCore.Http": "2.3.0", - "Microsoft.AspNetCore.Http.Extensions": "2.3.0" - } - }, - "Microsoft.AspNetCore.Authorization": { - "type": "Transitive", - "resolved": "9.0.0", - "contentHash": "qDJlBC5pUQ/3o6/C6Vuo9CGKtV5TAe5AdKeHvDR2bgmw8vwPxsAy3KG5eU0i1C+iAUNbmq+iDTbiKt16f9pRiA==", - "dependencies": { - "Microsoft.AspNetCore.Metadata": "9.0.0", - "Microsoft.Extensions.Logging.Abstractions": "9.0.0", - "Microsoft.Extensions.Options": "9.0.0" - } - }, - "Microsoft.AspNetCore.Components": { - "type": "Transitive", - "resolved": "9.0.0", - "contentHash": "xKzY0LRqWrwuPVzKIF9k1kC21NrLmIE2qPhhKlInEAdYqNe8qcMoPWZy7fo1uScHkz5g73nTqDDra3+aAV7mTQ==", - "dependencies": { - "Microsoft.AspNetCore.Authorization": "9.0.0", - "Microsoft.AspNetCore.Components.Analyzers": "9.0.0" - } - }, - "Microsoft.AspNetCore.Components.Analyzers": { - "type": "Transitive", - "resolved": "9.0.0", - "contentHash": "maOE1qlJ9hf1Fb7PhFLw9bgP9mWckuDOcn1uKNt9/msdJG2YHl3cPRHojYa6CxliGHIXL8Da4qPgeUc4CaOoeg==" - }, - "Microsoft.AspNetCore.Cryptography.Internal": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "E4pHyEb2Ul5a6bIwraGtw9TN39a/C2asyVPEJoyItc0reV4Y26FsPcEdcXyKjBbP4kSz9iU1Cz4Yhx/aOFPpqA==" - }, - "Microsoft.AspNetCore.Cryptography.KeyDerivation": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "5v9Kj2arRrCftLKW80Hfj31HkNnjcKyw57lQhF84drvGxJlCR63J0zMM1sMM+Hc+KCQjuoDmHtjwN0uOT+X3ag==", - "dependencies": { - "Microsoft.AspNetCore.Cryptography.Internal": "9.0.4" - } - }, - "Microsoft.AspNetCore.DataProtection": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "C+FhGaA8ekrfes0Ujhtkhk74Bpkt6Zt+NrMaGrCWBqW1LFzqw/pXDbMbpcAyI9hbYgZfC6+t01As4LGXbdxG4A==", - "dependencies": { - "Microsoft.AspNetCore.Cryptography.Internal": "2.3.0", - "Microsoft.AspNetCore.DataProtection.Abstractions": "2.3.0", - "Microsoft.AspNetCore.Hosting.Abstractions": "2.3.0", - "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2", - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.Extensions.Options": "8.0.2", - "Microsoft.Win32.Registry": "4.5.0", - "System.Security.Cryptography.Xml": "8.0.2", - "System.Security.Principal.Windows": "5.0.0" - } - }, - "Microsoft.AspNetCore.DataProtection.Abstractions": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "71GdtUkVDagLsBt+YatfzUItnbT2vIjHxWySNE2MkgIDhqT3g4sNNxOj/0PlPTpc1+mG3ZwfUoZ61jIt1wPw7g==" - }, - "Microsoft.AspNetCore.Hosting.Abstractions": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "4ivq53W2k6Nj4eez9wc81ytfGj6HR1NaZJCpOrvghJo9zHuQF57PLhPoQH5ItyCpHXnrN/y7yJDUm+TGYzrx0w==", - "dependencies": { - "Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.3.0", - "Microsoft.AspNetCore.Http.Abstractions": "2.3.0", - "Microsoft.Extensions.Hosting.Abstractions": "8.0.1" - } - }, - "Microsoft.AspNetCore.Hosting.Server.Abstractions": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "F5iHx7odAbFKBV1DNPDkFFcVmD5Tk7rk+tYm3LMQxHEFFdjlg5QcYb5XhHAefl5YaaPeG6ad+/ck8kSG3/D6kw==", - "dependencies": { - "Microsoft.AspNetCore.Http.Features": "2.3.0", - "Microsoft.Extensions.Configuration.Abstractions": "8.0.0" - } - }, - "Microsoft.AspNetCore.Http": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "I9azEG2tZ4DDHAFgv+N38e6Yhttvf+QjE2j2UYyCACE7Swm5/0uoihCMWZ87oOZYeqiEFSxbsfpT71OYHe2tpw==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.3.0", - "Microsoft.AspNetCore.WebUtilities": "2.3.0", - "Microsoft.Extensions.ObjectPool": "8.0.11", - "Microsoft.Extensions.Options": "8.0.2", - "Microsoft.Net.Http.Headers": "2.3.0" - } - }, - "Microsoft.AspNetCore.Http.Abstractions": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "39r9PPrjA6s0blyFv5qarckjNkaHRA5B+3b53ybuGGNTXEj1/DStQJ4NWjFL6QTRQpL9zt7nDyKxZdJOlcnq+Q==", - "dependencies": { - "Microsoft.AspNetCore.Http.Features": "2.3.0", - "System.Text.Encodings.Web": "8.0.0" - } - }, - "Microsoft.AspNetCore.Http.Extensions": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "EY2u/wFF5jsYwGXXswfQWrSsFPmiXsniAlUWo3rv/MGYf99ZFsENDnZcQP6W3c/+xQmQXq0NauzQ7jyy+o1LDQ==", - "dependencies": { - "Microsoft.AspNetCore.Http.Abstractions": "2.3.0", - "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", - "Microsoft.Net.Http.Headers": "2.3.0", - "System.Buffers": "4.6.0" - } - }, - "Microsoft.AspNetCore.Http.Features": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "f10WUgcsKqrkmnz6gt8HeZ7kyKjYN30PO7cSic1lPtH7paPtnQqXPOveul/SIPI43PhRD4trttg4ywnrEmmJpA==", - "dependencies": { - "Microsoft.Extensions.Primitives": "8.0.0" - } - }, - "Microsoft.AspNetCore.Metadata": { - "type": "Transitive", - "resolved": "9.0.0", - "contentHash": "X81C891nMuWgzNHyZ0C3s+blSDxRHzQHDFYQoOKtFvFuxGq3BbkLbc5CfiCqIzA/sWIfz6u8sGBgwntQwBJWBw==" - }, - "Microsoft.AspNetCore.WebUtilities": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "trbXdWzoAEUVd0PE2yTopkz4kjZaAIA7xUWekd5uBw+7xE8Do/YOVTeb9d9koPTlbtZT539aESJjSLSqD8eYrQ==", - "dependencies": { - "Microsoft.Net.Http.Headers": "2.3.0", - "System.Text.Encodings.Web": "8.0.0" - } - }, - "Microsoft.EntityFrameworkCore": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "+5IAX0aicQYCRfN4pAjad+JPwdEYoVEM3Z1Cl8/EiEv3FVHQHdd8TJQpQIslQDDQS/UsUMb0MsOXwqOh+TJtRw==", - "dependencies": { - "Microsoft.EntityFrameworkCore.Abstractions": "9.0.4", - "Microsoft.EntityFrameworkCore.Analyzers": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" - } - }, - "Microsoft.EntityFrameworkCore.Abstractions": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "E0pkWzI0liqu2ogqJ1kohk2eGkYRhf5tI75HGF6IQDARsshY/0w+prGyLvNuUeV7B8I7vYQZ4CzAKYKxw7b9gQ==" - }, - "Microsoft.EntityFrameworkCore.Analyzers": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "cMsm1O7g9X5qbB2wjHf3BVVvGwkG+zeXQ+M91I1Bm6RfylFMImqBPzs0+vmuef7fPxr2yOzPhIfJ2wQJfmtaSw==" - }, - "Microsoft.EntityFrameworkCore.Relational": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "OjJ+xh/wQff5b0wiC3SPvoQqTA2boZeJQf+15+3+OJPtjBKzvxuwr25QRIu1p1t+K8ryQ8pzaoZ7eOpXfNzVGA==", - "dependencies": { - "Microsoft.EntityFrameworkCore": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" - } - }, - "Microsoft.Extensions.Caching.Abstractions": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "imcZ5BGhBw5mNsWLepBbqqumWaFe0GtvyCvne2/2wsDIBRa2+Lhx4cU/pKt/4BwOizzUEOls2k1eOJQXHGMalg==", - "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.4" - } - }, - "Microsoft.Extensions.Caching.Memory": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "G5rEq1Qez5VJDTEyRsRUnewAspKjaY57VGsdZ8g8Ja6sXXzoiI3PpTd1t43HjHqNWD5A06MQveb2lscn+2CU+w==", - "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "9.0.4", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4", - "Microsoft.Extensions.Logging.Abstractions": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" - } - }, - "Microsoft.Extensions.Configuration.Abstractions": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0LN/DiIKvBrkqp7gkF3qhGIeZk6/B63PthAHjQsxymJfIBcz0kbf4/p/t4lMgggVxZ+flRi5xvTwlpPOoZk8fg==", - "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.4" - } - }, - "Microsoft.Extensions.DependencyInjection": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "f2MTUaS2EQ3lX4325ytPAISZqgBfXmY0WvgD80ji6Z20AoDNiCESxsqo6mFRwHJD/jfVKRw9FsW6+86gNre3ug==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4" - } - }, - "Microsoft.Extensions.DependencyInjection.Abstractions": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "UI0TQPVkS78bFdjkTodmkH0Fe8lXv9LnhGFKgKrsgUJ5a5FVdFRcgjIkBVLbGgdRhxWirxH/8IXUtEyYJx6GQg==" - }, - "Microsoft.Extensions.Diagnostics.Abstractions": { - "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "elH2vmwNmsXuKmUeMQ4YW9ldXiF+gSGDgg1vORksob5POnpaI6caj1Hu8zaYbEuibhqCoWg0YRWDazBY3zjBfg==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2", - "Microsoft.Extensions.Options": "8.0.2" - } - }, - "Microsoft.Extensions.FileProviders.Abstractions": { - "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==", - "dependencies": { - "Microsoft.Extensions.Primitives": "8.0.0" - } - }, - "Microsoft.Extensions.Hosting.Abstractions": { - "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "nHwq9aPBdBPYXPti6wYEEfgXddfBrYC+CQLn+qISiwQq5tpfaqDZSKOJNxoe9rfQxGf1c+2wC/qWFe1QYJPYqw==", - "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "8.0.0", - "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2", - "Microsoft.Extensions.Diagnostics.Abstractions": "8.0.1", - "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", - "Microsoft.Extensions.Logging.Abstractions": "8.0.2" - } - }, - "Microsoft.Extensions.Identity.Core": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "KKfCsoIHFGZmmCEjZBPuvDW0pCjboMru/Z3vbEyC/OIwUVeKrdPugFyjc81i7rNSjcPcDxVvGl/Ks8HLelKocg==", - "dependencies": { - "Microsoft.AspNetCore.Cryptography.KeyDerivation": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4" - } - }, - "Microsoft.Extensions.Identity.Stores": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0F6lSngwyXzrv+qtX46nhHYBOlPxEzj0qyCCef1kvlyEYhbj8kBL13FuDk4nEPkzk1yVjZgsnXBG19+TrNdakQ==", - "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "9.0.4", - "Microsoft.Extensions.Identity.Core": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" - } - }, - "Microsoft.Extensions.Localization": { - "type": "Transitive", - "resolved": "9.0.0", - "contentHash": "Up8Juy8Bh+vL+fXmMWsoSg/G6rszmLFiF44aI2tpOMJE7Ln4D9s37YxOOm81am4Z+V7g8Am3AgVwHYJzi+cL/g==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0", - "Microsoft.Extensions.Localization.Abstractions": "9.0.0", - "Microsoft.Extensions.Logging.Abstractions": "9.0.0", - "Microsoft.Extensions.Options": "9.0.0" - } - }, - "Microsoft.Extensions.Localization.Abstractions": { - "type": "Transitive", - "resolved": "9.0.0", - "contentHash": "wc7PaRhPOnio5Csj80b3UgBWA5l6bp28EhGem7gtfpVopcwbkfPb2Sk8Cu6eBnIW3ZNf1YUgYJzwtjzZEM8+iw==" - }, - "Microsoft.Extensions.Logging": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "xW6QPYsqhbuWBO9/1oA43g/XPKbohJx+7G8FLQgQXIriYvY7s+gxr2wjQJfRoPO900dvvv2vVH7wZovG+M1m6w==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection": "9.0.4", - "Microsoft.Extensions.Logging.Abstractions": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4" - } - }, - "Microsoft.Extensions.Logging.Abstractions": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0MXlimU4Dud6t+iNi5NEz3dO2w1HXdhoOLaYFuLPCjAsvlPQGwOT6V2KZRMLEhCAm/stSZt1AUv0XmDdkjvtbw==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4" - } - }, - "Microsoft.Extensions.ObjectPool": { - "type": "Transitive", - "resolved": "8.0.11", - "contentHash": "6ApKcHNJigXBfZa6XlDQ8feJpq7SG1ogZXg6M4FiNzgd6irs3LUAzo0Pfn4F2ZI9liGnH1XIBR/OtSbZmJAV5w==" - }, - "Microsoft.Extensions.Primitives": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "SPFyMjyku1nqTFFJ928JAMd0QnRe4xjE7KeKnZMWXf3xk+6e0WiOZAluYtLdbJUXtsl2cCRSi8cBquJ408k8RA==" - }, - "Microsoft.Extensions.WebEncoders": { - "type": "Transitive", - "resolved": "8.0.11", - "contentHash": "EwF+KaQzTa/MoIm8gciABL6xeeiGKowqyam+lPYWukTppwch1P3QeL8CpgtLs8kIWuEowpAAUrVfP1kyZsZgqg==", - "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2", - "Microsoft.Extensions.Options": "8.0.2" - } - }, - "Microsoft.IdentityModel.Abstractions": { - "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "0lKw+f3vkmV9t3PLe6sY3xPrYrHYiMRFxuOse5CMkKPxhQYiabpfJsuk6wX2RrVQ86Dn+t/8poHpH0nbp6sFvA==" - }, - "Microsoft.IdentityModel.Logging": { - "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "sUyoxzg/WBZobbFLJK8loT9IILKtS9ePmWu5B11ogQqhSHppE6SRZKw0fhI6Fd16X6ey52cbbWc2rvMBC98EQA==", - "dependencies": { - "Microsoft.IdentityModel.Abstractions": "8.8.0" - } - }, - "Microsoft.IdentityModel.Protocols": { - "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", - "dependencies": { - "Microsoft.IdentityModel.Tokens": "8.0.1" - } - }, - "Microsoft.IdentityModel.Protocols.OpenIdConnect": { - "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", - "dependencies": { - "Microsoft.IdentityModel.Protocols": "8.0.1", - "System.IdentityModel.Tokens.Jwt": "8.0.1" - } - }, - "Microsoft.Net.Http.Headers": { - "type": "Transitive", - "resolved": "2.3.0", - "contentHash": "/M0wVg6tJUOHutWD3BMOUVZAioJVXe0tCpFiovzv0T9T12TBf4MnaHP0efO8TCr1a6O9RZgQeZ9Gdark8L9XdA==", - "dependencies": { - "Microsoft.Extensions.Primitives": "8.0.0", - "System.Buffers": "4.6.0" - } - }, - "Microsoft.NETCore.Platforms": { - "type": "Transitive", - "resolved": "2.0.0", - "contentHash": "VdLJOCXhZaEMY7Hm2GKiULmn7IEPFE4XC5LPSfBVCUIA8YLZVh846gtfBJalsPQF2PlzdD7ecX7DZEulJ402ZQ==" - }, - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "+FWlwd//+Tt56316p00hVePBCouXyEzT86Jb3+AuRotTND0IYn0OO3obs1gnQEs/txEnt+rF2JBGLItTG+Be6A==", - "dependencies": { - "System.Security.AccessControl": "4.5.0", - "System.Security.Principal.Windows": "4.5.0" - } - }, - "Newtonsoft.Json": { - "type": "Transitive", - "resolved": "13.0.3", - "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" - }, - "Npgsql": { - "type": "Transitive", - "resolved": "9.0.3", - "contentHash": "tPvY61CxOAWxNsKLEBg+oR646X4Bc8UmyQ/tJszL/7mEmIXQnnBhVJZrZEEUv0Bstu0mEsHZD5At3EO8zQRAYw==", - "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "8.0.2" - } - }, - "QuikGraph": { - "type": "Transitive", - "resolved": "2.5.0", - "contentHash": "sG+mrPpXwxlXknRK5VqWUGiOmDACa9X+3ftlkQIMgOZUqxVOQSe0+HIU9PTjwqazy0pqSf8MPDXYFGl0GYWcKw==" - }, - "System.Buffers": { - "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" - }, - "System.IdentityModel.Tokens.Jwt": { - "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "GJw3bYkWpOgvN3tJo5X4lYUeIFA2HD293FPUhKmp7qxS+g5ywAb34Dnd3cDAFLkcMohy5XTpoaZ4uAHuw0uSPQ==", - "dependencies": { - "Microsoft.IdentityModel.JsonWebTokens": "8.0.1", - "Microsoft.IdentityModel.Tokens": "8.0.1" - } - }, - "System.Linq.Dynamic.Core": { - "type": "Transitive", - "resolved": "1.6.2", - "contentHash": "piIcdelf4dGotuIjFlyu7JLIZkYTmYM0ZTLGpCcxs9iCJFflhJht0nchkIV+GS5wfA3OtC3QNjIcUqyOdBdOsA==" - }, - "System.Security.AccessControl": { - "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "vW8Eoq0TMyz5vAG/6ce483x/CP83fgm4SJe5P8Tb1tZaobcvPrbMEL7rhH1DRdrYbbb6F0vq3OlzmK0Pkwks5A==", - "dependencies": { - "Microsoft.NETCore.Platforms": "2.0.0", - "System.Security.Principal.Windows": "4.5.0" - } - }, - "System.Security.Cryptography.Pkcs": { - "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "CoCRHFym33aUSf/NtWSVSZa99dkd0Hm7OCZUxORBjRB16LNhIEOf8THPqzIYlvKM0nNDAPTRBa1FxEECrgaxxA==" - }, - "System.Security.Cryptography.Xml": { - "type": "Transitive", - "resolved": "8.0.2", - "contentHash": "aDM/wm0ZGEZ6ZYJLzgqjp2FZdHbDHh6/OmpGfb7AdZ105zYmPn/83JRU2xLIbwgoNz9U1SLUTJN0v5th3qmvjA==", - "dependencies": { - "System.Security.Cryptography.Pkcs": "8.0.1" - } - }, - "System.Security.Principal.Windows": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" - }, - "System.Text.Encodings.Web": { - "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" - }, - "application": { - "type": "Project", - "dependencies": { - "AspNetCore.Localizer.Json": "[1.0.1, )", - "AutoMapper": "[14.0.0, )", - "Domain": "[1.0.0, )", - "FluentValidation": "[11.11.0, )", - "MediatR": "[12.4.1, )", - "MediatR.Behaviors.Authorization": "[12.2.0, )", - "Microsoft.Extensions.Logging": "[9.0.4, )", - "Newtonsoft.Json": "[13.0.3, )", - "QuikGraph": "[2.5.0, )", - "System.Linq.Dynamic.Core": "[1.6.2, )" - } - }, - "domain": { - "type": "Project" - } - } - } -} \ No newline at end of file diff --git a/src/Infrastructure/Services/ExchangeApiCurrencyConverterService.cs b/src/Infrastructure/Services/ExchangeApiCurrencyConverterService.cs index e2bd323..7c36d53 100644 --- a/src/Infrastructure/Services/ExchangeApiCurrencyConverterService.cs +++ b/src/Infrastructure/Services/ExchangeApiCurrencyConverterService.cs @@ -1,5 +1,5 @@ using System.Globalization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; +using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Enums; using Newtonsoft.Json; diff --git a/src/Infrastructure/Services/LiqPayPaymentService.cs b/src/Infrastructure/Services/LiqPayPaymentService.cs index 70fc88b..dce188b 100644 --- a/src/Infrastructure/Services/LiqPayPaymentService.cs +++ b/src/Infrastructure/Services/LiqPayPaymentService.cs @@ -8,7 +8,7 @@ using Newtonsoft.Json; namespace cuqmbr.TravelGuide.Infrastructure.Services; public sealed class LiqPayPaymentService : - cuqmbr.TravelGuide.Application.Common.Interfaces.Services.LiqPayPaymentService + cuqmbr.TravelGuide.Application.Common.Services.LiqPayPaymentService { private readonly LiqPayConfigurationOptions _configuration; private readonly string _callbackAddressBase; diff --git a/src/Infrastructure/Services/Pbkdf2PasswordHasherService.cs b/src/Infrastructure/Services/Pbkdf2PasswordHasherService.cs new file mode 100644 index 0000000..2f4e5bf --- /dev/null +++ b/src/Infrastructure/Services/Pbkdf2PasswordHasherService.cs @@ -0,0 +1,32 @@ +using System.Security.Cryptography; +using cuqmbr.TravelGuide.Application.Common.Services; + +namespace cuqmbr.TravelGuide.Infrastructure.Services; + +public sealed class Pbkdf2PasswordHasherService : PasswordHasherService +{ + private const int IterationCount = 210_000; + + private readonly HashAlgorithmName Hash = HashAlgorithmName.SHA3_512; + private const byte HashLengthBytes = 64; + + public Task HashAsync(byte[] password, byte[] salt, + CancellationToken cancellationToken) + { + return Task.FromResult( + Rfc2898DeriveBytes.Pbkdf2( + password, salt, IterationCount, + Hash, HashLengthBytes)); + } + + public Task IsValidHashAsync(byte[] hash, byte[] password, + byte[] salt, CancellationToken cancellationToken) + { + var computedHash = Rfc2898DeriveBytes.Pbkdf2( + password, salt, IterationCount, + Hash, HashLengthBytes); + + return Task.FromResult( + Enumerable.SequenceEqual(computedHash, hash)); + } +} diff --git a/src/Infrastructure/packages.lock.json b/src/Infrastructure/packages.lock.json index b07e4dd..47ecef3 100644 --- a/src/Infrastructure/packages.lock.json +++ b/src/Infrastructure/packages.lock.json @@ -68,6 +68,14 @@ "resolved": "2.0.1", "contentHash": "FYv95bNT4UwcNA+G/J1oX5OpRiSUxteXaUt2BJbRSdRNiIUNbggJF69wy6mnk2wYToaanpdXZdCwVylt96MpwQ==" }, + "Microsoft.AspNetCore.Authentication.JwtBearer": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "8J04KPX5NCo6j5AjY/rgeLTceMBJ8Sq4k+YNxN/7hCrbCH1iwHVw7VGGvlCscj615ewMX3jYDmxxLdutbSPOcA==", + "dependencies": { + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" + } + }, "Microsoft.AspNetCore.Authorization": { "type": "Transitive", "resolved": "9.0.0", @@ -234,11 +242,67 @@ "resolved": "9.0.4", "contentHash": "SPFyMjyku1nqTFFJ928JAMd0QnRe4xjE7KeKnZMWXf3xk+6e0WiOZAluYtLdbJUXtsl2cCRSi8cBquJ408k8RA==" }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "X92UuBmvHYtsVrD+R+senFn6wOtSVtliSZNTZI8oHD+WqhYLmLNlHH6avYcbXqEznozxshSYzD/DVAuz54jjtg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "rLvApg2vqs/Kz5kVHwHUMAe3owInYrsPX8QP8CQktubX9R63P+J47nR/IOS4n6ddJCvGInUGRBKqcBGJtuA4Rw==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.11.0" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "/JNOMdYOQ4Tgbdwu9GbEcRJEpzakizuECCE8dCgY5lKXyqZUdAKXyeq4zITgS81eZYThqjhQZUYaJxOPofbmrg==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.11.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.0.1" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "8.0.1", + "System.IdentityModel.Tokens.Jwt": "8.0.1" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "E0iKSD9vv9X+tbHGriMTLkSNK/OOjxOPuf1dt9q32d25Ig+OZaidUqDoUTSS3mWTvPw+x5oXrCTHtDatbzRzTQ==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.11.0" + } + }, "QuikGraph": { "type": "Transitive", "resolved": "2.5.0", "contentHash": "sG+mrPpXwxlXknRK5VqWUGiOmDACa9X+3ftlkQIMgOZUqxVOQSe0+HIU9PTjwqazy0pqSf8MPDXYFGl0GYWcKw==" }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "GJw3bYkWpOgvN3tJo5X4lYUeIFA2HD293FPUhKmp7qxS+g5ywAb34Dnd3cDAFLkcMohy5XTpoaZ4uAHuw0uSPQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.0.1", + "Microsoft.IdentityModel.Tokens": "8.0.1" + } + }, "System.Linq.Dynamic.Core": { "type": "Transitive", "resolved": "1.6.2", @@ -253,7 +317,10 @@ "FluentValidation": "[11.11.0, )", "MediatR": "[12.4.1, )", "MediatR.Behaviors.Authorization": "[12.2.0, )", + "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.5, )", "Microsoft.Extensions.Logging": "[9.0.4, )", + "Microsoft.IdentityModel.JsonWebTokens": "[8.11.0, )", + "Microsoft.IdentityModel.Tokens": "[8.11.0, )", "Newtonsoft.Json": "[13.0.3, )", "QuikGraph": "[2.5.0, )", "System.Linq.Dynamic.Core": "[1.6.2, )" diff --git a/src/Persistence/DbSeeder.cs b/src/Persistence/DbSeeder.cs index baefefe..229bc7d 100644 --- a/src/Persistence/DbSeeder.cs +++ b/src/Persistence/DbSeeder.cs @@ -1,12 +1,105 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; +using System.Security.Cryptography; +using System.Text; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Entities; +using cuqmbr.TravelGuide.Domain.Enums; +using Microsoft.Extensions.DependencyInjection; namespace cuqmbr.TravelGuide.Persistence; public static class DbSeeder { - public static void Seed(UnitOfWork unitOfWork) + public static void Seed(IServiceProvider serviceProvider) { - // Do Seeding Here + var unitOfWork = + serviceProvider.GetRequiredService(); + + var passwordHasher = + serviceProvider.GetRequiredService(); + + + // Seed Roles + { + var datastoreRoles = unitOfWork.RoleRepository + .GetPageAsync(1, IdentityRole.Enumerations.Count, + CancellationToken.None) + .Result.Items.Select(r => r.Value); + + var roles = IdentityRole.Enumerations.Select(r => r.Value); + + foreach (var role in roles) + { + + if (datastoreRoles.Contains(role)) + { + continue; + } + + unitOfWork.RoleRepository.AddOneAsync( + new Role() { Value = role }, + CancellationToken.None).Wait(); + } + + unitOfWork.SaveAsync(CancellationToken.None).Wait(); + } + + // Seed Accounts + { + var accounts = + new (string Username, string Email, + string Password, IdentityRole[] Roles)[] + { + ("admin", "admin", "admin", + new [] { IdentityRole.Administrator }), + }; + + var roles = unitOfWork.RoleRepository + .GetPageAsync(1, IdentityRole.Enumerations.Count, + CancellationToken.None) + .Result.Items; + + foreach (var account in accounts) + { + var datastoreAccount = + unitOfWork.AccountRepository.GetOneAsync( + e => e.Email == account.Email, CancellationToken.None) + .Result; + + if (datastoreAccount != null) + { + continue; + } + + var password = Encoding.UTF8.GetBytes(account.Password); + + var salt = RandomNumberGenerator.GetBytes(128 / 8); + var hash = passwordHasher + .HashAsync(password, salt, CancellationToken.None) + .Result; + + var saltBase64 = Convert.ToBase64String(salt); + var hashBase64 = Convert.ToBase64String(hash); + + unitOfWork.AccountRepository.AddOneAsync( + new Account() + { + Username = account.Username, + Email = account.Email, + PasswordHash = hashBase64, + PasswordSalt = saltBase64, + AccountRoles = account.Roles.Select(ar => + new AccountRole() + { + RoleId = roles.Single(dr => dr.Value.Equals(ar)).Id + }) + .ToArray() + }, + CancellationToken.None).Wait(); + } + + unitOfWork.SaveAsync(CancellationToken.None).Wait(); + } unitOfWork.Dispose(); } diff --git a/src/Persistence/InMemory/InMemoryDbContext.cs b/src/Persistence/InMemory/InMemoryDbContext.cs index 41f3171..2d41303 100644 --- a/src/Persistence/InMemory/InMemoryDbContext.cs +++ b/src/Persistence/InMemory/InMemoryDbContext.cs @@ -55,5 +55,11 @@ public class InMemoryDbContext : DbContext builder .Properties() .HaveConversion(); + + + builder + .Properties() + .HaveColumnType("varchar(64)") + .HaveConversion(); } } diff --git a/src/Persistence/InMemory/InMemoryUnitOfWork.cs b/src/Persistence/InMemory/InMemoryUnitOfWork.cs index c04be86..ee832c6 100644 --- a/src/Persistence/InMemory/InMemoryUnitOfWork.cs +++ b/src/Persistence/InMemory/InMemoryUnitOfWork.cs @@ -1,5 +1,5 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Persistence.InMemory.Repositories; namespace cuqmbr.TravelGuide.Persistence.InMemory; @@ -34,6 +34,11 @@ public sealed class InMemoryUnitOfWork : UnitOfWork new InMemoryRouteAddressDetailRepository(_dbContext); VehicleEnrollmentEmployeeRepository = new InMemoryVehicleEnrollmentEmployeeRepository(_dbContext); + + AccountRepository = new InMemoryAccountRepository(_dbContext); + RoleRepository = new InMemoryRoleRepository(_dbContext); + AccountRoleRepository = new InMemoryAccountRoleRepository(_dbContext); + RefreshTokenRepository = new InMemoryRefreshTokenRepository(_dbContext); } public CountryRepository CountryRepository { get; init; } @@ -70,6 +75,15 @@ public sealed class InMemoryUnitOfWork : UnitOfWork public VehicleEnrollmentEmployeeRepository VehicleEnrollmentEmployeeRepository { get; init; } + + public AccountRepository AccountRepository { get; init; } + + public RoleRepository RoleRepository { get; init; } + + public AccountRoleRepository AccountRoleRepository { get; init; } + + public RefreshTokenRepository RefreshTokenRepository { get; init; } + public int Save() { return _dbContext.SaveChanges(); diff --git a/src/Persistence/InMemory/Repositories/InMemoryAccountRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryAccountRepository.cs new file mode 100644 index 0000000..aa24b2e --- /dev/null +++ b/src/Persistence/InMemory/Repositories/InMemoryAccountRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; + +public sealed class InMemoryAccountRepository : + InMemoryBaseRepository, AccountRepository +{ + public InMemoryAccountRepository(InMemoryDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/InMemory/Repositories/InMemoryAccountRoleRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryAccountRoleRepository.cs new file mode 100644 index 0000000..eed11a7 --- /dev/null +++ b/src/Persistence/InMemory/Repositories/InMemoryAccountRoleRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; + +public sealed class InMemoryAccountRoleRepository : + InMemoryBaseRepository, AccountRoleRepository +{ + public InMemoryAccountRoleRepository(InMemoryDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/InMemory/Repositories/InMemoryAddressRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryAddressRepository.cs index 3b206f1..95982ab 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryAddressRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryAddressRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryAircraftRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryAircraftRepository.cs index 86373d5..cb203b6 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryAircraftRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryAircraftRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryBaseRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryBaseRepository.cs index 8e628a8..609ab72 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryBaseRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryBaseRepository.cs @@ -1,5 +1,5 @@ using System.Linq.Expressions; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Domain.Entities; using Microsoft.EntityFrameworkCore; diff --git a/src/Persistence/InMemory/Repositories/InMemoryBusRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryBusRepository.cs index 2180258..6b40e7b 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryBusRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryBusRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryCityRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryCityRepository.cs index 22f942a..b6aca53 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryCityRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryCityRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryCompanyRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryCompanyRepository.cs index 66b2516..8d65211 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryCompanyRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryCompanyRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryCountryRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryCountryRepository.cs index a0e0e1f..bc9812f 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryCountryRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryCountryRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryEmployeeRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryEmployeeRepository.cs index 40e9b63..939f74e 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryEmployeeRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryEmployeeRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryRefreshTokenRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryRefreshTokenRepository.cs new file mode 100644 index 0000000..dff079b --- /dev/null +++ b/src/Persistence/InMemory/Repositories/InMemoryRefreshTokenRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; + +public sealed class InMemoryRefreshTokenRepository : + InMemoryBaseRepository, RefreshTokenRepository +{ + public InMemoryRefreshTokenRepository(InMemoryDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/InMemory/Repositories/InMemoryRegionRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryRegionRepository.cs index 63a668e..5d7e7ee 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryRegionRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryRegionRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryRoleRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryRoleRepository.cs new file mode 100644 index 0000000..81bbbc4 --- /dev/null +++ b/src/Persistence/InMemory/Repositories/InMemoryRoleRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; + +public sealed class InMemoryRoleRepository : + InMemoryBaseRepository, RoleRepository +{ + public InMemoryRoleRepository(InMemoryDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/InMemory/Repositories/InMemoryRouteAddressDetailRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryRouteAddressDetailRepository.cs index 992e9a1..9a7ee0b 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryRouteAddressDetailRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryRouteAddressDetailRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryRouteAddressRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryRouteAddressRepository.cs index ce24624..70e6141 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryRouteAddressRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryRouteAddressRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryRouteRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryRouteRepository.cs index f728978..27bb20f 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryRouteRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryRouteRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryTicketGroupRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryTicketGroupRepository.cs index 613715b..b160761 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryTicketGroupRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryTicketGroupRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryTicketRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryTicketRepository.cs index ab406b0..398bbab 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryTicketRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryTicketRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryTrainRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryTrainRepository.cs index 603b223..971391c 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryTrainRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryTrainRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentEmployeeRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentEmployeeRepository.cs index d9b8d21..3705f86 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentEmployeeRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentEmployeeRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentRepository.cs index 2bf6313..520d174 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryVehicleEnrollmentRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/InMemory/Repositories/InMemoryVehicleRepository.cs b/src/Persistence/InMemory/Repositories/InMemoryVehicleRepository.cs index a0bd558..ae36b4b 100644 --- a/src/Persistence/InMemory/Repositories/InMemoryVehicleRepository.cs +++ b/src/Persistence/InMemory/Repositories/InMemoryVehicleRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories; diff --git a/src/Persistence/PostgreSql/Configurations/AccountConfiguration.cs b/src/Persistence/PostgreSql/Configurations/AccountConfiguration.cs new file mode 100644 index 0000000..dc16077 --- /dev/null +++ b/src/Persistence/PostgreSql/Configurations/AccountConfiguration.cs @@ -0,0 +1,48 @@ +using cuqmbr.TravelGuide.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations; + +public class AccountConfiguration : BaseConfiguration +{ + public override void Configure(EntityTypeBuilder builder) + { + builder + .ToTable("accounts"); + + base.Configure(builder); + + + builder + .Property(a => a.Username) + .HasColumnName("username") + .HasColumnType("varchar(32)") + .IsRequired(true); + + builder + .Property(a => a.Email) + .HasColumnName("email") + .HasColumnType("varchar(256)") + .IsRequired(true); + + // Base64 encoded PBKDF2 SHA512. + // Base64 represents 3 input bytes 4 output bytes, it adds padding + // if the input bytes count isn't divisible by 3. + // 512 / 8 / 3 = 21.(3) => 22 input characters (with padding) => + // 88 output characters. + builder + .Property(a => a.PasswordHash) + .HasColumnName("password_hash") + .HasColumnType("varchar(88)") + .IsRequired(true); + + // Base64 encoded 128 bits + // 128 / 8 / 3 = 5.(3) => 6 in chars \w padding => 24 out chars + builder + .Property(a => a.PasswordSalt) + .HasColumnName("password_salt") + .HasColumnType("varchar(24)") + .IsRequired(true); + } +} diff --git a/src/Persistence/PostgreSql/Configurations/AccountRoleConfiguration.cs b/src/Persistence/PostgreSql/Configurations/AccountRoleConfiguration.cs new file mode 100644 index 0000000..50ae6aa --- /dev/null +++ b/src/Persistence/PostgreSql/Configurations/AccountRoleConfiguration.cs @@ -0,0 +1,64 @@ +using cuqmbr.TravelGuide.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations; + +public class AccountRoleConfiguration : BaseConfiguration +{ + public override void Configure(EntityTypeBuilder builder) + { + builder + .ToTable("account_roles"); + + base.Configure(builder); + + + builder + .Property(ar => ar.AccountId) + .HasColumnName("account_id") + .HasColumnType("bigint") + .IsRequired(true); + + builder + .HasOne(ar => ar.Account) + .WithMany(a => a.AccountRoles) + .HasForeignKey(ar => ar.AccountId) + .HasConstraintName( + "fk_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(ar => ar.AccountId).Metadata.GetColumnName()}") + .OnDelete(DeleteBehavior.Cascade); + + builder + .HasIndex(ar => ar.AccountId) + .HasDatabaseName( + "ix_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(ar => ar.AccountId).Metadata.GetColumnName()}"); + + + builder + .Property(ar => ar.RoleId) + .HasColumnName("role_id") + .HasColumnType("bigint") + .IsRequired(true); + + builder + .HasOne(ar => ar.Role) + .WithMany(r => r.AccountRoles) + .HasForeignKey(ar => ar.RoleId) + .HasConstraintName( + "fk_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(ar => ar.RoleId).Metadata.GetColumnName()}") + .OnDelete(DeleteBehavior.Cascade); + + builder + .HasIndex(ar => ar.RoleId) + .HasDatabaseName( + "ix_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(ar => ar.RoleId).Metadata.GetColumnName()}"); + } +} diff --git a/src/Persistence/PostgreSql/Configurations/BaseConfiguration.cs b/src/Persistence/PostgreSql/Configurations/BaseConfiguration.cs index c7a8bac..f9b0128 100644 --- a/src/Persistence/PostgreSql/Configurations/BaseConfiguration.cs +++ b/src/Persistence/PostgreSql/Configurations/BaseConfiguration.cs @@ -9,8 +9,6 @@ public class BaseConfiguration : IEntityTypeConfiguration { public virtual void Configure(EntityTypeBuilder builder) { - // Set table name for inherited types using type name - // instead of mapped table name var tableName = builder.Metadata.GetTableName(); builder diff --git a/src/Persistence/PostgreSql/Configurations/RefreshTokenConfiguration.cs b/src/Persistence/PostgreSql/Configurations/RefreshTokenConfiguration.cs new file mode 100644 index 0000000..5265083 --- /dev/null +++ b/src/Persistence/PostgreSql/Configurations/RefreshTokenConfiguration.cs @@ -0,0 +1,67 @@ +using cuqmbr.TravelGuide.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations; + +public class RefreshTokenConfiguration : BaseConfiguration +{ + public override void Configure(EntityTypeBuilder builder) + { + builder + .ToTable("refresh_tokens"); + + base.Configure(builder); + + + // Base64 encoded 128 bits + // 128 / 8 / 3 = 5.(3) => 6 in chars \w padding => 24 out chars + builder + .Property(rt => rt.Value) + .HasColumnName("value") + .HasColumnType("varchar(24)") + .IsRequired(true); + + builder + .Property(rt => rt.CreationTime) + .HasColumnName("creation_time") + .HasColumnType("timestamptz") + .IsRequired(true); + + builder + .Property(rt => rt.ExpirationTime) + .HasColumnName("expiration_time") + .HasColumnType("timestamptz") + .IsRequired(true); + + builder + .Property(rt => rt.RevocationTime) + .HasColumnName("revocation_time") + .HasColumnType("timestamptz") + .IsRequired(false); + + + builder + .Property(rt => rt.AccountId) + .HasColumnName("account_id") + .HasColumnType("bigint") + .IsRequired(true); + + builder + .HasOne(rt => rt.Account) + .WithMany(rt => rt.RefreshTokens) + .HasForeignKey(rt => rt.AccountId) + .HasConstraintName( + "fk_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(rt => rt.AccountId).Metadata.GetColumnName()}") + .OnDelete(DeleteBehavior.Cascade); + + builder + .HasIndex(rt => rt.AccountId) + .HasDatabaseName( + "ix_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(rt => rt.AccountId).Metadata.GetColumnName()}"); + } +} diff --git a/src/Persistence/PostgreSql/Configurations/RoleConfiguration.cs b/src/Persistence/PostgreSql/Configurations/RoleConfiguration.cs new file mode 100644 index 0000000..90a3e21 --- /dev/null +++ b/src/Persistence/PostgreSql/Configurations/RoleConfiguration.cs @@ -0,0 +1,32 @@ +using cuqmbr.TravelGuide.Domain.Entities; +using cuqmbr.TravelGuide.Domain.Enums; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations; + +public class RoleConfiguration : BaseConfiguration +{ + public override void Configure(EntityTypeBuilder builder) + { + builder + .Property(r => r.Value) + .HasColumnName("name") + .IsRequired(true); + + builder + .ToTable( + "roles", + r => r.HasCheckConstraint( + "ck_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(r => r.Value) + .Metadata.GetColumnName()}", + $"{builder.Property(r => r.Value) + .Metadata.GetColumnName()} IN ('{String + .Join("', '", IdentityRole.Enumerations + .Values.Select(v => v.Name))}')")); + + base.Configure(builder); + } +} diff --git a/src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.Designer.cs b/src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.Designer.cs new file mode 100644 index 0000000..44068d3 --- /dev/null +++ b/src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.Designer.cs @@ -0,0 +1,1294 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using cuqmbr.TravelGuide.Persistence.PostgreSql; + +#nullable disable + +namespace Persistence.PostgreSql.Migrations +{ + [DbContext(typeof(PostgreSqlDbContext))] + [Migration("20250528083243_Add_Account_Role_and_AccountRole")] + partial class Add_Account_Role_and_AccountRole + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("application") + .HasAnnotation("ProductVersion", "9.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.HasSequence("account_roles_id_sequence"); + + modelBuilder.HasSequence("accounts_id_sequence"); + + modelBuilder.HasSequence("addresses_id_sequence"); + + modelBuilder.HasSequence("cities_id_sequence"); + + modelBuilder.HasSequence("companies_id_sequence"); + + modelBuilder.HasSequence("countries_id_sequence"); + + modelBuilder.HasSequence("employee_documents_id_sequence"); + + modelBuilder.HasSequence("employees_id_sequence"); + + modelBuilder.HasSequence("refresh_tokens_id_sequence"); + + modelBuilder.HasSequence("regions_id_sequence"); + + modelBuilder.HasSequence("roles_id_sequence"); + + modelBuilder.HasSequence("route_address_details_id_sequence"); + + modelBuilder.HasSequence("route_addresses_id_sequence"); + + modelBuilder.HasSequence("routes_id_sequence"); + + modelBuilder.HasSequence("ticket_groups_id_sequence"); + + modelBuilder.HasSequence("tickets_id_sequence"); + + modelBuilder.HasSequence("vehicle_enrollment_employees_id_sequence"); + + modelBuilder.HasSequence("vehicle_enrollments_id_sequence"); + + modelBuilder.HasSequence("vehicles_id_sequence"); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.accounts_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "accounts_id_sequence"); + + b.Property("Email") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("email"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("varchar(88)") + .HasColumnName("password_hash"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("varchar(24)") + .HasColumnName("password_salt"); + + b.Property("Username") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("username"); + + b.HasKey("Id") + .HasName("pk_accounts"); + + b.HasAlternateKey("Guid") + .HasName("altk_accounts_uuid"); + + b.ToTable("accounts", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.AccountRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.account_roles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "account_roles_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_account_roles"); + + b.HasAlternateKey("Guid") + .HasName("altk_account_roles_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_account_roles_account_id"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_account_roles_role_id"); + + b.ToTable("account_roles", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.addresses_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "addresses_id_sequence"); + + b.Property("CityId") + .HasColumnType("bigint") + .HasColumnName("city_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Latitude") + .HasColumnType("double precision"); + + b.Property("Longitude") + .HasColumnType("double precision"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(128)") + .HasColumnName("name"); + + b.Property("VehicleType") + .IsRequired() + .HasColumnType("varchar(16)") + .HasColumnName("vehicle_type"); + + b.HasKey("Id") + .HasName("pk_addresses"); + + b.HasAlternateKey("Guid") + .HasName("altk_addresses_uuid"); + + b.HasIndex("CityId") + .HasDatabaseName("ix_addresses_city_id"); + + b.ToTable("addresses", "application", t => + { + t.HasCheckConstraint("ck_addresses_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.cities_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "cities_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.Property("RegionId") + .HasColumnType("bigint") + .HasColumnName("region_id"); + + b.HasKey("Id") + .HasName("pk_cities"); + + b.HasAlternateKey("Guid") + .HasName("altk_cities_uuid"); + + b.HasIndex("RegionId") + .HasDatabaseName("ix_cities_region_id"); + + b.ToTable("cities", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.companies_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "companies_id_sequence"); + + b.Property("ContactEmail") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("contact_email"); + + b.Property("ContactPhoneNumber") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("contact_phone_number"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("LegalAddress") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("legal_address"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_companies"); + + b.HasAlternateKey("Guid") + .HasName("altk_companies_uuid"); + + b.ToTable("companies", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.countries_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "countries_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_countries"); + + b.HasAlternateKey("Guid") + .HasName("altk_countries_uuid"); + + b.ToTable("countries", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.employees_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "employees_id_sequence"); + + b.Property("BirthDate") + .HasColumnType("date") + .HasColumnName("birth_date"); + + b.Property("CompanyId") + .HasColumnType("bigint") + .HasColumnName("company_id"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("first_name"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("last_name"); + + b.Property("Patronymic") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("patronymic"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("sex"); + + b.HasKey("Id") + .HasName("pk_employees"); + + b.HasAlternateKey("Guid") + .HasName("altk_employees_uuid"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_employees_company_id"); + + b.ToTable("employees", "application", t => + { + t.HasCheckConstraint("ck_employees_sex", "sex IN ('male', 'female')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.EmployeeDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.employee_documents_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "employee_documents_id_sequence"); + + b.Property("DocumentType") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("document_type"); + + b.Property("EmployeeId") + .HasColumnType("bigint") + .HasColumnName("employee_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Information") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("information"); + + b.HasKey("Id") + .HasName("pk_employee_documents"); + + b.HasAlternateKey("Guid") + .HasName("altk_employee_documents_uuid"); + + b.HasIndex("EmployeeId") + .HasDatabaseName("ix_employee_documents_employee_id"); + + b.ToTable("employee_documents", "application", t => + { + t.HasCheckConstraint("ck_employee_documents_document_type", "document_type IN ('passport')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.refresh_tokens_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "refresh_tokens_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("CreationTime") + .HasColumnType("timestamptz") + .HasColumnName("creation_time"); + + b.Property("ExpirationTime") + .HasColumnType("timestamptz") + .HasColumnName("expiration_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RevocationTime") + .HasColumnType("timestamptz") + .HasColumnName("revocation_time"); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(24)") + .HasColumnName("value"); + + b.HasKey("Id") + .HasName("pk_refresh_tokens"); + + b.HasAlternateKey("Guid") + .HasName("altk_refresh_tokens_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_refresh_tokens_account_id"); + + b.ToTable("refresh_tokens", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.regions_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "regions_id_sequence"); + + b.Property("CountryId") + .HasColumnType("bigint") + .HasColumnName("country_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_regions"); + + b.HasAlternateKey("Guid") + .HasName("altk_regions_uuid"); + + b.HasIndex("CountryId") + .HasDatabaseName("ix_regions_country_id"); + + b.ToTable("regions", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.roles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "roles_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_roles"); + + b.HasAlternateKey("Guid") + .HasName("altk_roles_uuid"); + + b.ToTable("roles", "application", t => + { + t.HasCheckConstraint("ck_roles_name", "name IN ('administrator', 'user', 'company_owner', 'company_employee')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.routes_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "routes_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.Property("VehicleType") + .IsRequired() + .HasColumnType("varchar(16)") + .HasColumnName("vehicle_type"); + + b.HasKey("Id") + .HasName("pk_routes"); + + b.HasAlternateKey("Guid") + .HasName("altk_routes_uuid"); + + b.ToTable("routes", "application", t => + { + t.HasCheckConstraint("ck_routes_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.route_addresses_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "route_addresses_id_sequence"); + + b.Property("AddressId") + .HasColumnType("bigint") + .HasColumnName("address_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("RouteId") + .HasColumnType("bigint") + .HasColumnName("route_id"); + + b.HasKey("Id") + .HasName("pk_route_addresses"); + + b.HasAlternateKey("Guid") + .HasName("altk_route_addresses_uuid"); + + b.HasAlternateKey("AddressId", "RouteId", "Order") + .HasName("altk_route_addresses_address_id_route_id_order"); + + b.HasIndex("AddressId") + .HasDatabaseName("ix_route_addresses_address_id"); + + b.HasIndex("RouteId") + .HasDatabaseName("ix_route_addresses_route_id"); + + b.ToTable("route_addresses", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddressDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.route_address_details_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "route_address_details_id_sequence"); + + b.Property("CostToNextAddress") + .HasColumnType("numeric(24,12)") + .HasColumnName("cost_to_next_address"); + + b.Property("CurrentAddressStopTime") + .HasColumnType("interval") + .HasColumnName("current_address_stop_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RouteAddressId") + .HasColumnType("bigint") + .HasColumnName("route_address_id"); + + b.Property("TimeToNextAddress") + .HasColumnType("interval") + .HasColumnName("time_to_next_address"); + + b.Property("VehicleEnrollmentId") + .HasColumnType("bigint") + .HasColumnName("vehicle_enrollment_id"); + + b.HasKey("Id") + .HasName("pk_route_address_details"); + + b.HasAlternateKey("Guid") + .HasName("altk_route_address_details_uuid"); + + b.HasIndex("RouteAddressId") + .HasDatabaseName("ix_route_address_details_route_address_id"); + + b.HasIndex("VehicleEnrollmentId") + .HasDatabaseName("ix_route_address_details_vehicle_enrollment_id"); + + b.ToTable("route_address_details", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.tickets_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "tickets_id_sequence"); + + b.Property("ArrivalRouteAddressId") + .HasColumnType("bigint") + .HasColumnName("arrival_route_address_id"); + + b.Property("Cost") + .HasColumnType("numeric(24,12)") + .HasColumnName("cost"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("varchar(8)") + .HasColumnName("currency"); + + b.Property("DepartureRouteAddressId") + .HasColumnType("bigint") + .HasColumnName("departure_route_address_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("TicketGroupId") + .HasColumnType("bigint") + .HasColumnName("ticket_group_id"); + + b.Property("VehicleEnrollmentId") + .HasColumnType("bigint") + .HasColumnName("vehicle_enrollment_id"); + + b.HasKey("Id") + .HasName("pk_tickets"); + + b.HasAlternateKey("Guid") + .HasName("altk_tickets_uuid"); + + b.HasIndex("ArrivalRouteAddressId"); + + b.HasIndex("DepartureRouteAddressId"); + + b.HasIndex("TicketGroupId") + .HasDatabaseName("ix_tickets_ticket_group_id"); + + b.HasIndex("VehicleEnrollmentId") + .HasDatabaseName("ix_tickets_vehicle_enrollment_id"); + + b.ToTable("tickets", "application", t => + { + t.HasCheckConstraint("ck_tickets_currency", "currency IN ('DEFAULT', 'USD', 'EUR', 'UAH')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.ticket_groups_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "ticket_groups_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("PassangerBirthDate") + .HasColumnType("date") + .HasColumnName("passanger_birth_date"); + + b.Property("PassangerFirstName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_first_name"); + + b.Property("PassangerLastName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_last_name"); + + b.Property("PassangerPatronymic") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_patronymic"); + + b.Property("PassangerSex") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_sex"); + + b.Property("PurchaseTime") + .HasColumnType("timestamptz") + .HasColumnName("purchase_time"); + + b.Property("Status") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("status"); + + b.Property("TravelTime") + .HasColumnType("interval") + .HasColumnName("travel_time"); + + b.HasKey("Id") + .HasName("pk_ticket_groups"); + + b.HasAlternateKey("Guid") + .HasName("altk_ticket_groups_uuid"); + + b.ToTable("ticket_groups", "application", t => + { + t.HasCheckConstraint("ck_ticket_groups_passanger_sex", "passanger_sex IN ('male', 'female')"); + + t.HasCheckConstraint("ck_ticket_groups_status", "status IN ('reserved', 'returned', 'purchased')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.vehicles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "vehicles_id_sequence"); + + b.Property("CompanyId") + .HasColumnType("bigint") + .HasColumnName("company_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("VehicleType") + .IsRequired() + .HasColumnType("varchar(16)") + .HasColumnName("vehicle_type"); + + b.HasKey("Id") + .HasName("pk_vehicles"); + + b.HasAlternateKey("Guid") + .HasName("altk_vehicles_uuid"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_vehicles_company_id"); + + b.ToTable("vehicles", "application", t => + { + t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')"); + }); + + b.HasDiscriminator("VehicleType"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.vehicle_enrollments_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "vehicle_enrollments_id_sequence"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("varchar(8)") + .HasColumnName("currency"); + + b.Property("DepartureTime") + .HasColumnType("timestamptz") + .HasColumnName("departure_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RouteId") + .HasColumnType("bigint") + .HasColumnName("route_id"); + + b.Property("VehicleId") + .HasColumnType("bigint") + .HasColumnName("vehicle_id"); + + b.HasKey("Id") + .HasName("pk_vehicle_enrollments"); + + b.HasAlternateKey("Guid") + .HasName("altk_vehicle_enrollments_uuid"); + + b.HasIndex("RouteId") + .HasDatabaseName("ix_vehicle_enrollments_route_id"); + + b.HasIndex("VehicleId") + .HasDatabaseName("ix_vehicle_enrollments_vehicle_id"); + + b.ToTable("vehicle_enrollments", "application", t => + { + t.HasCheckConstraint("ck_vehicle_enrollments_currency", "currency IN ('DEFAULT', 'USD', 'EUR', 'UAH')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollmentEmployee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.vehicle_enrollment_employees_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "vehicle_enrollment_employees_id_sequence"); + + b.Property("EmployeeId") + .HasColumnType("bigint") + .HasColumnName("employee_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("VehicleEnrollmentId") + .HasColumnType("bigint") + .HasColumnName("vehicle_enrollment_id"); + + b.HasKey("Id") + .HasName("pk_vehicle_enrollment_employees"); + + b.HasAlternateKey("Guid") + .HasName("altk_vehicle_enrollment_employees_uuid"); + + b.HasIndex("EmployeeId") + .HasDatabaseName("ix_vehicle_enrollment_employees_employee_id"); + + b.HasIndex("VehicleEnrollmentId") + .HasDatabaseName("ix_vehicle_enrollment_employees_vehicle_enrollment_id"); + + b.ToTable("vehicle_enrollment_employees", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Aircraft", b => + { + b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle"); + + b.Property("Capacity") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("smallint") + .HasColumnName("capacity"); + + b.Property("Model") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(64)") + .HasColumnName("model"); + + b.Property("Number") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(32)") + .HasColumnName("number"); + + b.ToTable(t => + { + t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')"); + }); + + b.HasDiscriminator().HasValue("aircraft"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Bus", b => + { + b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle"); + + b.Property("Capacity") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("smallint") + .HasColumnName("capacity"); + + b.Property("Model") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(64)") + .HasColumnName("model"); + + b.Property("Number") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(32)") + .HasColumnName("number"); + + b.ToTable(t => + { + t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')"); + }); + + b.HasDiscriminator().HasValue("bus"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Train", b => + { + b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle"); + + b.Property("Capacity") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("smallint") + .HasColumnName("capacity"); + + b.Property("Model") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(64)") + .HasColumnName("model"); + + b.Property("Number") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(32)") + .HasColumnName("number"); + + b.ToTable(t => + { + t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')"); + }); + + b.HasDiscriminator().HasValue("train"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.AccountRole", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("AccountRoles") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_roles_account_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Role", "Role") + .WithMany("AccountRoles") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_roles_role_id"); + + b.Navigation("Account"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.City", "City") + .WithMany("Addresses") + .HasForeignKey("CityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_addresses_city_id"); + + b.Navigation("City"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Region", "Region") + .WithMany("Cities") + .HasForeignKey("RegionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_cities_region_id"); + + b.Navigation("Region"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Employee", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company") + .WithMany("Employees") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_employees_company_id"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.EmployeeDocument", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Employee", "Employee") + .WithMany("Documents") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_employee_documents_employee_id"); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RefreshToken", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("RefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_refresh_tokens_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Country", "Country") + .WithMany("Regions") + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_regions_country_id"); + + b.Navigation("Country"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Address", "Address") + .WithMany("AddressRoutes") + .HasForeignKey("AddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_route_addresses_address_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route") + .WithMany("RouteAddresses") + .HasForeignKey("RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_route_addresses_route_id"); + + b.Navigation("Address"); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddressDetail", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", "RouteAddress") + .WithMany("Details") + .HasForeignKey("RouteAddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_route_address_details_route_address_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", "VehicleEnrollment") + .WithMany("RouteAddressDetails") + .HasForeignKey("VehicleEnrollmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_route_address_details_vehicle_enrollment_id"); + + b.Navigation("RouteAddress"); + + b.Navigation("VehicleEnrollment"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Ticket", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", "ArrivalRouteAddress") + .WithMany() + .HasForeignKey("ArrivalRouteAddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", "DepartureRouteAddress") + .WithMany() + .HasForeignKey("DepartureRouteAddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", "TicketGroup") + .WithMany("Tickets") + .HasForeignKey("TicketGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_tickets_ticket_group_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", "VehicleEnrollment") + .WithMany("Tickets") + .HasForeignKey("VehicleEnrollmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_tickets_vehicle_enrollment_id"); + + b.Navigation("ArrivalRouteAddress"); + + b.Navigation("DepartureRouteAddress"); + + b.Navigation("TicketGroup"); + + b.Navigation("VehicleEnrollment"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company") + .WithMany("Vehicles") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicles_company_id"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route") + .WithMany("VehicleEnrollments") + .HasForeignKey("RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicle_enrollments_route_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Vehicle", "Vehicle") + .WithMany("Enrollments") + .HasForeignKey("VehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicle_enrollments_vehicle_id"); + + b.Navigation("Route"); + + b.Navigation("Vehicle"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollmentEmployee", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Employee", "Employee") + .WithMany("VehicleEnrollmentEmployees") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicle_enrollment_employees_employee_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", "VehicleEnrollment") + .WithMany("VehicleEnrollmentEmployees") + .HasForeignKey("VehicleEnrollmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicle_enrollment_employees_vehicle_enrollment_id"); + + b.Navigation("Employee"); + + b.Navigation("VehicleEnrollment"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Account", b => + { + b.Navigation("AccountRoles"); + + b.Navigation("RefreshTokens"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => + { + b.Navigation("AddressRoutes"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b => + { + b.Navigation("Addresses"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Company", b => + { + b.Navigation("Employees"); + + b.Navigation("Vehicles"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b => + { + b.Navigation("Regions"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Employee", b => + { + b.Navigation("Documents"); + + b.Navigation("VehicleEnrollmentEmployees"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => + { + b.Navigation("Cities"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Role", b => + { + b.Navigation("AccountRoles"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b => + { + b.Navigation("RouteAddresses"); + + b.Navigation("VehicleEnrollments"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b => + { + b.Navigation("Details"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", b => + { + b.Navigation("Tickets"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b => + { + b.Navigation("Enrollments"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b => + { + b.Navigation("RouteAddressDetails"); + + b.Navigation("Tickets"); + + b.Navigation("VehicleEnrollmentEmployees"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.cs b/src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.cs new file mode 100644 index 0000000..0cdd345 --- /dev/null +++ b/src/Persistence/PostgreSql/Migrations/20250528083243_Add_Account_Role_and_AccountRole.cs @@ -0,0 +1,175 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Persistence.PostgreSql.Migrations +{ + /// + public partial class Add_Account_Role_and_AccountRole : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateSequence( + name: "account_roles_id_sequence", + schema: "application"); + + migrationBuilder.CreateSequence( + name: "accounts_id_sequence", + schema: "application"); + + migrationBuilder.CreateSequence( + name: "refresh_tokens_id_sequence", + schema: "application"); + + migrationBuilder.CreateSequence( + name: "roles_id_sequence", + schema: "application"); + + migrationBuilder.CreateTable( + name: "accounts", + schema: "application", + columns: table => new + { + id = table.Column(type: "bigint", nullable: false, defaultValueSql: "nextval('application.accounts_id_sequence')"), + username = table.Column(type: "varchar(32)", nullable: false), + email = table.Column(type: "varchar(256)", nullable: false), + password_hash = table.Column(type: "varchar(88)", nullable: false), + password_salt = table.Column(type: "varchar(24)", nullable: false), + uuid = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_accounts", x => x.id); + table.UniqueConstraint("altk_accounts_uuid", x => x.uuid); + }); + + migrationBuilder.CreateTable( + name: "roles", + schema: "application", + columns: table => new + { + id = table.Column(type: "bigint", nullable: false, defaultValueSql: "nextval('application.roles_id_sequence')"), + name = table.Column(type: "varchar(64)", nullable: false), + uuid = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_roles", x => x.id); + table.UniqueConstraint("altk_roles_uuid", x => x.uuid); + table.CheckConstraint("ck_roles_name", "name IN ('administrator', 'user', 'company_owner', 'company_employee')"); + }); + + migrationBuilder.CreateTable( + name: "refresh_tokens", + schema: "application", + columns: table => new + { + id = table.Column(type: "bigint", nullable: false, defaultValueSql: "nextval('application.refresh_tokens_id_sequence')"), + value = table.Column(type: "varchar(24)", nullable: false), + creation_time = table.Column(type: "timestamptz", nullable: false), + expiration_time = table.Column(type: "timestamptz", nullable: false), + revocation_time = table.Column(type: "timestamptz", nullable: true), + account_id = table.Column(type: "bigint", nullable: false), + uuid = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_refresh_tokens", x => x.id); + table.UniqueConstraint("altk_refresh_tokens_uuid", x => x.uuid); + table.ForeignKey( + name: "fk_refresh_tokens_account_id", + column: x => x.account_id, + principalSchema: "application", + principalTable: "accounts", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "account_roles", + schema: "application", + columns: table => new + { + id = table.Column(type: "bigint", nullable: false, defaultValueSql: "nextval('application.account_roles_id_sequence')"), + account_id = table.Column(type: "bigint", nullable: false), + role_id = table.Column(type: "bigint", nullable: false), + uuid = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_account_roles", x => x.id); + table.UniqueConstraint("altk_account_roles_uuid", x => x.uuid); + table.ForeignKey( + name: "fk_account_roles_account_id", + column: x => x.account_id, + principalSchema: "application", + principalTable: "accounts", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_account_roles_role_id", + column: x => x.role_id, + principalSchema: "application", + principalTable: "roles", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "ix_account_roles_account_id", + schema: "application", + table: "account_roles", + column: "account_id"); + + migrationBuilder.CreateIndex( + name: "ix_account_roles_role_id", + schema: "application", + table: "account_roles", + column: "role_id"); + + migrationBuilder.CreateIndex( + name: "ix_refresh_tokens_account_id", + schema: "application", + table: "refresh_tokens", + column: "account_id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "account_roles", + schema: "application"); + + migrationBuilder.DropTable( + name: "refresh_tokens", + schema: "application"); + + migrationBuilder.DropTable( + name: "roles", + schema: "application"); + + migrationBuilder.DropTable( + name: "accounts", + schema: "application"); + + migrationBuilder.DropSequence( + name: "account_roles_id_sequence", + schema: "application"); + + migrationBuilder.DropSequence( + name: "accounts_id_sequence", + schema: "application"); + + migrationBuilder.DropSequence( + name: "refresh_tokens_id_sequence", + schema: "application"); + + migrationBuilder.DropSequence( + name: "roles_id_sequence", + schema: "application"); + } + } +} diff --git a/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs b/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs index 1f16747..ba23151 100644 --- a/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs +++ b/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs @@ -23,6 +23,10 @@ namespace Persistence.PostgreSql.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.HasSequence("account_roles_id_sequence"); + + modelBuilder.HasSequence("accounts_id_sequence"); + modelBuilder.HasSequence("addresses_id_sequence"); modelBuilder.HasSequence("cities_id_sequence"); @@ -35,8 +39,12 @@ namespace Persistence.PostgreSql.Migrations modelBuilder.HasSequence("employees_id_sequence"); + modelBuilder.HasSequence("refresh_tokens_id_sequence"); + modelBuilder.HasSequence("regions_id_sequence"); + modelBuilder.HasSequence("roles_id_sequence"); + modelBuilder.HasSequence("route_address_details_id_sequence"); modelBuilder.HasSequence("route_addresses_id_sequence"); @@ -53,6 +61,86 @@ namespace Persistence.PostgreSql.Migrations modelBuilder.HasSequence("vehicles_id_sequence"); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.accounts_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "accounts_id_sequence"); + + b.Property("Email") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("email"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("varchar(88)") + .HasColumnName("password_hash"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("varchar(24)") + .HasColumnName("password_salt"); + + b.Property("Username") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("username"); + + b.HasKey("Id") + .HasName("pk_accounts"); + + b.HasAlternateKey("Guid") + .HasName("altk_accounts_uuid"); + + b.ToTable("accounts", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.AccountRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.account_roles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "account_roles_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_account_roles"); + + b.HasAlternateKey("Guid") + .HasName("altk_account_roles_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_account_roles_account_id"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_account_roles_role_id"); + + b.ToTable("account_roles", "application"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => { b.Property("Id") @@ -308,6 +396,53 @@ namespace Persistence.PostgreSql.Migrations }); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.refresh_tokens_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "refresh_tokens_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("CreationTime") + .HasColumnType("timestamptz") + .HasColumnName("creation_time"); + + b.Property("ExpirationTime") + .HasColumnType("timestamptz") + .HasColumnName("expiration_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RevocationTime") + .HasColumnType("timestamptz") + .HasColumnName("revocation_time"); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(24)") + .HasColumnName("value"); + + b.HasKey("Id") + .HasName("pk_refresh_tokens"); + + b.HasAlternateKey("Guid") + .HasName("altk_refresh_tokens_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_refresh_tokens_account_id"); + + b.ToTable("refresh_tokens", "application"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => { b.Property("Id") @@ -343,6 +478,37 @@ namespace Persistence.PostgreSql.Migrations b.ToTable("regions", "application"); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.roles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "roles_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_roles"); + + b.HasAlternateKey("Guid") + .HasName("altk_roles_uuid"); + + b.ToTable("roles", "application", t => + { + t.HasCheckConstraint("ck_roles_name", "name IN ('administrator', 'user', 'company_owner', 'company_employee')"); + }); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b => { b.Property("Id") @@ -817,6 +983,27 @@ namespace Persistence.PostgreSql.Migrations b.HasDiscriminator().HasValue("train"); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.AccountRole", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("AccountRoles") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_roles_account_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Role", "Role") + .WithMany("AccountRoles") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_roles_role_id"); + + b.Navigation("Account"); + + b.Navigation("Role"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => { b.HasOne("cuqmbr.TravelGuide.Domain.Entities.City", "City") @@ -865,6 +1052,18 @@ namespace Persistence.PostgreSql.Migrations b.Navigation("Employee"); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RefreshToken", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("RefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_refresh_tokens_account_id"); + + b.Navigation("Account"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => { b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Country", "Country") @@ -1010,6 +1209,13 @@ namespace Persistence.PostgreSql.Migrations b.Navigation("VehicleEnrollment"); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Account", b => + { + b.Navigation("AccountRoles"); + + b.Navigation("RefreshTokens"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => { b.Navigation("AddressRoutes"); @@ -1044,6 +1250,11 @@ namespace Persistence.PostgreSql.Migrations b.Navigation("Cities"); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Role", b => + { + b.Navigation("AccountRoles"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b => { b.Navigation("RouteAddresses"); diff --git a/src/Persistence/PostgreSql/PostgreSqlDbContext.cs b/src/Persistence/PostgreSql/PostgreSqlDbContext.cs index 0f5571c..4825aac 100644 --- a/src/Persistence/PostgreSql/PostgreSqlDbContext.cs +++ b/src/Persistence/PostgreSql/PostgreSqlDbContext.cs @@ -62,5 +62,11 @@ public class PostgreSqlDbContext : DbContext builder .Properties() .HaveConversion(); + + + builder + .Properties() + .HaveColumnType("varchar(64)") + .HaveConversion(); } } diff --git a/src/Persistence/PostgreSql/PostgreSqlUnitOfWork.cs b/src/Persistence/PostgreSql/PostgreSqlUnitOfWork.cs index 717d684..5b42993 100644 --- a/src/Persistence/PostgreSql/PostgreSqlUnitOfWork.cs +++ b/src/Persistence/PostgreSql/PostgreSqlUnitOfWork.cs @@ -1,5 +1,5 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; namespace cuqmbr.TravelGuide.Persistence.PostgreSql; @@ -34,6 +34,11 @@ public sealed class PostgreSqlUnitOfWork : UnitOfWork new PostgreSqlRouteAddressDetailRepository(_dbContext); VehicleEnrollmentEmployeeRepository = new PostgreSqlVehicleEnrollmentEmployeeRepository(_dbContext); + + AccountRepository = new PostgreSqlAccountRepository(_dbContext); + RoleRepository = new PostgreSqlRoleRepository(_dbContext); + AccountRoleRepository = new PostgreSqlAccountRoleRepository(_dbContext); + RefreshTokenRepository = new PostgreSqlRefreshTokenRepository(_dbContext); } public CountryRepository CountryRepository { get; init; } @@ -70,6 +75,15 @@ public sealed class PostgreSqlUnitOfWork : UnitOfWork public VehicleEnrollmentEmployeeRepository VehicleEnrollmentEmployeeRepository { get; init; } + + public AccountRepository AccountRepository { get; init; } + + public RoleRepository RoleRepository { get; init; } + + public AccountRoleRepository AccountRoleRepository { get; init; } + + public RefreshTokenRepository RefreshTokenRepository { get; init; } + public int Save() { return _dbContext.SaveChanges(); diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRepository.cs new file mode 100644 index 0000000..e622829 --- /dev/null +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; + +public sealed class PostgreSqlAccountRepository : + PostgreSqlBaseRepository, AccountRepository +{ + public PostgreSqlAccountRepository(PostgreSqlDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRoleRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRoleRepository.cs new file mode 100644 index 0000000..6a683dc --- /dev/null +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlAccountRoleRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; + +public sealed class PostgreSqlAccountRoleRepository : + PostgreSqlBaseRepository, AccountRoleRepository +{ + public PostgreSqlAccountRoleRepository(PostgreSqlDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlAddressRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlAddressRepository.cs index 58915b0..f50216b 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlAddressRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlAddressRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlAircraftRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlAircraftRepository.cs index 292fcea..d6cb3d8 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlAircraftRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlAircraftRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlBaseRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlBaseRepository.cs index cc3930a..468fb49 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlBaseRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlBaseRepository.cs @@ -1,5 +1,5 @@ using System.Linq.Expressions; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Application.Common.Models; using cuqmbr.TravelGuide.Domain.Entities; using Microsoft.EntityFrameworkCore; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlBusRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlBusRepository.cs index da4c844..7f9c09c 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlBusRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlBusRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlCityRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlCityRepository.cs index 441d6b9..0fdb212 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlCityRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlCityRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlCompanyRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlCompanyRepository.cs index ed857cd..c0862bc 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlCompanyRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlCompanyRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlCountryRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlCountryRepository.cs index 78d315b..b45a481 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlCountryRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlCountryRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlEmployeeRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlEmployeeRepository.cs index 03319c3..36d1176 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlEmployeeRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlEmployeeRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlRefreshTokenRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlRefreshTokenRepository.cs new file mode 100644 index 0000000..6b436ed --- /dev/null +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlRefreshTokenRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; + +public sealed class PostgreSqlRefreshTokenRepository : + PostgreSqlBaseRepository, RefreshTokenRepository +{ + public PostgreSqlRefreshTokenRepository(PostgreSqlDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlRegionRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlRegionRepository.cs index 036018e..8be382d 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlRegionRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlRegionRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlRoleRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlRoleRepository.cs new file mode 100644 index 0000000..e549ba2 --- /dev/null +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlRoleRepository.cs @@ -0,0 +1,11 @@ +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; + +public sealed class PostgreSqlRoleRepository : + PostgreSqlBaseRepository, RoleRepository +{ + public PostgreSqlRoleRepository(PostgreSqlDbContext dbContext) + : base(dbContext) { } +} diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressDetailRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressDetailRepository.cs index d88305f..11b9c48 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressDetailRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressDetailRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressRepository.cs index fcd828b..9f8d7e7 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteAddressRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteRepository.cs index 1af92ff..c30b052 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlRouteRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketGroupRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketGroupRepository.cs index 204d808..42af631 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketGroupRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketGroupRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketRepository.cs index b2f53f6..96a9bf6 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlTicketRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlTrainRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlTrainRepository.cs index 2dffccc..0bab7ce 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlTrainRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlTrainRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentEmployeeRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentEmployeeRepository.cs index ed6ca66..1a11fba 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentEmployeeRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentEmployeeRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentRepository.cs index 434b69c..6ae4d01 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleEnrollmentRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleRepository.cs b/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleRepository.cs index da7cf91..536af9c 100644 --- a/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleRepository.cs +++ b/src/Persistence/PostgreSql/Repositories/PostgreSqlVehicleRepository.cs @@ -1,4 +1,4 @@ -using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories; +using cuqmbr.TravelGuide.Application.Common.Persistence.Repositories; using cuqmbr.TravelGuide.Domain.Entities; namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories; diff --git a/src/Persistence/TypeConverters/RoleConverter.cs b/src/Persistence/TypeConverters/RoleConverter.cs new file mode 100644 index 0000000..d809f43 --- /dev/null +++ b/src/Persistence/TypeConverters/RoleConverter.cs @@ -0,0 +1,13 @@ +using cuqmbr.TravelGuide.Domain.Enums; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace cuqmbr.TravelGuide.Persistence.TypeConverters; + +public class RoleConverter : ValueConverter +{ + public RoleConverter() + : base( + v => v.Name, + v => IdentityRole.FromName(v)) + { } +} diff --git a/src/Persistence/packages.lock.json b/src/Persistence/packages.lock.json index 4833b36..bce5250 100644 --- a/src/Persistence/packages.lock.json +++ b/src/Persistence/packages.lock.json @@ -108,6 +108,14 @@ "resolved": "2.0.1", "contentHash": "FYv95bNT4UwcNA+G/J1oX5OpRiSUxteXaUt2BJbRSdRNiIUNbggJF69wy6mnk2wYToaanpdXZdCwVylt96MpwQ==" }, + "Microsoft.AspNetCore.Authentication.JwtBearer": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "8J04KPX5NCo6j5AjY/rgeLTceMBJ8Sq4k+YNxN/7hCrbCH1iwHVw7VGGvlCscj615ewMX3jYDmxxLdutbSPOcA==", + "dependencies": { + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" + } + }, "Microsoft.AspNetCore.Authorization": { "type": "Transitive", "resolved": "9.0.0", @@ -266,6 +274,53 @@ "resolved": "9.0.4", "contentHash": "SPFyMjyku1nqTFFJ928JAMd0QnRe4xjE7KeKnZMWXf3xk+6e0WiOZAluYtLdbJUXtsl2cCRSi8cBquJ408k8RA==" }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "X92UuBmvHYtsVrD+R+senFn6wOtSVtliSZNTZI8oHD+WqhYLmLNlHH6avYcbXqEznozxshSYzD/DVAuz54jjtg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "rLvApg2vqs/Kz5kVHwHUMAe3owInYrsPX8QP8CQktubX9R63P+J47nR/IOS4n6ddJCvGInUGRBKqcBGJtuA4Rw==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.11.0" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "/JNOMdYOQ4Tgbdwu9GbEcRJEpzakizuECCE8dCgY5lKXyqZUdAKXyeq4zITgS81eZYThqjhQZUYaJxOPofbmrg==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.11.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.0.1" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "8.0.1", + "System.IdentityModel.Tokens.Jwt": "8.0.1" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "8.11.0", + "contentHash": "E0iKSD9vv9X+tbHGriMTLkSNK/OOjxOPuf1dt9q32d25Ig+OZaidUqDoUTSS3mWTvPw+x5oXrCTHtDatbzRzTQ==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.11.0" + } + }, "Newtonsoft.Json": { "type": "Transitive", "resolved": "13.0.3", @@ -314,6 +369,15 @@ "SQLitePCLRaw.core": "2.1.10" } }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "8.0.1", + "contentHash": "GJw3bYkWpOgvN3tJo5X4lYUeIFA2HD293FPUhKmp7qxS+g5ywAb34Dnd3cDAFLkcMohy5XTpoaZ4uAHuw0uSPQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.0.1", + "Microsoft.IdentityModel.Tokens": "8.0.1" + } + }, "System.Linq.Dynamic.Core": { "type": "Transitive", "resolved": "1.6.2", @@ -338,7 +402,10 @@ "FluentValidation": "[11.11.0, )", "MediatR": "[12.4.1, )", "MediatR.Behaviors.Authorization": "[12.2.0, )", + "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.5, )", "Microsoft.Extensions.Logging": "[9.0.4, )", + "Microsoft.IdentityModel.JsonWebTokens": "[8.11.0, )", + "Microsoft.IdentityModel.Tokens": "[8.11.0, )", "Newtonsoft.Json": "[13.0.3, )", "QuikGraph": "[2.5.0, )", "System.Linq.Dynamic.Core": "[1.6.2, )" diff --git a/tst/Application.IntegrationTests/BaseTest.cs b/tst/Application.IntegrationTests/BaseTest.cs index 194ab99..26ebcb3 100644 --- a/tst/Application.IntegrationTests/BaseTest.cs +++ b/tst/Application.IntegrationTests/BaseTest.cs @@ -3,12 +3,11 @@ using cuqmbr.TravelGuide.Configuration.Configuration; using cuqmbr.TravelGuide.Configuration.Logging; using cuqmbr.TravelGuide.Configuration.Application; using cuqmbr.TravelGuide.Configuration.Persistence; -using cuqmbr.TravelGuide.Configuration.Identity; using Moq; using System.Globalization; -using cuqmbr.TravelGuide.Application.Common.Interfaces.Services; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Application.Common.Services; +using cuqmbr.TravelGuide.Domain.Enums; namespace cuqmbr.TravelGuide.Application.IntegrationTests; @@ -61,8 +60,8 @@ public abstract class TestBase : IDisposable var guid = Guid.NewGuid(); mock.Setup(s => s.Email).Returns(guid.ToString()); - mock.Setup(s => s.Id).Returns(guid.GetHashCode()); - mock.Setup(s => s.Uuid).Returns(Guid.NewGuid()); + mock.Setup(s => s.Guid).Returns(guid); + mock.Setup(s => s.Guid).Returns(Guid.NewGuid()); mock.Setup(s => s.IsAuthenticated).Returns(true); mock.Setup(s => s.Roles).Returns(roles); diff --git a/tst/Application.IntegrationTests/CitiesTests.cs b/tst/Application.IntegrationTests/CitiesTests.cs index 5a7b514..438e308 100644 --- a/tst/Application.IntegrationTests/CitiesTests.cs +++ b/tst/Application.IntegrationTests/CitiesTests.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Domain.Enums; using cuqmbr.TravelGuide.Application.Common.Exceptions; using cuqmbr.TravelGuide.Application.Countries.Commands.AddCountry; using cuqmbr.TravelGuide.Application.Regions.Commands.AddRegion; @@ -9,7 +9,6 @@ using cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity; using cuqmbr.TravelGuide.Application.Cities.Queries.GetCity; using cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage; - namespace cuqmbr.TravelGuide.Application.IntegrationTests; public class CitiesTests : TestBase diff --git a/tst/Application.IntegrationTests/CountriesTests.cs b/tst/Application.IntegrationTests/CountriesTests.cs index 43b5f88..72d6af3 100644 --- a/tst/Application.IntegrationTests/CountriesTests.cs +++ b/tst/Application.IntegrationTests/CountriesTests.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Domain.Enums; using cuqmbr.TravelGuide.Application.Common.Exceptions; using cuqmbr.TravelGuide.Application.Countries.Commands.AddCountry; using cuqmbr.TravelGuide.Application.Countries.Commands.UpdateCountry; @@ -7,7 +7,6 @@ using cuqmbr.TravelGuide.Application.Countries.Commands.DeleteCountry; using cuqmbr.TravelGuide.Application.Countries.Queries.GetCountry; using cuqmbr.TravelGuide.Application.Countries.Queries.GetCountriesPage; - namespace cuqmbr.TravelGuide.Application.IntegrationTests; public class CountriesTests : TestBase diff --git a/tst/Application.IntegrationTests/RegionsTests.cs b/tst/Application.IntegrationTests/RegionsTests.cs index 7dbc6e8..372300e 100644 --- a/tst/Application.IntegrationTests/RegionsTests.cs +++ b/tst/Application.IntegrationTests/RegionsTests.cs @@ -1,5 +1,5 @@ using MediatR; -using cuqmbr.TravelGuide.Application.Common.Models; +using cuqmbr.TravelGuide.Domain.Enums; using cuqmbr.TravelGuide.Application.Common.Exceptions; using cuqmbr.TravelGuide.Application.Countries.Commands.AddCountry; using cuqmbr.TravelGuide.Application.Regions.Commands.AddRegion; @@ -8,7 +8,6 @@ using cuqmbr.TravelGuide.Application.Regions.Commands.DeleteRegion; using cuqmbr.TravelGuide.Application.Regions.Queries.GetRegion; using cuqmbr.TravelGuide.Application.Regions.Queries.GetRegionsPage; - namespace cuqmbr.TravelGuide.Application.IntegrationTests; public class RegionsTests : TestBase diff --git a/tst/Application.IntegrationTests/packages.lock.json b/tst/Application.IntegrationTests/packages.lock.json index 117f2e7..1a02d20 100644 --- a/tst/Application.IntegrationTests/packages.lock.json +++ b/tst/Application.IntegrationTests/packages.lock.json @@ -154,8 +154,8 @@ }, "Microsoft.AspNetCore.Authentication.JwtBearer": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0HgfWPfnjlzWFbW4pw6FYNuIMV8obVU+MUkiZ33g4UOpvZcmdWzdayfheKPZ5+EUly8SvfgW0dJwwIrW4IVLZQ==", + "resolved": "9.0.5", + "contentHash": "8J04KPX5NCo6j5AjY/rgeLTceMBJ8Sq4k+YNxN/7hCrbCH1iwHVw7VGGvlCscj615ewMX3jYDmxxLdutbSPOcA==", "dependencies": { "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" } @@ -186,15 +186,15 @@ }, "Microsoft.AspNetCore.Cryptography.Internal": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "E4pHyEb2Ul5a6bIwraGtw9TN39a/C2asyVPEJoyItc0reV4Y26FsPcEdcXyKjBbP4kSz9iU1Cz4Yhx/aOFPpqA==" + "resolved": "2.3.0", + "contentHash": "/qy5r0CD40OccajzDmX3gBfqqxpAJkcXoqlVz0YR70x3gTRq/VuseDU/lZ5eh8vM+KCdmPFAtyGcRWxTyXxuYg==" }, "Microsoft.AspNetCore.Cryptography.KeyDerivation": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "5v9Kj2arRrCftLKW80Hfj31HkNnjcKyw57lQhF84drvGxJlCR63J0zMM1sMM+Hc+KCQjuoDmHtjwN0uOT+X3ag==", + "resolved": "2.3.0", + "contentHash": "S7pph0JuBkgNqtyiIdLtQ5icZxmpX502zxxvHuMtM5W7IR3CKl1r/Cup+i6+E6B7IF3BeZYF4O3RbcA108syig==", "dependencies": { - "Microsoft.AspNetCore.Cryptography.Internal": "9.0.4" + "Microsoft.AspNetCore.Cryptography.Internal": "2.3.0" } }, "Microsoft.AspNetCore.DataProtection": { @@ -288,15 +288,6 @@ "Microsoft.Extensions.Identity.Core": "2.3.0" } }, - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "IC3X6Db6H0cXdE2zGtyk/jmSwXhHbJZaiNpg7TNFV/Biu/NgO6l/GuwgE0D1U6U9pca00WsqxESkNov+WA77CA==", - "dependencies": { - "Microsoft.EntityFrameworkCore.Relational": "9.0.4", - "Microsoft.Extensions.Identity.Stores": "9.0.4" - } - }, "Microsoft.AspNetCore.Metadata": { "type": "Transitive", "resolved": "9.0.0", @@ -566,22 +557,13 @@ }, "Microsoft.Extensions.Identity.Core": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "KKfCsoIHFGZmmCEjZBPuvDW0pCjboMru/Z3vbEyC/OIwUVeKrdPugFyjc81i7rNSjcPcDxVvGl/Ks8HLelKocg==", + "resolved": "2.3.0", + "contentHash": "yR0eFnUbAM2k+q5QsX0NKinfShIe1B/aiHXEywiNT5Cs2MvEhxQIbIn5rWXnEAfmwW+i+t5D8odPSEHz/taIyQ==", "dependencies": { - "Microsoft.AspNetCore.Cryptography.KeyDerivation": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4" - } - }, - "Microsoft.Extensions.Identity.Stores": { - "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0F6lSngwyXzrv+qtX46nhHYBOlPxEzj0qyCCef1kvlyEYhbj8kBL13FuDk4nEPkzk1yVjZgsnXBG19+TrNdakQ==", - "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "9.0.4", - "Microsoft.Extensions.Identity.Core": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" + "Microsoft.AspNetCore.Cryptography.KeyDerivation": "2.3.0", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Options": "8.0.2", + "System.ComponentModel.Annotations": "5.0.0" } }, "Microsoft.Extensions.Localization": { @@ -687,23 +669,23 @@ }, "Microsoft.IdentityModel.Abstractions": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "0lKw+f3vkmV9t3PLe6sY3xPrYrHYiMRFxuOse5CMkKPxhQYiabpfJsuk6wX2RrVQ86Dn+t/8poHpH0nbp6sFvA==" + "resolved": "8.11.0", + "contentHash": "X92UuBmvHYtsVrD+R+senFn6wOtSVtliSZNTZI8oHD+WqhYLmLNlHH6avYcbXqEznozxshSYzD/DVAuz54jjtg==" }, "Microsoft.IdentityModel.JsonWebTokens": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "lepOkZZTMfJCPSnWITXxV+4Wxb54g+9oIybs9YovlOzZWuR1i2DOpzaDgSe+piDJaGtnSrcUlcB9fZ5Swur7Uw==", + "resolved": "8.11.0", + "contentHash": "rLvApg2vqs/Kz5kVHwHUMAe3owInYrsPX8QP8CQktubX9R63P+J47nR/IOS4n6ddJCvGInUGRBKqcBGJtuA4Rw==", "dependencies": { - "Microsoft.IdentityModel.Tokens": "8.8.0" + "Microsoft.IdentityModel.Tokens": "8.11.0" } }, "Microsoft.IdentityModel.Logging": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "sUyoxzg/WBZobbFLJK8loT9IILKtS9ePmWu5B11ogQqhSHppE6SRZKw0fhI6Fd16X6ey52cbbWc2rvMBC98EQA==", + "resolved": "8.11.0", + "contentHash": "/JNOMdYOQ4Tgbdwu9GbEcRJEpzakizuECCE8dCgY5lKXyqZUdAKXyeq4zITgS81eZYThqjhQZUYaJxOPofbmrg==", "dependencies": { - "Microsoft.IdentityModel.Abstractions": "8.8.0" + "Microsoft.IdentityModel.Abstractions": "8.11.0" } }, "Microsoft.IdentityModel.Protocols": { @@ -725,11 +707,11 @@ }, "Microsoft.IdentityModel.Tokens": { "type": "Transitive", - "resolved": "8.8.0", - "contentHash": "09hnbUJh/18gUmu5nCVFMvyzAFC4l1qyc4bwSJaKzUBqHN7aNDwmSx8dE3/MMJImbvnKq9rEtkkgnrS/OUBtjA==", + "resolved": "8.11.0", + "contentHash": "E0iKSD9vv9X+tbHGriMTLkSNK/OOjxOPuf1dt9q32d25Ig+OZaidUqDoUTSS3mWTvPw+x5oXrCTHtDatbzRzTQ==", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "8.0.2", - "Microsoft.IdentityModel.Logging": "8.8.0" + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.11.0" } }, "Microsoft.Net.Http.Headers": { @@ -856,6 +838,11 @@ "resolved": "4.6.0", "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==" + }, "System.Diagnostics.EventLog": { "type": "Transitive", "resolved": "6.0.0", @@ -986,7 +973,10 @@ "FluentValidation": "[11.11.0, )", "MediatR": "[12.4.1, )", "MediatR.Behaviors.Authorization": "[12.2.0, )", + "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.5, )", "Microsoft.Extensions.Logging": "[9.0.4, )", + "Microsoft.IdentityModel.JsonWebTokens": "[8.11.0, )", + "Microsoft.IdentityModel.Tokens": "[8.11.0, )", "Newtonsoft.Json": "[13.0.3, )", "QuikGraph": "[2.5.0, )", "System.Linq.Dynamic.Core": "[1.6.2, )" @@ -999,7 +989,6 @@ "AspNetCore.Localizer.Json": "[1.0.1, )", "Domain": "[1.0.0, )", "FluentValidation.DependencyInjectionExtensions": "[11.11.0, )", - "Identity": "[1.0.0, )", "Infrastructure": "[1.0.0, )", "Microsoft.AspNetCore.Identity": "[2.3.1, )", "Microsoft.EntityFrameworkCore.InMemory": "[9.0.4, )", @@ -1019,19 +1008,6 @@ "domain": { "type": "Project" }, - "identity": { - "type": "Project", - "dependencies": { - "Application": "[1.0.0, )", - "Microsoft.AspNetCore.Authentication.JwtBearer": "[9.0.4, )", - "Microsoft.AspNetCore.Identity": "[2.3.1, )", - "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "[9.0.4, )", - "Microsoft.Extensions.Options": "[9.0.4, )", - "Microsoft.IdentityModel.JsonWebTokens": "[8.8.0, )", - "Microsoft.IdentityModel.Tokens": "[8.8.0, )", - "Npgsql.EntityFrameworkCore.PostgreSQL": "[9.0.4, )" - } - }, "infrastructure": { "type": "Project", "dependencies": {