From fba79dba5f0d63dc9c8f89c000dd6531e06bc9fd Mon Sep 17 00:00:00 2001
From: Jeff Stirn <52271945+jfstirn@users.noreply.github.com>
Date: Tue, 19 Dec 2023 20:00:34 +0100
Subject: [PATCH] User Access module implementation with the microsoft identity
framework.
---
.gitignore | 7 +
.../CompanyName.MyMeetings.API.csproj | 14 +-
.../CompanyName.MyMeetings.API.xml | 114 ++++++
.../HasPermissionAuthorizationHandler.cs | 4 +-
.../PermissionAuthorizationHandler.cs | 61 ++++
.../ExecutionContextAccessor.cs | 3 +
.../Extensions/ConfigurationExtensions.cs | 15 +
.../Extensions/SwaggerExtensions.cs | 17 +
.../AuthenticatedUserController.cs | 12 +-
.../{ => IdentityServer}/EmailsController.cs | 6 +-
.../RegisterNewUserRequest.cs | 2 +-
.../ResourceOwnerPasswordValidator.cs | 6 +-
.../UserAccessAutofacModule.cs | 6 +-
.../UserRegistrationsController.cs | 8 +-
.../ApplicationController.cs | 55 +++
.../AuthenticationController.cs | 233 ++++++++++++
.../AuthenticationMappingProfile.cs | 16 +
.../Authentication/IdentityController.cs | 61 ++++
.../AuthenticationRequestValidator.cs | 14 +
.../ResetPasswordRequestValidator.cs | 18 +
.../Authorization/AuthorizationController.cs | 40 ++
.../AuthorizationMappingProfile.cs | 15 +
.../MicrosoftIdentity/Results/ApiResult.cs | 110 ++++++
.../Results/ApiResultStatus.cs | 29 ++
.../MicrosoftIdentity/Results/ErrorMapper.cs | 64 ++++
.../Results/ResultExtensions.cs | 141 +++++++
.../Roles/RoleMappingProfile.cs | 16 +
.../Roles/RolesController.cs | 130 +++++++
.../Validators/AddRoleRequestValidator.cs | 14 +
.../Validators/RenameRoleRequestValidator.cs | 13 +
.../SetRolePermissionsRequestValidator.cs | 13 +
.../UserAccessAutofacModule.cs | 16 +
.../Users/UserMappingProfile.cs | 18 +
.../Users/UserRegistrationsController.cs | 49 +++
.../Users/UsersController.cs | 221 +++++++++++
.../ConfirmEmailAddressRequestValidator.cs | 14 +
.../CreateUserAccountRequestValidator.cs | 14 +
.../SetUserPermissionsRequestValidator.cs | 13 +
.../SetUserRolesRequestValidator.cs | 13 +
.../MicrosoftIdentity/UsersPermissions.cs | 28 ++
src/API/CompanyName.MyMeetings.API/Startup.cs | 112 +++++-
.../appsettings.json | 47 ++-
.../CompanyName.MyMeetings.Contracts.csproj | 9 +
.../Results/ErrorMessage.cs | 14 +
.../Results/Result.cs | 48 +++
.../Results/ResultOfT.cs | 19 +
.../Authentication/AuthenticationRequest.cs | 8 +
.../Authentication/AuthenticationResultDto.cs | 16 +
.../Authentication/ResetPasswordRequest.cs | 17 +
.../V1/Users/Authentication/TokenRequest.cs | 8 +
.../V1/Users/Authentication/TokenResultDto.cs | 8 +
.../V1/Users/Authorization/PermissionDto.cs | 10 +
.../V1/Users/Identity/UserAccountDto.cs | 18 +
.../V1/Users/Identity/UserPermissionDto.cs | 6 +
.../V1/Users/Roles/AddRoleRequest.cs | 8 +
.../V1/Users/Roles/PermissionDto.cs | 10 +
.../V1/Users/Roles/RenameRoleRequest.cs | 6 +
.../V1/Users/Roles/RoleDto.cs | 8 +
.../Users/Roles/SetRolePermissionsRequest.cs | 6 +
.../RegisterNewUserRequest.cs | 16 +
.../Users/Users/ConfirmEmailAddressRequest.cs | 8 +
.../Users/Users/CreateUserAccountRequest.cs | 19 +
.../V1/Users/Users/PermissionDto.cs | 10 +
.../V1/Users/Users/RoleDto.cs | 8 +
.../Users/Users/SetUserPermissionsRequest.cs | 6 +
.../V1/Users/Users/SetUserRolesRequest.cs | 6 +
.../Users/Users/UpdateUserAccountRequest.cs | 10 +
.../V1/Users/Users/UserAccountDto.cs | 71 ++++
.../Data/IDatabaseConfiguration.cs | 6 +
.../Application/IExecutionContextAccessor.cs | 2 +
src/BuildingBlocks/Domain/Entity.cs | 2 +-
src/BuildingBlocks/Domain/IEntity.cs | 12 +
.../Infrastructure/DatabaseConfiguration.cs | 13 +
.../StronglyTypedIdValueConverterSelector.cs | 2 +-
src/CompanyName.MyMeetings.sln | 75 +++-
.../CompanyName.MyMeetings.Database.sqlproj | 23 ++
.../Scripts/CreateStructure.sql | 345 ++++++++++++++++++
.../Scripts/Seeds/0002_SeedPermissions.sql | 91 +++++
.../Scripts/Seeds/0003_SeedRoles.sql | 60 +++
.../Scripts/Seeds/0004_SeedUsers.sql | 48 +++
.../Structure/Security/Schemas.sql | 3 +
.../usersmi/Tables/InboxMessages.sql | 10 +
.../usersmi/Tables/InternalCommands.sql | 11 +
.../usersmi/Tables/OutboxMessages.sql | 10 +
.../Structure/usersmi/Tables/Permission.sql | 8 +
.../Structure/usersmi/Tables/Role.sql | 11 +
.../Structure/usersmi/Tables/RoleClaim.sql | 10 +
.../Structure/usersmi/Tables/User.sql | 25 ++
.../Structure/usersmi/Tables/UserClaim.sql | 10 +
.../Structure/usersmi/Tables/UserLogin.sql | 10 +
.../usersmi/Tables/UserRefreshToken.sql | 13 +
.../usersmi/Tables/UserRegistrations.sql | 15 +
.../Structure/usersmi/Tables/UserRole.sql | 9 +
.../Structure/usersmi/Tables/UserToken.sql | 10 +
.../usersmi/Views/v_UserPermissions.sql | 10 +
.../usersmi/Views/v_UserRegistrations.sql | 12 +
.../Structure/usersmi/Views/v_UserRoles.sql | 8 +
.../Structure/usersmi/Views/v_Users.sql | 11 +
src/Directory.Build.props | 3 +-
src/Directory.Build.targets | 1 +
src/Directory.Packages.props | 5 +-
....Modules.Administration.Application.csproj | 2 +-
...ewUserRegisteredIntegrationEventHandler.cs | 2 +-
.../EventsBus/EventsBusStartup.cs | 2 +-
.../SeedWork/ExecutionContextMock.cs | 2 +
...etings.Modules.Meetings.Application.csproj | 4 +-
...ewUserRegisteredIntegrationEventHandler.cs | 2 +-
.../EventsBus/EventsBusStartup.cs | 2 +-
.../SeedWork/ExecutionContextMock.cs | 2 +
...etings.Modules.Payments.Application.csproj | 2 +-
...ewUserRegisteredIntegrationEventHandler.cs | 2 +-
.../EventsBus/EventsBusStartup.cs | 2 +-
.../SeedWork/ExecutionContextMock.cs | 2 +
.../Authenticate/AuthenticateCommand.cs | 4 +-
.../AuthenticateCommandHandler.cs | 6 +-
.../AuthenticateCommandValidator.cs | 2 +-
.../Authenticate/AuthenticationResult.cs | 2 +-
.../Authentication/Authenticate/UserDto.cs | 2 +-
.../Authentication/PasswordManager.cs | 2 +-
.../GetAuthenticatedUserPermissionsQuery.cs | 6 +-
...uthenticatedUserPermissionsQueryHandler.cs | 6 +-
.../GetUserPermissionsQuery.cs | 4 +-
.../GetUserPermissionsQueryHandler.cs | 4 +-
.../GetUserPermissions/UserPermissionDto.cs | 2 +-
...s.Modules.UserAccessIS.Application.csproj} | 3 -
.../Configuration/Commands/ICommandHandler.cs | 4 +-
.../Commands/ICommandsScheduler.cs | 4 +-
.../Commands/InternalCommandBase.cs | 4 +-
.../Configuration/Queries/IQueryHandler.cs | 4 +-
.../Application/Contracts/CommandBase.cs | 2 +-
.../Application/Contracts/CustomClaimTypes.cs | 2 +-
.../Application/Contracts/ICommand.cs | 2 +-
.../Application/Contracts/IQuery.cs | 2 +-
.../Contracts/IRecurringCommand.cs | 2 +-
.../Contracts/IUserAccessModule.cs | 2 +-
.../Application/Contracts/QueryBase.cs | 2 +-
.../UserAccess/Application/Contracts/Roles.cs | 2 +-
.../UserAccess/Application/Emails/EmailDto.cs | 2 +-
.../Application/Emails/GetAllEmailsQuery.cs | 4 +-
.../Emails/GetAllEmailsQueryHandler.cs | 4 +-
.../IdentityServer/IdentityServerConfig.cs | 4 +-
.../IdentityServer/ProfileService.cs | 4 +-
.../ConfirmUserRegistrationCommand.cs | 4 +-
.../ConfirmUserRegistrationCommandHandler.cs | 6 +-
.../UserRegistrationConfirmedHandler.cs | 8 +-
.../GetUserRegistrationQuery.cs | 4 +-
.../GetUserRegistrationQueryHandler.cs | 4 +-
.../UserRegistrationDto.cs | 2 +-
...gisteredEnqueueEmailConfirmationHandler.cs | 6 +-
.../NewUserRegisteredNotification.cs | 4 +-
.../NewUserRegisteredPublishEventHandler.cs | 4 +-
.../RegisterNewUser/RegisterNewUserCommand.cs | 4 +-
.../RegisterNewUserCommandHandler.cs | 8 +-
...serRegistrationConfirmationEmailCommand.cs | 6 +-
...strationConfirmationEmailCommandHandler.cs | 4 +-
.../UserRegistrations/UsersCounter.cs | 4 +-
.../Users/AddAdminUser/AddAdminUserCommand.cs | 4 +-
.../AddAdminUserCommandHandler.cs | 8 +-
.../GetAuthenticatedUserQuery.cs | 6 +-
.../GetAuthenticatedUserQueryHandler.cs | 6 +-
.../Application/Users/GetUser/GetUserQuery.cs | 4 +-
.../Users/GetUser/GetUserQueryHandler.cs | 4 +-
.../Application/Users/GetUser/UserDto.cs | 2 +-
...etings.Modules.UserAccessIS.Domain.csproj} | 0
.../Events/NewUserRegisteredDomainEvent.cs | 2 +-
.../UserRegistrationConfirmedDomainEvent.cs | 2 +-
.../UserRegistrationExpiredDomainEvent.cs | 2 +-
.../IUserRegistrationRepository.cs | 2 +-
.../Domain/UserRegistrations/IUsersCounter.cs | 2 +-
...eatedWhenRegistrationIsNotConfirmedRule.cs | 2 +-
.../Rules/UserLoginMustBeUniqueRule.cs | 2 +-
...ionCannotBeConfirmedAfterExpirationRule.cs | 2 +-
...rationCannotBeConfirmedMoreThanOnceRule.cs | 2 +-
...strationCannotBeExpiredMoreThanOnceRule.cs | 2 +-
.../UserRegistrations/UserRegistration.cs | 8 +-
.../UserRegistrations/UserRegistrationId.cs | 2 +-
.../UserRegistrationStatus.cs | 2 +-
.../Users/Events/UserCreatedDomainEvent.cs | 2 +-
.../Domain/Users/IUserRepository.cs | 2 +-
src/Modules/UserAccess/Domain/Users/User.cs | 6 +-
src/Modules/UserAccess/Domain/Users/UserId.cs | 2 +-
.../UserAccess/Domain/Users/UserRole.cs | 2 +-
...odules.UserAccessIS.Infrastructure.csproj} | 0
.../Configuration/AllConstructorFinder.cs | 2 +-
.../Configuration/Assemblies.cs | 4 +-
.../DataAccess/DataAccessModule.cs | 2 +-
.../Configuration/Domain/DomainModule.cs | 6 +-
.../Configuration/Email/EmailModule.cs | 2 +-
.../EventsBus/EventsBusModule.cs | 2 +-
.../EventsBus/EventsBusStartup.cs | 2 +-
.../IntegrationEventGenericHandler.cs | 2 +-
.../Configuration/Logging/LoggingModule.cs | 2 +-
.../Configuration/Mediation/MediatorModule.cs | 4 +-
.../Processing/CommandsExecutor.cs | 4 +-
.../Processing/IRecurringCommand.cs | 2 +-
.../Processing/Inbox/InboxMessageDto.cs | 2 +-
.../Processing/Inbox/ProcessInboxCommand.cs | 6 +-
.../Inbox/ProcessInboxCommandHandler.cs | 4 +-
.../Processing/Inbox/ProcessInboxJob.cs | 2 +-
.../InternalCommands/CommandsScheduler.cs | 6 +-
.../ProcessInternalCommandsCommand.cs | 6 +-
.../ProcessInternalCommandsCommandHandler.cs | 4 +-
.../ProcessInternalCommandsJob.cs | 2 +-
.../LoggingCommandHandlerDecorator.cs | 11 +-
...oggingCommandHandlerWithResultDecorator.cs | 6 +-
.../Processing/Outbox/OutboxMessageDto.cs | 2 +-
.../Processing/Outbox/OutboxModule.cs | 4 +-
.../Processing/Outbox/ProcessOutboxCommand.cs | 6 +-
.../Outbox/ProcessOutboxCommandHandler.cs | 4 +-
.../Processing/Outbox/ProcessOutboxJob.cs | 2 +-
.../Processing/ProcessingModule.cs | 6 +-
.../UnitOfWorkCommandHandlerDecorator.cs | 6 +-
...OfWorkCommandHandlerWithResultDecorator.cs | 6 +-
.../ValidationCommandHandlerDecorator.cs | 6 +-
...dationCommandHandlerWithResultDecorator.cs | 6 +-
.../Configuration/Quartz/QuartzModule.cs | 2 +-
.../Configuration/Quartz/QuartzStartup.cs | 8 +-
.../Quartz/SerilogLogProvider.cs | 2 +-
.../Security/AesDataProtector.cs | 2 +-
.../Configuration/Security/IDataProtector.cs | 2 +-
.../Configuration/Security/SecurityModule.cs | 2 +-
.../UserAccessCompositionRoot.cs | 2 +-
.../Configuration/UserAccessStartup.cs | 24 +-
...UserRegistrationEntityTypeConfiguration.cs | 4 +-
.../UserRegistrationRepository.cs | 4 +-
.../Users/UserEntityTypeConfiguration.cs | 4 +-
.../Domain/Users/UserRepository.cs | 4 +-
.../InternalCommandEntityTypeConfiguration.cs | 2 +-
.../Infrastructure/Outbox/OutboxAccessor.cs | 2 +-
.../OutboxMessageEntityTypeConfiguration.cs | 2 +-
.../Infrastructure/UserAccessContext.cs | 14 +-
.../Infrastructure/UserAccessModule.cs | 8 +-
...les.UserAccessIS.IntegrationEvents.csproj} | 0
.../NewUserRegisteredIntegrationEvent.cs | 2 +-
.../ArchTests/Application/ApplicationTests.cs | 10 +-
...ngs.Modules.UserAccessIS.ArchTests.csproj} | 0
.../Tests/ArchTests/Domain/DomainTests.cs | 4 +-
.../Tests/ArchTests/Module/LayersTests.cs | 4 +-
.../Tests/ArchTests/SeedWork/TestBase.cs | 8 +-
.../Tests/IntegrationTests/AssemblyInfo.cs | 2 +-
...ules.UserAccessIS.IntegrationTests.csproj} | 0
.../SeedWork/ExecutionContextMock.cs | 4 +-
.../SeedWork/OutboxMessagesHelper.cs | 6 +-
.../IntegrationTests/SeedWork/TestBase.cs | 8 +-
.../ConfirmUserRegistrationTests.cs | 12 +-
...dUserRegistrationConfirmationEmailTests.cs | 8 +-
.../UserRegistrationSampleData.cs | 2 +-
.../UserRegistrationTests.cs | 8 +-
.../IntegrationTests/Users/CreateUserTests.cs | 12 +-
...ules.UserAccessIS.Domain.UnitTests.csproj} | 0
.../SeedWork/DomainEventsTestHelper.cs | 2 +-
.../Tests/UnitTests/SeedWork/TestBase.cs | 2 +-
.../UserRegistrationTests.cs | 12 +-
.../Login/AccountLoginCommand.cs | 16 +
.../Login/AccountLoginCommandHandler.cs | 162 ++++++++
.../Login/AccountLoginCommandValidator.cs | 12 +
.../Login/AccountTwoFactorLoginCommand.cs | 19 +
.../AccountTwoFactorLoginCommandHandler.cs | 57 +++
.../Login/AuthenticationResult.cs | 62 ++++
.../External/ExternalAccountLoginCommand.cs | 22 ++
.../ExternalAccountLoginCommandHandler.cs | 76 ++++
.../Authentication/Login/UserDto.cs | 16 +
.../RefreshToken/RefreshTokenCommand.cs | 17 +
.../RefreshTokenCommandHandler.cs | 22 ++
.../Authentication/RefreshToken/TokenDto.cs | 3 +
.../ForgotPasswordLinkResult.cs | 17 +
.../RequestForgotPasswordLinkCommand.cs | 13 +
...RequestForgotPasswordLinkCommandHandler.cs | 41 +++
.../ResetPassword/ResetPasswordCommand.cs | 20 +
.../ResetPasswordCommandHandler.cs | 40 ++
.../ByUserId/GetPermissionsQuery.cs | 14 +
.../ByUserId/GetPermissionsQueryHandler.cs | 84 +++++
.../Directory/GetPermissionsQuery.cs | 8 +
.../Directory/GetPermissionsQueryHandler.cs | 31 ++
.../GetPermissions/PermissionDto.cs | 10 +
.../GetUserRoles/GetUserRolesQuery.cs | 14 +
.../GetUserRoles/GetUserRolesQueryHandler.cs | 44 +++
.../Authorization/GetUserRoles/RoleDto.cs | 8 +
...gs.Modules.UserAccessMI.Application.csproj | 11 +
.../Configuration/Commands/ICommandHandler.cs | 15 +
.../Commands/ICommandsScheduler.cs | 10 +
.../Commands/InternalCommandBase.cs | 28 ++
.../Configuration/Queries/IQueryHandler.cs | 10 +
.../Configuration/Results/IResult.cs | 26 ++
.../Configuration/Results/IResultOfT.cs | 8 +
.../Configuration/Results/RespultOfT.cs | 42 +++
.../Configuration/Results/Result.cs | 117 ++++++
.../Configuration/Results/ResultStatus.cs | 24 ++
.../Contracts/ApplicationPermissions.cs | 6 +
.../Application/Contracts/CommandBase.cs | 31 ++
.../Application/Contracts/CustomClaimTypes.cs | 15 +
.../Application/Contracts/ICommand.cs | 13 +
.../Application/Contracts/IQuery.cs | 7 +
.../Contracts/IRecurringCommand.cs | 5 +
.../Contracts/ITokenClaimsService.cs | 20 +
.../Contracts/IUserAccessModule.cs | 10 +
.../Application/Contracts/QueryBase.cs | 16 +
.../Application/Contracts/Roles.cs | 8 +
.../Application/CustomValidators.cs | 110 ++++++
.../GetUserAccount/GetUserAccountQuery.cs | 14 +
.../GetUserAccountQueryHandler.cs | 37 ++
.../Identity/GetUserAccount/UserAccountDto.cs | 18 +
.../GetUserPermissionsQuery.cs | 14 +
.../GetUserPermissionsQueryHandler.cs | 29 ++
.../GetUserPermissions/UserPermissionDto.cs | 6 +
.../Application/IdentityHelpers.cs | 12 +
.../Roles/CreateRole/CreateRoleCommand.cs | 17 +
.../CreateRole/CreateRoleCommandHandler.cs | 39 ++
.../Roles/DeleteRole/DeleteRoleCommand.cs | 14 +
.../DeleteRole/DeleteRoleCommandHandler.cs | 29 ++
.../GetRolePermissionsQuery.cs | 14 +
.../GetRolePermissionsQueryHandler.cs | 64 ++++
.../Roles/GetRolePermissions/PermissionDto.cs | 10 +
.../Roles/GetRoles/ById/GetRolesQuery.cs | 14 +
.../GetRoles/ById/GetRolesQueryHandler.cs | 35 ++
.../Roles/GetRoles/Directory/GetRolesQuery.cs | 8 +
.../Directory/GetRolesQueryHandler.cs | 28 ++
.../Application/Roles/GetRoles/RoleDto.cs | 8 +
.../Roles/RenameRole/RenameRoleCommand.cs | 17 +
.../RenameRole/RenameRoleCommandHander.cs | 36 ++
.../SetRolePermissionsCommand.cs | 17 +
.../SetRolePermissionsCommandHandler.cs | 61 ++++
.../GetAuthenticatorKeyQuery.cs | 14 +
.../GetAuthenticatorKeyQueryHandler.cs | 46 +++
.../RegisterAuthenticatorCommand.cs | 17 +
.../RegisterAuthenticatorCommandHandler.cs | 35 ++
.../ChangeEmailAddressCommand.cs | 20 +
.../ChangeEmailAddressCommandHandler.cs | 47 +++
.../ChangePassword/ChangePasswordCommand.cs | 20 +
.../ChangePasswordCommandHandler.cs | 42 +++
.../ConfirmEmailAddressCommand.cs | 17 +
.../ConfirmEmailAddressCommandHandler.cs | 34 ++
.../CreateUserAccountCommand.cs | 29 ++
.../CreateUserAccountCommandHandler.cs | 67 ++++
.../ById/GetUserAccountsQuery.cs | 14 +
.../ById/GetUserAccountsQueryHandler.cs | 47 +++
.../Directory/GetUserAccountsQuery.cs | 8 +
.../Directory/GetUserAccountsQueryHandler.cs | 41 +++
.../GetUserAccounts/UserAccountDto.cs | 83 +++++
.../RequestChangeEmailAddressCommand.cs | 18 +
...RequestChangeEmailAddressCommandHandler.cs | 31 ++
.../RequestChangeEmailAddressResult.cs | 18 +
.../SetUserPermissionsCommand.cs | 17 +
.../SetUserPermissionsCommandHandler.cs | 48 +++
.../SetUserRoles/SetUserRolesCommand.cs | 17 +
.../SetUserRolesCommandHandler.cs | 66 ++++
.../UnlockUserAccountCommand.cs | 14 +
.../UnlockUserAccountCommandHandler.cs | 34 ++
.../UpdateUserAccountCommand.cs | 23 ++
.../UpdateUserAccountCommandHandler.cs | 38 ++
.../ConfirmUserRegistrationCommand.cs | 14 +
.../ConfirmUserRegistrationCommandHandler.cs | 30 ++
.../UserRegistrationConfirmedHandler.cs | 48 +++
.../GetUserRegistrationQuery.cs | 15 +
.../GetUserRegistrationQueryHandler.cs | 48 +++
.../UserRegistrationDto.cs | 18 +
...gisteredEnqueueEmailConfirmationHandler.cs | 24 ++
.../NewUserRegisteredNotification.cs | 14 +
.../NewUserRegisteredPublishEventHandler.cs | 28 ++
.../RegisterNewUser/RegisterNewUserCommand.cs | 35 ++
.../RegisterNewUserCommandHandler.cs | 42 +++
...serRegistrationConfirmationEmailCommand.cs | 27 ++
...strationConfirmationEmailCommandHandler.cs | 28 ++
.../UserRegistrations/UsersCounter.cs | 31 ++
...eetings.Modules.UserAccessMI.Domain.csproj | 12 +
.../Domain/ErrorHandling/Error.cs | 125 +++++++
.../Domain/ErrorHandling/ErrorExtensions.cs | 71 ++++
.../Domain/ErrorHandling/Errors.cs | 125 +++++++
.../Domain/IUserRefreshTokenRepository.cs | 10 +
.../UserAccessMI/Domain/UserRefreshToken.cs | 43 +++
.../UserAccessMI/Domain/UserRefreshTokenId.cs | 11 +
.../Events/NewUserRegisteredDomainEvent.cs | 42 +++
.../UserRegistrationConfirmedDomainEvent.cs | 13 +
.../UserRegistrationExpiredDomainEvent.cs | 13 +
.../IUserRegistrationRepository.cs | 8 +
.../Domain/UserRegistrations/IUsersCounter.cs | 6 +
...eatedWhenRegistrationIsNotConfirmedRule.cs | 17 +
.../Rules/UserLoginMustBeUniqueRule.cs | 19 +
...ionCannotBeConfirmedAfterExpirationRule.cs | 17 +
...rationCannotBeConfirmedMoreThanOnceRule.cs | 17 +
...strationCannotBeExpiredMoreThanOnceRule.cs | 17 +
.../UserRegistrations/UserRegistration.cs | 113 ++++++
.../UserRegistrations/UserRegistrationId.cs | 11 +
.../UserRegistrationStatus.cs | 20 +
.../Domain/Users/ApplicationUser.cs | 76 ++++
.../Users/Events/UserCreatedDomainEvent.cs | 13 +
src/Modules/UserAccessMI/Domain/Users/Role.cs | 16 +
.../UserAccessMI/Domain/Users/UserRole.cs | 22 ++
...Modules.UserAccessMI.Infrastructure.csproj | 16 +
.../Configuration/AllConstructorFinder.cs | 20 +
.../Configuration/Assemblies.cs | 9 +
.../DataAccess/DataAccessModule.cs | 41 +++
.../Configuration/Domain/DomainModule.cs | 16 +
.../Configuration/Email/EmailModule.cs | 34 ++
.../EventsBus/EventsBusModule.cs | 28 ++
.../EventsBus/EventsBusStartup.cs | 30 ++
.../IntegrationEventGenericHandler.cs | 38 ++
.../Configuration/IUserAccessConfiguration.cs | 30 ++
.../DoesNotContainPasswordValidator.cs | 29 ++
.../EmailConfirmationTokenProvider.cs | 21 ++
.../EmailConfirmationTokenProviderOptions.cs | 7 +
.../Configuration/Identity/IdentityModule.cs | 47 +++
.../Configuration/Logging/LoggingModule.cs | 21 ++
.../Configuration/Mediation/MediatorModule.cs | 92 +++++
.../Processing/CommandsExecutor.cs | 26 ++
.../Processing/IRecurringCommand.cs | 5 +
.../Processing/Inbox/InboxMessageDto.cs | 10 +
.../Processing/Inbox/ProcessInboxCommand.cs | 5 +
.../Inbox/ProcessInboxCommandHandler.cs | 62 ++++
.../Processing/Inbox/ProcessInboxJob.cs | 12 +
.../InternalCommands/CommandsScheduler.cs | 56 +++
.../ProcessInternalCommandsCommand.cs | 5 +
.../ProcessInternalCommandsCommandHandler.cs | 82 +++++
.../ProcessInternalCommandsJob.cs | 12 +
.../LoggingCommandHandlerDecorator.cs | 89 +++++
...oggingCommandHandlerWithResultDecorator.cs | 87 +++++
.../Processing/Outbox/OutboxMessageDto.cs | 10 +
.../Processing/Outbox/OutboxModule.cs | 59 +++
.../Processing/Outbox/ProcessOutboxCommand.cs | 5 +
.../Outbox/ProcessOutboxCommandHandler.cs | 84 +++++
.../Processing/Outbox/ProcessOutboxJob.cs | 12 +
.../Processing/ProcessingModule.cs | 68 ++++
.../UnitOfWorkCommandHandlerDecorator.cs | 41 +++
...OfWorkCommandHandlerWithResultDecorator.cs | 43 +++
.../ValidationCommandHandlerDecorator.cs | 37 ++
...dationCommandHandlerWithResultDecorator.cs | 38 ++
.../Configuration/Quartz/QuartzModule.cs | 13 +
.../Configuration/Quartz/QuartzStartup.cs | 111 ++++++
.../Quartz/SerilogLogProvider.cs | 67 ++++
.../Security/AesDataProtector.cs | 63 ++++
.../Configuration/Security/IDataProtector.cs | 8 +
.../Configuration/Security/SecurityModule.cs | 20 +
.../Configuration/Services/ServicesModule.cs | 25 ++
.../UserAccessCompositionRoot.cs | 23 ++
.../Configuration/UserAccessConfiguration.cs | 15 +
.../Configuration/UserAccessStartup.cs | 93 +++++
.../ApplicationUserEntityTypeConfiguration.cs | 17 +
...dentityRoleClaimEntityTypeConfiguration.cs | 13 +
...dentityUserClaimEntityTypeConfiguration.cs | 13 +
...dentityUserLoginEntityTypeConfiguration.cs | 13 +
...IdentityUserRoleEntityTypeConfiguration.cs | 13 +
...dentityUserTokenEntityTypeConfiguration.cs | 13 +
.../RoleEntityTypeConfiguration.cs | 13 +
...UserRefreshTokenEntityTypeConfiguration.cs | 22 ++
...UserRegistrationEntityTypeConfiguration.cs | 29 ++
.../UserRefreshTokenRepository.cs | 31 ++
.../UserRegistrationRepository.cs | 24 ++
.../InternalCommandEntityTypeConfiguration.cs | 16 +
.../Infrastructure/Outbox/OutboxAccessor.cs | 23 ++
.../OutboxMessageEntityTypeConfiguration.cs | 16 +
.../IdentityTokenService/CustomClaimTypes.cs | 12 +
.../IdentityTokenClaimService.cs | 186 ++++++++++
.../Infrastructure/UserAccessContext.cs | 90 +++++
.../Infrastructure/UserAccessModule.cs | 30 ++
...ules.UserAccessMI.IntegrationEvents.csproj | 9 +
.../NewUserRegisteredIntegrationEvent.cs | 29 ++
src/Tests/ArchTests/Modules/ModuleTests.cs | 6 +-
.../SeedWork/ExecutionContextMock.cs | 2 +
src/Tests/SUT/Helpers/UsersFactory.cs | 8 +-
.../SUT/SeedWork/ExecutionContextMock.cs | 2 +
src/Tests/SUT/SeedWork/TestBase.cs | 6 +-
461 files changed, 9718 insertions(+), 379 deletions(-)
create mode 100644 src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.xml
create mode 100644 src/API/CompanyName.MyMeetings.API/Configuration/Authorization/PermissionAuthorizationHandler.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Configuration/Extensions/ConfigurationExtensions.cs
rename src/API/CompanyName.MyMeetings.API/Modules/UserAccess/{ => IdentityServer}/AuthenticatedUserController.cs (69%)
rename src/API/CompanyName.MyMeetings.API/Modules/UserAccess/{ => IdentityServer}/EmailsController.cs (77%)
rename src/API/CompanyName.MyMeetings.API/Modules/UserAccess/{ => IdentityServer}/RegisterNewUserRequest.cs (81%)
rename src/API/CompanyName.MyMeetings.API/Modules/UserAccess/{ => IdentityServer}/ResourceOwnerPasswordValidator.cs (82%)
rename src/API/CompanyName.MyMeetings.API/Modules/UserAccess/{ => IdentityServer}/UserAccessAutofacModule.cs (59%)
rename src/API/CompanyName.MyMeetings.API/Modules/UserAccess/{ => IdentityServer}/UserRegistrationsController.cs (80%)
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/ApplicationController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationMappingProfile.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/IdentityController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/AuthenticationRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/ResetPasswordRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationMappingProfile.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResult.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResultStatus.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ErrorMapper.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ResultExtensions.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RoleMappingProfile.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RolesController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/AddRoleRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/RenameRoleRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/SetRolePermissionsRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UserAccessAutofacModule.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserMappingProfile.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserRegistrationsController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UsersController.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/ConfirmEmailAddressRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/CreateUserAccountRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserPermissionsRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserRolesRequestValidator.cs
create mode 100644 src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UsersPermissions.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/CompanyName.MyMeetings.Contracts.csproj
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/Results/ErrorMessage.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/Results/Result.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/Results/ResultOfT.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationResultDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/ResetPasswordRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenResultDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authorization/PermissionDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserAccountDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserPermissionDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/AddRoleRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/PermissionDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RenameRoleRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RoleDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/SetRolePermissionsRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/UserRegistrations/RegisterNewUserRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/ConfirmEmailAddressRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/CreateUserAccountRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/PermissionDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/RoleDto.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserPermissionsRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserRolesRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UpdateUserAccountRequest.cs
create mode 100644 src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UserAccountDto.cs
create mode 100644 src/BuildingBlocks/Application/Data/IDatabaseConfiguration.cs
create mode 100644 src/BuildingBlocks/Domain/IEntity.cs
create mode 100644 src/BuildingBlocks/Infrastructure/DatabaseConfiguration.cs
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0002_SeedPermissions.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0003_SeedRoles.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0004_SeedUsers.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InboxMessages.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InternalCommands.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/OutboxMessages.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Permission.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Role.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/RoleClaim.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/User.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserClaim.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserLogin.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRefreshToken.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRegistrations.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRole.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserToken.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserPermissions.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRegistrations.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRoles.sql
create mode 100644 src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_Users.sql
rename src/Modules/UserAccess/Application/{CompanyName.MyMeetings.Modules.UserAccess.Application.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.Application.csproj} (68%)
rename src/Modules/UserAccess/Domain/{CompanyName.MyMeetings.Modules.UserAccess.Domain.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.Domain.csproj} (100%)
rename src/Modules/UserAccess/Infrastructure/{CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.csproj} (100%)
rename src/Modules/UserAccess/IntegrationEvents/{CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents.csproj} (100%)
rename src/Modules/UserAccess/Tests/ArchTests/{CompanyName.MyMeetings.Modules.UserAccess.ArchTests.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.csproj} (100%)
rename src/Modules/UserAccess/Tests/IntegrationTests/{CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.csproj} (100%)
rename src/Modules/UserAccess/Tests/UnitTests/{CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.csproj => CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.csproj} (100%)
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandValidator.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/AuthenticationResult.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/Login/UserDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/RefreshToken/TokenDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/ForgotPasswordLinkResult.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetPermissions/PermissionDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/RoleDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/CompanyName.MyMeetings.Modules.UserAccessMI.Application.csproj
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandsScheduler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Commands/InternalCommandBase.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Queries/IQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Results/IResult.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Results/IResultOfT.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Results/RespultOfT.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Results/Result.cs
create mode 100644 src/Modules/UserAccessMI/Application/Configuration/Results/ResultStatus.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/ApplicationPermissions.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/CommandBase.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/CustomClaimTypes.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/ICommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/IQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/IRecurringCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/ITokenClaimsService.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/IUserAccessModule.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/QueryBase.cs
create mode 100644 src/Modules/UserAccessMI/Application/Contracts/Roles.cs
create mode 100644 src/Modules/UserAccessMI/Application/CustomValidators.cs
create mode 100644 src/Modules/UserAccessMI/Application/Identity/GetUserAccount/GetUserAccountQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Identity/GetUserAccount/GetUserAccountQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Identity/GetUserAccount/UserAccountDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/Identity/GetUserPermissions/GetUserPermissionsQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Identity/GetUserPermissions/GetUserPermissionsQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Identity/GetUserPermissions/UserPermissionDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/IdentityHelpers.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/CreateRole/CreateRoleCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/CreateRole/CreateRoleCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/DeleteRole/DeleteRoleCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/DeleteRole/DeleteRoleCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRolePermissions/GetRolePermissionsQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRolePermissions/GetRolePermissionsQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRolePermissions/PermissionDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRoles/ById/GetRolesQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRoles/ById/GetRolesQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRoles/Directory/GetRolesQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRoles/Directory/GetRolesQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/GetRoles/RoleDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/RenameRole/RenameRoleCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/RenameRole/RenameRoleCommandHander.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/SetRolePermissions/SetRolePermissionsCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/Roles/SetRolePermissions/SetRolePermissionsCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/AuthenticatorRegistration/GetAuthenticatorKey/GetAuthenticatorKeyQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/AuthenticatorRegistration/GetAuthenticatorKey/GetAuthenticatorKeyQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/AuthenticatorRegistration/RegisterAuthenticator/RegisterAuthenticatorCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/AuthenticatorRegistration/RegisterAuthenticator/RegisterAuthenticatorCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/ChangeEmailAddress/ChangeEmailAddressCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/ChangeEmailAddress/ChangeEmailAddressCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/ChangePassword/ChangePasswordCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/ChangePassword/ChangePasswordCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/ConfirmEmailAddress/ConfirmEmailAddressCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/ConfirmEmailAddress/ConfirmEmailAddressCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/CreateUserAccount/CreateUserAccountCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/CreateUserAccount/CreateUserAccountCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/GetUserAccounts/ById/GetUserAccountsQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/GetUserAccounts/ById/GetUserAccountsQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/GetUserAccounts/Directory/GetUserAccountsQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/GetUserAccounts/Directory/GetUserAccountsQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/GetUserAccounts/UserAccountDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/RequestChangeEmailAddress/RequestChangeEmailAddressCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/RequestChangeEmailAddress/RequestChangeEmailAddressCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/RequestChangeEmailAddress/RequestChangeEmailAddressResult.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/SetUserPermissions/SetUserPermissionsCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/SetUserPermissions/SetUserPermissionsCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/SetUserRoles/SetUserRolesCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/SetUserRoles/SetUserRolesCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/UnlockUserAccount/UnlockUserAccountCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/UnlockUserAccount/UnlockUserAccountCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/UpdateUserAccount/UpdateUserAccountCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserAccounts/UpdateUserAccount/UpdateUserAccountCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/ConfirmUserRegistration/UserRegistrationConfirmedHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQuery.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQueryHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/GetUserRegistration/UserRegistrationDto.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredEnqueueEmailConfirmationHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredNotification.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredPublishEventHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommand.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Application/UserRegistrations/UsersCounter.cs
create mode 100644 src/Modules/UserAccessMI/Domain/CompanyName.MyMeetings.Modules.UserAccessMI.Domain.csproj
create mode 100644 src/Modules/UserAccessMI/Domain/ErrorHandling/Error.cs
create mode 100644 src/Modules/UserAccessMI/Domain/ErrorHandling/ErrorExtensions.cs
create mode 100644 src/Modules/UserAccessMI/Domain/ErrorHandling/Errors.cs
create mode 100644 src/Modules/UserAccessMI/Domain/IUserRefreshTokenRepository.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRefreshToken.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRefreshTokenId.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Events/NewUserRegisteredDomainEvent.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Events/UserRegistrationConfirmedDomainEvent.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Events/UserRegistrationExpiredDomainEvent.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/IUserRegistrationRepository.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/IUsersCounter.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Rules/UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Rules/UserLoginMustBeUniqueRule.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedAfterExpirationRule.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedMoreThanOnceRule.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/Rules/UserRegistrationCannotBeExpiredMoreThanOnceRule.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/UserRegistration.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/UserRegistrationId.cs
create mode 100644 src/Modules/UserAccessMI/Domain/UserRegistrations/UserRegistrationStatus.cs
create mode 100644 src/Modules/UserAccessMI/Domain/Users/ApplicationUser.cs
create mode 100644 src/Modules/UserAccessMI/Domain/Users/Events/UserCreatedDomainEvent.cs
create mode 100644 src/Modules/UserAccessMI/Domain/Users/Role.cs
create mode 100644 src/Modules/UserAccessMI/Domain/Users/UserRole.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/CompanyName.MyMeetings.Modules.UserAccessMI.Infrastructure.csproj
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/AllConstructorFinder.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Assemblies.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/DataAccess/DataAccessModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Domain/DomainModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Email/EmailModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/EventsBus/EventsBusModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/EventsBus/IntegrationEventGenericHandler.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/IUserAccessConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Identity/DoesNotContainPasswordValidator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Identity/EmailConfirmationTokenProvider.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Identity/EmailConfirmationTokenProviderOptions.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Identity/IdentityModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Logging/LoggingModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Mediation/MediatorModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/CommandsExecutor.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/IRecurringCommand.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/InternalCommands/CommandsScheduler.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/LoggingCommandHandlerDecorator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/LoggingCommandHandlerWithResultDecorator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Outbox/OutboxModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommandHandler.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/ProcessingModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerDecorator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerWithResultDecorator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/ValidationCommandHandlerDecorator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Quartz/QuartzModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Quartz/QuartzStartup.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Quartz/SerilogLogProvider.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Security/AesDataProtector.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Security/IDataProtector.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Security/SecurityModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/Services/ServicesModule.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/UserAccessCompositionRoot.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/UserAccessConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Configuration/UserAccessStartup.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/ApplicationUserEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/IdentityRoleClaimEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/IdentityUserClaimEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/IdentityUserLoginEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/IdentityUserRoleEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/IdentityUserTokenEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/RoleEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/UserRefreshTokenEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Configuration/UserRegistrationEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Repositories/UserRefreshTokenRepository.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Domain/Repositories/UserRegistrationRepository.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/InternalCommands/InternalCommandEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Outbox/OutboxAccessor.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Outbox/OutboxMessageEntityTypeConfiguration.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Services/IdentityTokenService/CustomClaimTypes.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/Services/IdentityTokenService/IdentityTokenClaimService.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/UserAccessContext.cs
create mode 100644 src/Modules/UserAccessMI/Infrastructure/UserAccessModule.cs
create mode 100644 src/Modules/UserAccessMI/IntegrationEvents/CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents.csproj
create mode 100644 src/Modules/UserAccessMI/IntegrationEvents/NewUserRegisteredIntegrationEvent.cs
diff --git a/.gitignore b/.gitignore
index 0a74300d6..a7f6012f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -275,3 +275,10 @@ UploadedFiles
#Nuke working directory
.nuke-working-directory
/src/API/CompanyName.MyMeetings.API/tempkey.jwk
+
+
+#Ignore appsettings
+**/appsettings.Development.json
+
+# CodeRush personal settings
+**/.cr/personal
diff --git a/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.csproj b/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.csproj
index 340f1f0bf..fda3cf00a 100644
--- a/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.csproj
+++ b/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.csproj
@@ -5,7 +5,15 @@
Linux
..\..
-
-
-
+
+
+ .\CompanyName.MyMeetings.API.xml
+ 1701;1702;1591
+
+
+
+
+
+
+
diff --git a/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.xml b/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.xml
new file mode 100644
index 000000000..0d5dae6ef
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/CompanyName.MyMeetings.API.xml
@@ -0,0 +1,114 @@
+
+
+
+ CompanyName.MyMeetings.API
+
+
+
+
+ Custom base class for API Controllers
+
+ Decorating the controller class with the ApiController attribute unleashes more magic power the framework offers.
+ This automates the model state checks and the model state IsValid property doesn't need to be checked manually.
+ Further more the [FromBody] attribute isn't needed anymore since the controller now automatically infers the binding source for the incoming data.
+
+
+
+
+ User login.
+
+ Authentication attributes.
+ ApiResult.
+
+
+
+ User login.
+
+ User generated token.
+ ApiResult.
+
+
+
+ Send forgot password link.
+
+ Email address of the user.
+ ApiResult.
+
+
+
+ Reset password.
+
+ Reset password attributes.
+ ApiResult.
+
+
+
+ Successful result.
+
+
+
+
+ General error result.
+
+
+
+
+ Not found error result.
+
+
+
+
+ Invalid error result.
+
+
+
+
+ Forbidden error result.
+
+
+
+
+ Convert an Result to a ApiResult.
+
+ The Result to convert.
+ ApiResult.
+
+
+
+ Convert an Result to a ApiResult.
+
+ The value type being returned.
+ The Result to convert.
+ The value being returned.
+ ApiResult.
+
+
+
+ Convert an Result to a ApiResult.
+
+ The value being returned.
+ The Result to convert.
+ ApiResult.
+
+
+
+ Gets the user directory.
+
+ List of users.
+
+
+
+ Get the authenticator key for the current logged in user.
+ Use this key to register an new account in an authenticator app.
+
+ The authenticator key.
+
+
+
+ Enable two-step authentication for the current logged in user by providing the code generated by the authenticator app.
+
+ One-Time Password Code.
+ Result.
+
+
+
diff --git a/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/HasPermissionAuthorizationHandler.cs b/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/HasPermissionAuthorizationHandler.cs
index 82b1de0b3..ed5166636 100644
--- a/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/HasPermissionAuthorizationHandler.cs
+++ b/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/HasPermissionAuthorizationHandler.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using Microsoft.AspNetCore.Authorization;
namespace CompanyName.MyMeetings.API.Configuration.Authorization
diff --git a/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/PermissionAuthorizationHandler.cs b/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/PermissionAuthorizationHandler.cs
new file mode 100644
index 000000000..2a8748193
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Configuration/Authorization/PermissionAuthorizationHandler.cs
@@ -0,0 +1,61 @@
+using CompanyName.MyMeetings.BuildingBlocks.Application;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions.ByUserId;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using Microsoft.AspNetCore.Authorization;
+
+namespace CompanyName.MyMeetings.API.Configuration.Authorization;
+
+internal class PermissionAuthorizationHandler : AttributeAuthorizationHandler
+{
+ private readonly IUserAccessModule _userAccessModule;
+ private readonly IExecutionContextAccessor _executionContextAccessor;
+
+ public PermissionAuthorizationHandler(
+ IUserAccessModule userAccessModule,
+ IExecutionContextAccessor executionContextAccessor)
+ {
+ _userAccessModule = userAccessModule;
+ _executionContextAccessor = executionContextAccessor;
+ }
+
+ protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, HasPermissionAuthorizationRequirement requirement, HasPermissionAttribute attribute)
+ {
+ if (!_executionContextAccessor.IsAuthenticated)
+ {
+ context.Fail();
+ return;
+ }
+
+ var userId = _executionContextAccessor.UserId;
+ var response = await _userAccessModule.ExecuteQueryAsync(new GetPermissionsQuery(userId));
+ if (response.HasError)
+ {
+ context.Fail();
+ return;
+ }
+
+ var permissions = response.Value ?? Enumerable.Empty();
+
+ // Short circuit if the user owns the administrator privilege.
+ if (permissions.Any(x => x.Code.Equals(ApplicationPermissions.Administrator)))
+ {
+ context.Succeed(requirement);
+ return;
+ }
+
+ // Check if the user owns the necessary rights.
+ if (!IsAuthorized(attribute.Name, permissions))
+ {
+ context.Fail();
+ return;
+ }
+
+ context.Succeed(requirement);
+ }
+
+ private bool IsAuthorized(string permission, IEnumerable permissions)
+ {
+ return permissions.Any(x => x.Code == permission);
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Configuration/ExecutionContext/ExecutionContextAccessor.cs b/src/API/CompanyName.MyMeetings.API/Configuration/ExecutionContext/ExecutionContextAccessor.cs
index 207dbdeac..a316800cd 100644
--- a/src/API/CompanyName.MyMeetings.API/Configuration/ExecutionContext/ExecutionContextAccessor.cs
+++ b/src/API/CompanyName.MyMeetings.API/Configuration/ExecutionContext/ExecutionContextAccessor.cs
@@ -15,6 +15,7 @@ public Guid UserId
{
get
{
+ // nameidentifier
if (_httpContextAccessor
.HttpContext?
.User?
@@ -46,5 +47,7 @@ public Guid CorrelationId
}
public bool IsAvailable => _httpContextAccessor.HttpContext != null;
+
+ public bool IsAuthenticated => IsAvailable && (_httpContextAccessor.HttpContext.User.Identity?.IsAuthenticated ?? false);
}
}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/ConfigurationExtensions.cs b/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/ConfigurationExtensions.cs
new file mode 100644
index 000000000..41360fc75
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/ConfigurationExtensions.cs
@@ -0,0 +1,15 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Infrastructure.Configuration;
+
+namespace CompanyName.MyMeetings.API.Configuration.Extensions
+{
+ internal static class ConfigurationExtensions
+ {
+ public static IUserAccessConfiguration GetUserAccessConfiguration(this IConfiguration configuration)
+ {
+ ArgumentNullException.ThrowIfNull(configuration, nameof(configuration));
+
+ var userManagementSection = configuration.GetSection("Modules:UserAccess");
+ return userManagementSection.Get();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/SwaggerExtensions.cs b/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/SwaggerExtensions.cs
index 17dbce681..98a2c39b5 100644
--- a/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/SwaggerExtensions.cs
+++ b/src/API/CompanyName.MyMeetings.API/Configuration/Extensions/SwaggerExtensions.cs
@@ -1,4 +1,5 @@
using System.Reflection;
+using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
namespace CompanyName.MyMeetings.API.Configuration.Extensions
@@ -16,6 +17,22 @@ internal static IServiceCollection AddSwaggerDocumentation(this IServiceCollecti
Description = "MyMeetings API for modular monolith .NET application."
});
options.CustomSchemaIds(t => t.ToString());
+ options.TagActionsBy(api =>
+ {
+ if (api.GroupName != null)
+ {
+ return new[] { api.GroupName };
+ }
+
+ var controllerActionDescriptor = api.ActionDescriptor as ControllerActionDescriptor;
+ if (controllerActionDescriptor != null)
+ {
+ return new[] { controllerActionDescriptor.ControllerName };
+ }
+
+ throw new InvalidOperationException("Unable to determine tag for endpoint.");
+ });
+ options.DocInclusionPredicate((name, api) => true);
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var commentsFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/AuthenticatedUserController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/AuthenticatedUserController.cs
similarity index 69%
rename from src/API/CompanyName.MyMeetings.API/Modules/UserAccess/AuthenticatedUserController.cs
rename to src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/AuthenticatedUserController.cs
index 881cc033b..470c55b1c 100644
--- a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/AuthenticatedUserController.cs
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/AuthenticatedUserController.cs
@@ -1,12 +1,12 @@
using CompanyName.MyMeetings.API.Configuration.Authorization;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetAuthenticatedUserPermissions;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetAuthenticatedUser;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetAuthenticatedUserPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetAuthenticatedUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser;
using Microsoft.AspNetCore.Mvc;
-namespace CompanyName.MyMeetings.API.Modules.UserAccess
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.IdentityServer
{
[Route("api/userAccess/authenticatedUser")]
[ApiController]
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/EmailsController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/EmailsController.cs
similarity index 77%
rename from src/API/CompanyName.MyMeetings.API/Modules/UserAccess/EmailsController.cs
rename to src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/EmailsController.cs
index ee75f4d2d..2d67ba3ad 100644
--- a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/EmailsController.cs
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/EmailsController.cs
@@ -1,10 +1,10 @@
using CompanyName.MyMeetings.API.Configuration.Authorization;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Emails;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Emails;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
-namespace CompanyName.MyMeetings.API.Modules.UserAccess
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.IdentityServer
{
[Route("api/userAccess/emails")]
[ApiController]
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/RegisterNewUserRequest.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/RegisterNewUserRequest.cs
similarity index 81%
rename from src/API/CompanyName.MyMeetings.API/Modules/UserAccess/RegisterNewUserRequest.cs
rename to src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/RegisterNewUserRequest.cs
index 53fd0d6d1..7711e4a71 100644
--- a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/RegisterNewUserRequest.cs
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/RegisterNewUserRequest.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.API.Modules.UserAccess
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.IdentityServer
{
public class RegisterNewUserRequest
{
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/ResourceOwnerPasswordValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/ResourceOwnerPasswordValidator.cs
similarity index 82%
rename from src/API/CompanyName.MyMeetings.API/Modules/UserAccess/ResourceOwnerPasswordValidator.cs
rename to src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/ResourceOwnerPasswordValidator.cs
index 4a5b7a9de..d1b263010 100644
--- a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/ResourceOwnerPasswordValidator.cs
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/ResourceOwnerPasswordValidator.cs
@@ -1,9 +1,9 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication.Authenticate;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using IdentityServer4.Models;
using IdentityServer4.Validation;
-namespace CompanyName.MyMeetings.API.Modules.UserAccess
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.IdentityServer
{
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/UserAccessAutofacModule.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/UserAccessAutofacModule.cs
similarity index 59%
rename from src/API/CompanyName.MyMeetings.API/Modules/UserAccess/UserAccessAutofacModule.cs
rename to src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/UserAccessAutofacModule.cs
index 4f846e7da..54772e839 100644
--- a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/UserAccessAutofacModule.cs
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/UserAccessAutofacModule.cs
@@ -1,8 +1,8 @@
using Autofac;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure;
-namespace CompanyName.MyMeetings.API.Modules.UserAccess
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.IdentityServer
{
public class UserAccessAutofacModule : Module
{
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/UserRegistrationsController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/UserRegistrationsController.cs
similarity index 80%
rename from src/API/CompanyName.MyMeetings.API/Modules/UserAccess/UserRegistrationsController.cs
rename to src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/UserRegistrationsController.cs
index 01d1411c9..550cbaa0f 100644
--- a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/UserRegistrationsController.cs
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/IdentityServer/UserRegistrationsController.cs
@@ -1,11 +1,11 @@
using CompanyName.MyMeetings.API.Configuration.Authorization;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.ConfirmUserRegistration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
-namespace CompanyName.MyMeetings.API.Modules.UserAccess
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.IdentityServer
{
[Route("userAccess/[controller]")]
[ApiController]
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/ApplicationController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/ApplicationController.cs
new file mode 100644
index 000000000..ac50db793
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/ApplicationController.cs
@@ -0,0 +1,55 @@
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using Microsoft.AspNetCore.Mvc;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity;
+
+///
+/// Custom base class for API Controllers
+///
+/// Decorating the controller class with the ApiController attribute unleashes more magic power the framework offers.
+/// This automates the model state checks and the model state IsValid property doesn't need to be checked manually.
+/// Further more the [FromBody] attribute isn't needed anymore since the controller now automatically infers the binding source for the incoming data.
+///
+[ApiController]
+[Route("api/[controller]")]
+public class ApplicationController : ControllerBase
+{
+ protected new IActionResult Ok(object result = null)
+ {
+ return ApiResult.Ok(result);
+ }
+
+ /*
+ protected IActionResult Ok(string successMessage, object result = null)
+ {
+ return ApiResult.Ok(result, successMessage);
+ }
+ */
+
+ protected IActionResult NotFound(Error error, string invalidField = null)
+ {
+ return ApiResult.NotFound(error, invalidField);
+ }
+
+ protected IActionResult Error(Error error, string invalidField = null)
+ {
+ return ApiResult.Error(error, invalidField);
+ }
+
+ protected IActionResult FromResponse(Result response)
+ {
+ return response.ToApiResult();
+ }
+
+ protected IActionResult FromResult(CSharpFunctionalExtensions.Result result)
+ {
+ if (result.IsSuccess)
+ {
+ return Ok();
+ }
+
+ return Error(result.Error);
+ }
+}
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationController.cs
new file mode 100644
index 000000000..ad846a2f3
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationController.cs
@@ -0,0 +1,233 @@
+using System.Security.Claims;
+using CompanyName.MyMeetings.API.Configuration.Authorization;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.BuildingBlocks.Application;
+using CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login.External;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RefreshToken;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RequestForgotPasswordLink;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.ResetPassword;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authentication;
+
+[AllowAnonymous]
+[Route("api/userAccess/authentication")]
+[ApiExplorerSettings(GroupName = "Authentication")]
+public class AuthenticationController : ApplicationController
+{
+ private readonly IUserAccessModule _userAccessModule;
+ private readonly IExecutionContextAccessor _executionContextAccessor;
+
+ public AuthenticationController(IUserAccessModule userAccessModule, IExecutionContextAccessor executionContextAccessor)
+ {
+ _userAccessModule = userAccessModule;
+ _executionContextAccessor = executionContextAccessor;
+ }
+
+ ///
+ /// User login.
+ ///
+ /// Authentication attributes.
+ /// ApiResult.
+ [HttpPost("login")]
+ [NoPermissionRequired]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ public async Task Login(AuthenticationRequest request)
+ {
+ AuthenticationResultDto result = null;
+
+ var response = await _userAccessModule.ExecuteCommandAsync(new AccountLoginCommand(request.UserName, request.Password));
+ if (response != null)
+ {
+ if (response.RequiresTwoFactor)
+ {
+ await HttpContext.SignInAsync(IdentityConstants.TwoFactorUserIdScheme, response.ClaimsPrincipal);
+
+ result = new AuthenticationResultDto()
+ {
+ RequiresTwoFactor = true
+ };
+ }
+ else if (response.IsAuthenticated)
+ {
+ await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, response.ClaimsPrincipal);
+
+ result = new AuthenticationResultDto()
+ {
+ UserName = response.User.UserName,
+ AccessToken = response.AccessToken,
+ RefreshToken = response.RefreshToken
+ };
+ }
+
+ return response.ToApiResult(result);
+ }
+
+ return Error(Errors.General.InvalidRequest());
+ }
+
+ ///
+ /// User login.
+ ///
+ /// User generated token.
+ /// ApiResult.
+ [HttpPost("two-factor-login")]
+ [NoPermissionRequired]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ public async Task TwoFactorLogin(string token)
+ {
+ var result = await HttpContext.AuthenticateAsync(IdentityConstants.TwoFactorUserIdScheme);
+ if (result != null)
+ {
+ if (!result.Succeeded)
+ {
+ return Error(Errors.Authentication.LoginRequestExpired());
+ }
+
+ var response = await _userAccessModule.ExecuteCommandAsync(new AccountTwoFactorLoginCommand(
+ Guid.Parse(result.Principal.FindFirstValue("sub")),
+ result.Principal.FindFirstValue("amr"),
+ token));
+
+ if (response != null)
+ {
+ if (response.IsAuthenticated)
+ {
+ // Clean up the cookie
+ await HttpContext.SignOutAsync(IdentityConstants.TwoFactorUserIdScheme);
+ await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, response.ClaimsPrincipal);
+
+ AuthenticationResultDto authenticationResult = new AuthenticationResultDto()
+ {
+ UserName = response.User.UserName,
+ AccessToken = response.AccessToken,
+ RefreshToken = response.RefreshToken
+ };
+ return Ok(authenticationResult);
+ }
+
+ return Error(Errors.Authentication.InvalidToken());
+ }
+ }
+
+ return Error(Errors.General.InvalidRequest());
+ }
+
+ ///
+ /// Send forgot password link.
+ ///
+ /// Email address of the user.
+ /// ApiResult.
+ [HttpPost("request-forgot-password-link")]
+ [NoPermissionRequired]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ public async Task RequestForgotPasswordLink(string emailAddress)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new RequestForgotPasswordLinkCommand(emailAddress));
+ return response.ToApiResult(response.Token);
+ }
+
+ ///
+ /// Reset password.
+ ///
+ /// Reset password attributes.
+ /// ApiResult.
+ [HttpPost("reset-password")]
+ [NoPermissionRequired]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ public async Task ResetPassword(ResetPasswordRequest resetPassword)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new ResetPasswordCommand(resetPassword.Token, resetPassword.EmailAddress, resetPassword.Password));
+ return response.ToApiResult();
+ }
+
+ [HttpGet("external-login")]
+ [NoPermissionRequired]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public IActionResult ExternalLogin(string provider)
+ {
+ var properties = new AuthenticationProperties
+ {
+ RedirectUri = Url.Action(nameof(ExternalLoginCallback)),
+ Items = { { "scheme", provider } }
+ };
+ return Challenge(properties, provider);
+ }
+
+ [HttpGet("external-login-callback")]
+ [NoPermissionRequired]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ public async Task ExternalLoginCallback()
+ {
+ var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
+ if (result != null)
+ {
+ // We really need the external user identifier
+ var externalUserId = result.Principal.FindFirstValue("sub")
+ ?? result.Principal.FindFirstValue(ClaimTypes.NameIdentifier)
+ ?? throw new Exception("Cannot find external user id");
+
+ // Get the provider from the authentication properties which is available from the scheme item
+ var provider = result.Properties.Items["scheme"];
+
+ var emailAddress = result.Principal.FindFirstValue("email")
+ ?? result.Principal.FindFirstValue(ClaimTypes.Email);
+
+ // Once we have all this we can go ahead an call the external login command
+ var response = await _userAccessModule.ExecuteCommandAsync(new ExternalAccountLoginCommand(provider, externalUserId, emailAddress, false));
+
+ if (response != null)
+ {
+ if (response.IsAuthenticated)
+ {
+ // Clean up the cookie
+ await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
+
+ await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, response.ClaimsPrincipal);
+
+ var authenticationResult = new AuthenticationResultDto()
+ {
+ UserName = response.User.UserName,
+ AccessToken = response.AccessToken,
+ RefreshToken = response.RefreshToken
+ };
+ return response.ToApiResult(authenticationResult);
+ }
+
+ return Error(Errors.Authentication.InvalidToken());
+ }
+ }
+
+ return Error(Errors.General.InvalidRequest());
+ }
+
+ [HttpPost("refresh-token")]
+ [NoPermissionRequired]
+ public async Task RefreshToken(TokenRequest tokenRequest)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new RefreshTokenCommand(tokenRequest.AccessToken, tokenRequest.RefreshToken));
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var tokenResult = new TokenResultDto()
+ {
+ AccessToken = response.Value!.AccessToken,
+ RefreshToken = response.Value!.RefreshToken
+ };
+ return response.ToApiResult(tokenResult);
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationMappingProfile.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationMappingProfile.cs
new file mode 100644
index 000000000..051458d65
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/AuthenticationMappingProfile.cs
@@ -0,0 +1,16 @@
+using AutoMapper;
+using CompanyName.MyMeetings.Contracts.V1.Users.Identity;
+using Application = CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authentication;
+
+internal class AuthenticationMappingProfile : Profile
+{
+ public AuthenticationMappingProfile()
+ {
+ AllowNullCollections = true;
+
+ CreateMap();
+ CreateMap();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/IdentityController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/IdentityController.cs
new file mode 100644
index 000000000..6c365fc31
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/IdentityController.cs
@@ -0,0 +1,61 @@
+using AutoMapper;
+using CompanyName.MyMeetings.API.Configuration.Authorization;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.BuildingBlocks.Application;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Identity.GetUserAccount;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Identity.GetUserPermissions;
+using Microsoft.AspNetCore.Mvc;
+using IdentityContracts = CompanyName.MyMeetings.Contracts.V1.Users.Identity;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authentication;
+
+[Route("api/userAccess/identity")]
+[ApiExplorerSettings(GroupName = "Authenticated User")]
+public class IdentityController : ApplicationController
+{
+ private readonly IMapper _mapper;
+ private readonly IUserAccessModule _userAccessModule;
+ private readonly IExecutionContextAccessor _executionContextAccessor;
+
+ public IdentityController(IUserAccessModule userAccessModule, IExecutionContextAccessor executionContextAccessor, IMapper mapper)
+ {
+ _mapper = mapper;
+ _userAccessModule = userAccessModule;
+ _executionContextAccessor = executionContextAccessor;
+ }
+
+ [HttpGet("user-account")]
+ [HasPermission(UsersPermissions.GetUserAccounts)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ public async Task GetUserAccount()
+ {
+ var result = await _userAccessModule.ExecuteQueryAsync(new GetUserAccountQuery(_executionContextAccessor.UserId));
+ if (result.HasError)
+ {
+ return FromResponse(result);
+ }
+
+ var userAccount = _mapper.Map(result.Value);
+ return result.ToApiResult(userAccount);
+ }
+
+ [HttpGet("permissions")]
+ [HasPermission(UsersPermissions.GetUserAccounts)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ public async Task GetAuthenticatedUserPermissions()
+ {
+ var result = await _userAccessModule.ExecuteQueryAsync(new GetUserPermissionsQuery(_executionContextAccessor.UserId));
+ if (result.HasError)
+ {
+ return FromResponse(result);
+ }
+
+ var permissions = _mapper.Map>(result.Value);
+ return result.ToApiResult(permissions);
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/AuthenticationRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/AuthenticationRequestValidator.cs
new file mode 100644
index 000000000..e21ae38eb
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/AuthenticationRequestValidator.cs
@@ -0,0 +1,14 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authentication.Validators;
+
+internal class AuthenticationRequestValidator : AbstractValidator
+{
+ public AuthenticationRequestValidator()
+ {
+ RuleFor(x => x.UserName).CustomNotEmpty();
+ RuleFor(x => x.Password).CustomNotEmpty();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/ResetPasswordRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/ResetPasswordRequestValidator.cs
new file mode 100644
index 000000000..a96b6946f
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authentication/Validators/ResetPasswordRequestValidator.cs
@@ -0,0 +1,18 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authentication.Validators;
+
+internal class ResetPasswordRequestValidator : AbstractValidator
+{
+ public ResetPasswordRequestValidator()
+ {
+ RuleFor(x => x.Token).CustomNotEmpty();
+ RuleFor(x => x.EmailAddress).CustomEmailAddress();
+ RuleFor(x => x.Password).CustomNotEmpty();
+ RuleFor(x => x.ConfirmPassword).CustomNotEmpty();
+
+ RuleFor(x => x.ConfirmPassword).CustomEqual(x => x.Password);
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationController.cs
new file mode 100644
index 000000000..c0217f2fb
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationController.cs
@@ -0,0 +1,40 @@
+using AutoMapper;
+using CompanyName.MyMeetings.API.Configuration.Authorization;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using Microsoft.AspNetCore.Mvc;
+using AuthorizationApplication = CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions;
+using AuthorizationContracts = CompanyName.MyMeetings.Contracts.V1.Users.Authorization;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authorization;
+
+[Route("api/userAccess/authorization")]
+[ApiExplorerSettings(GroupName = "User Access")]
+public class AuthorizationController : ApplicationController
+{
+ private readonly IMapper _mapper;
+ private readonly IUserAccessModule _userAccessModule;
+
+ public AuthorizationController(IUserAccessModule userAccessModule, IMapper mapper)
+ {
+ _mapper = mapper;
+ _userAccessModule = userAccessModule;
+ }
+
+ [HttpGet("permissions")]
+ [NoPermissionRequired]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ public async Task GetPermissionDirectory()
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new AuthorizationApplication.Directory.GetPermissionsQuery());
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var permissions = _mapper.Map>(response.Value);
+ return response.ToApiResult(permissions);
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationMappingProfile.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationMappingProfile.cs
new file mode 100644
index 000000000..cce6bbd96
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Authorization/AuthorizationMappingProfile.cs
@@ -0,0 +1,15 @@
+using AutoMapper;
+using CompanyName.MyMeetings.Contracts.V1.Users.Authorization;
+using Application = CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Authorization;
+
+public class AuthorizationMappingProfile : Profile
+{
+ public AuthorizationMappingProfile()
+ {
+ AllowNullCollections = true;
+
+ CreateMap();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResult.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResult.cs
new file mode 100644
index 000000000..f532ea07a
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResult.cs
@@ -0,0 +1,110 @@
+using System.Net;
+using CompanyName.MyMeetings.Contracts.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using Microsoft.AspNetCore.Mvc;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+
+public class ApiResult : IActionResult
+{
+ private readonly Result _result;
+ private readonly int _statusCode;
+
+ public ApiResult(Result result, HttpStatusCode statusCode)
+ {
+ _result = result;
+ _statusCode = (int)statusCode;
+ }
+
+ public Guid? CorrelationId { get; set; }
+
+ public ApiResultStatus Status => MapStatus(_statusCode);
+
+ public Task ExecuteResultAsync(ActionContext context)
+ {
+ var objectResult = new ObjectResult(_result)
+ {
+ StatusCode = _statusCode
+ };
+
+ return objectResult.ExecuteResultAsync(context);
+ }
+
+ /*
+ public static ApiResult Ok(string successMessage = null)
+ => new ApiResult(Result.Ok(successMessage), HttpStatusCode.OK);
+ */
+
+ public static ApiResult Ok()
+ => new ApiResult(Result.Ok(), HttpStatusCode.OK);
+
+ public static ApiResult Ok(object result = null)
+ => new ApiResult(Result.Ok(result), HttpStatusCode.OK);
+
+ /*
+ public static ApiResult Ok(object result = null, string successMessage = null)
+ => new ApiResult(Result.Ok(result, successMessage), HttpStatusCode.OK);
+ */
+
+ public static ApiResult Error(Error error, string fieldName = null)
+ => new ApiResult(Result.Error(error.ToErrorMessages(), fieldName), HttpStatusCode.BadRequest);
+
+ public static ApiResult Error()
+ => Error(Errors.General.InvalidRequest());
+
+ public static ApiResult Error(Error error)
+ => Error(new Dictionary>() { { string.Empty, new[] { error } } });
+
+ public static ApiResult Error(IEnumerable errors)
+ => Error(new Dictionary>() { { string.Empty, errors } });
+
+ public static ApiResult Error(IDictionary> errors)
+ => new ApiResult(Result.Error(errors.ToErrorMessages()), HttpStatusCode.BadRequest);
+
+ public static ApiResult NotFound(Error error)
+ => NotFound(new Dictionary>() { { string.Empty, new[] { error } } });
+
+ public static ApiResult NotFound(Error error, string fieldName = null)
+ => NotFound(new Dictionary>() { { fieldName ?? string.Empty, new[] { error } } });
+
+ public static ApiResult NotFound(IEnumerable errors)
+ => NotFound(new Dictionary>() { { string.Empty, errors } });
+
+ public static ApiResult NotFound(IDictionary> errors)
+ => new ApiResult(Result.Error(errors.ToErrorMessages()), HttpStatusCode.NotFound);
+
+ public static ApiResult Forbidden(string errorMessage)
+ => Forbidden(Errors.Authentication.NotAuthorized(errorMessage));
+
+ public static ApiResult Forbidden(Error error)
+ => Forbidden(new Dictionary>() { { string.Empty, new[] { error } } });
+
+ public static ApiResult Forbidden(IEnumerable errors)
+ => Forbidden(new Dictionary>() { { string.Empty, errors } });
+
+ public static ApiResult Forbidden(IDictionary> errors)
+ => new ApiResult(Result.Error(errors.ToErrorMessages()), HttpStatusCode.Forbidden);
+
+ private ApiResultStatus MapStatus(int status)
+ {
+ switch (status)
+ {
+ case (int)HttpStatusCode.InternalServerError:
+ return ApiResultStatus.Error;
+
+ case (int)HttpStatusCode.Forbidden:
+ return ApiResultStatus.Forbidden;
+
+ case (int)HttpStatusCode.BadRequest:
+ return ApiResultStatus.Invalid;
+
+ case (int)HttpStatusCode.NotFound:
+ return ApiResultStatus.NotFound;
+
+ case (int)HttpStatusCode.OK:
+ return ApiResultStatus.Ok;
+ }
+
+ return ApiResultStatus.Error;
+ }
+}
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResultStatus.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResultStatus.cs
new file mode 100644
index 000000000..487edb9d6
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ApiResultStatus.cs
@@ -0,0 +1,29 @@
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+
+public enum ApiResultStatus
+{
+ ///
+ /// Successful result.
+ ///
+ Ok,
+
+ ///
+ /// General error result.
+ ///
+ Error,
+
+ ///
+ /// Not found error result.
+ ///
+ NotFound,
+
+ ///
+ /// Invalid error result.
+ ///
+ Invalid,
+
+ ///
+ /// Forbidden error result.
+ ///
+ Forbidden
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ErrorMapper.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ErrorMapper.cs
new file mode 100644
index 000000000..f0a70891f
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ErrorMapper.cs
@@ -0,0 +1,64 @@
+using CompanyName.MyMeetings.Contracts.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+
+internal static class ErrorMapper
+{
+ public static IDictionary> ToErrorMessages(this IDictionary> errors)
+ {
+ var errorMessages = new Dictionary>();
+ foreach (var keyValue in errors)
+ {
+ errorMessages.Add(keyValue.Key, keyValue.Value.ToErrorMessages());
+ }
+
+ return errorMessages;
+ }
+
+ public static IEnumerable ToErrorMessages(this IEnumerable errors)
+ {
+ var errorMessages = new List();
+ foreach (var error in errors)
+ {
+ errorMessages.AddRange(error.ToErrorMessages());
+ }
+
+ return errorMessages;
+ }
+
+ public static IEnumerable ToErrorMessages(this Error error, List errorMessages = null)
+ {
+ if (error is null)
+ {
+ throw new ArgumentNullException(nameof(error));
+ }
+
+ errorMessages ??= new List();
+
+ if (!string.IsNullOrEmpty(error.Code + error.Message))
+ {
+ errorMessages.Add(error.ToErrorMessage());
+ }
+
+ if (error.Errors is not null)
+ {
+ foreach (var subError in error.Errors)
+ {
+ subError.ToErrorMessages(errorMessages);
+ }
+ }
+
+ return errorMessages;
+ }
+
+ private static ErrorMessage ToErrorMessage(this Error error)
+ {
+ if (error is null)
+ {
+ throw new ArgumentNullException(nameof(error));
+ }
+
+ return new ErrorMessage(error.Code, error.Message);
+ }
+}
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ResultExtensions.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ResultExtensions.cs
new file mode 100644
index 000000000..07d9f6011
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Results/ResultExtensions.cs
@@ -0,0 +1,141 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+
+internal static class ResultExtensions
+{
+ ///
+ /// Convert an Result to a ApiResult.
+ ///
+ /// The Result to convert.
+ /// ApiResult.
+ public static ApiResult ToApiResult(this MyMeetings.Modules.UserAccessMI.Application.Configuration.Results.IResult result)
+ {
+ if (result == null)
+ {
+ return ApiResult.Error();
+ }
+
+ // Create the result
+ ApiResult apiResult = null;
+
+ // Translate the response
+ if (result.Status == ResultStatus.Forbidden)
+ {
+ apiResult = ApiResult.Forbidden("Not authorized.");
+ }
+
+ if (result.Status == ResultStatus.NotFound)
+ {
+ apiResult = ApiResult.NotFound(result.Errors);
+ }
+
+ if (result.Status == ResultStatus.Error)
+ {
+ apiResult = ApiResult.Error(result.Errors);
+ }
+
+ if (result.Status == ResultStatus.Ok)
+ {
+ apiResult = ApiResult.Ok();
+ }
+
+ if (apiResult is null)
+ {
+ throw new InvalidOperationException($"The Result with status '{result.Status}' cannot be translated to an equivalent ApiResult.");
+ }
+
+ return apiResult;
+ }
+
+ ///
+ /// Convert an Result to a ApiResult.
+ ///
+ /// The value type being returned.
+ /// The Result to convert.
+ /// The value being returned.
+ /// ApiResult.
+ public static ApiResult ToApiResult(this MyMeetings.Modules.UserAccessMI.Application.Configuration.Results.IResult result, T value)
+ {
+ if (result == null)
+ {
+ return ApiResult.Error();
+ }
+
+ // Create the result
+ ApiResult apiResult = null;
+
+ // Translate the response
+ if (result.Status == ResultStatus.Forbidden)
+ {
+ apiResult = ApiResult.Forbidden("Not authorized.");
+ }
+
+ if (result.Status == ResultStatus.NotFound)
+ {
+ apiResult = ApiResult.NotFound(result.Errors);
+ }
+
+ if (result.Status == ResultStatus.Error)
+ {
+ apiResult = ApiResult.Error(result.Errors);
+ }
+
+ if (result.Status == ResultStatus.Ok)
+ {
+ apiResult = ApiResult.Ok(value);
+ }
+
+ if (apiResult is null)
+ {
+ throw new InvalidOperationException($"The Result with status '{result.Status}' cannot be translated to an equivalent ApiResult.");
+ }
+
+ return apiResult;
+ }
+
+ ///
+ /// Convert an Result to a ApiResult.
+ ///
+ /// The value being returned.
+ /// The Result to convert.
+ /// ApiResult.
+ public static ApiResult ToApiResult(this IResult result)
+ {
+ if (result == null)
+ {
+ return ApiResult.Error();
+ }
+
+ // Create the result
+ ApiResult apiResult = null;
+
+ // Translate the response
+ if (result.Status == ResultStatus.Forbidden)
+ {
+ apiResult = ApiResult.Forbidden("Not authorized.");
+ }
+
+ if (result.Status == ResultStatus.NotFound)
+ {
+ apiResult = ApiResult.NotFound(result.Errors);
+ }
+
+ if (result.Status == ResultStatus.Error)
+ {
+ apiResult = ApiResult.Error(result.Errors);
+ }
+
+ if (result.Status == ResultStatus.Ok)
+ {
+ apiResult = ApiResult.Ok(result.Value);
+ }
+
+ if (apiResult is null)
+ {
+ throw new InvalidOperationException($"The Result with status '{result.Status}' cannot be translated to an equivalent ApiResult.");
+ }
+
+ return apiResult;
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RoleMappingProfile.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RoleMappingProfile.cs
new file mode 100644
index 000000000..54d37038e
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RoleMappingProfile.cs
@@ -0,0 +1,16 @@
+using AutoMapper;
+using CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+using Application = CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Roles;
+
+internal class RoleMappingProfile : Profile
+{
+ public RoleMappingProfile()
+ {
+ AllowNullCollections = true;
+
+ CreateMap();
+ CreateMap();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RolesController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RolesController.cs
new file mode 100644
index 000000000..02bce7a3f
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/RolesController.cs
@@ -0,0 +1,130 @@
+using AutoMapper;
+using CompanyName.MyMeetings.API.Configuration.Authorization;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Roles.CreateRole;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Roles.DeleteRole;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Roles.GetRolePermissions;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Roles.RenameRole;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Roles.SetRolePermissions;
+using Microsoft.AspNetCore.Mvc;
+using RolesApplication = CompanyName.MyMeetings.Modules.UserAccessMI.Application.Roles.GetRoles;
+using UserRoleContracts = CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Roles;
+
+[Route("api/userAccess/roles")]
+[ApiExplorerSettings(GroupName = "User Access")]
+public class RolesController : ApplicationController
+{
+ private readonly IMapper _mapper;
+ private readonly IUserAccessModule _userAccessModule;
+
+ public RolesController(IUserAccessModule userAccessModule, IMapper mapper)
+ {
+ _mapper = mapper;
+ _userAccessModule = userAccessModule;
+ }
+
+ [HttpGet]
+ [HasPermission(UsersPermissions.GetRoles)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetRoleDirectory()
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new RolesApplication.Directory.GetRolesQuery());
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var userRoles = _mapper.Map>(response.Value);
+ return response.ToApiResult(userRoles);
+ }
+
+ [HttpGet("{roleId}")]
+ [HasPermission(UsersPermissions.GetRoles)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetRole(Guid roleId)
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new RolesApplication.ById.GetRolesQuery(roleId));
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var userRoles = _mapper.Map(response.Value);
+ return response.ToApiResult(userRoles);
+ }
+
+ [HttpPost]
+ [HasPermission(UsersPermissions.AddRole)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task AddRole([FromBody] UserRoleContracts.AddRoleRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new CreateRoleCommand(request.Name, request.Permissions));
+ return response.ToApiResult();
+ }
+
+ [HttpPatch("{roleId}/rename")]
+ [HasPermission(UsersPermissions.RenameRole)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task RenameRole(Guid roleId, [FromBody] UserRoleContracts.RenameRoleRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new RenameRoleCommand(roleId, request.Name));
+ return response.ToApiResult();
+ }
+
+ [HttpDelete("{roleId}")]
+ [HasPermission(UsersPermissions.DeleteRole)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task DeleteRole(Guid roleId)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new DeleteRoleCommand(roleId));
+ return response.ToApiResult();
+ }
+
+ [HttpGet("{roleId}/permissions")]
+ [HasPermission(UsersPermissions.GetRolePermissions)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetRolePermissions(Guid roleId)
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new GetRolePermissionsQuery(roleId));
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var permissions = _mapper.Map>(response.Value);
+ return response.ToApiResult(permissions);
+ }
+
+ [HttpPatch("{roleId}/permissions")]
+ [HasPermission(UsersPermissions.SetRolePermissions)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task SetRolePermissions(Guid roleId, [FromBody] UserRoleContracts.SetRolePermissionsRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new SetRolePermissionsCommand(roleId, request.Permissions));
+ return response.ToApiResult();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/AddRoleRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/AddRoleRequestValidator.cs
new file mode 100644
index 000000000..3e3c1a955
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/AddRoleRequestValidator.cs
@@ -0,0 +1,14 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Roles.Validators;
+
+internal class AddRoleRequestValidator : AbstractValidator
+{
+ public AddRoleRequestValidator()
+ {
+ RuleFor(x => x.Name).CustomNotEmpty();
+ RuleFor(x => x.Permissions).CustomNotEmpty();
+ }
+}
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/RenameRoleRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/RenameRoleRequestValidator.cs
new file mode 100644
index 000000000..153f6c742
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/RenameRoleRequestValidator.cs
@@ -0,0 +1,13 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Roles.Validators;
+
+internal class RenameRoleRequestValidator : AbstractValidator
+{
+ public RenameRoleRequestValidator()
+ {
+ RuleFor(x => x.Name).CustomNotEmpty();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/SetRolePermissionsRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/SetRolePermissionsRequestValidator.cs
new file mode 100644
index 000000000..98b06e4b3
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Roles/Validators/SetRolePermissionsRequestValidator.cs
@@ -0,0 +1,13 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Roles.Validators;
+
+internal class SetRolePermissionsRequestValidator : AbstractValidator
+{
+ public SetRolePermissionsRequestValidator()
+ {
+ RuleFor(x => x.Permissions).CustomNotEmpty();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UserAccessAutofacModule.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UserAccessAutofacModule.cs
new file mode 100644
index 000000000..30bd78f23
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UserAccessAutofacModule.cs
@@ -0,0 +1,16 @@
+using Autofac;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Infrastructure;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity
+{
+ public class UserAccessAutofacModule : Module
+ {
+ protected override void Load(ContainerBuilder builder)
+ {
+ builder.RegisterType()
+ .As()
+ .InstancePerLifetimeScope();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserMappingProfile.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserMappingProfile.cs
new file mode 100644
index 000000000..fa824aedf
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserMappingProfile.cs
@@ -0,0 +1,18 @@
+using AutoMapper;
+using CompanyName.MyMeetings.Contracts.V1.Users.Users;
+using Application = CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users;
+
+internal class UserMappingProfile : Profile
+{
+ public UserMappingProfile()
+ {
+ AllowNullCollections = true;
+
+ CreateMap();
+
+ CreateMap();
+ CreateMap();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserRegistrationsController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserRegistrationsController.cs
new file mode 100644
index 000000000..02e48b5a7
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UserRegistrationsController.cs
@@ -0,0 +1,49 @@
+using CompanyName.MyMeetings.API.Configuration.Authorization;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.Contracts.V1.Users.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserRegistrations.ConfirmUserRegistration;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserRegistrations.RegisterNewUser;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users;
+
+[Route("userAccess/[controller]")]
+[ApiExplorerSettings(GroupName = "User Access")]
+public class UserRegistrationsController : ApplicationController
+{
+ private readonly IUserAccessModule _userAccessModule;
+
+ public UserRegistrationsController(IUserAccessModule userAccessModule)
+ {
+ _userAccessModule = userAccessModule;
+ }
+
+ [NoPermissionRequired]
+ [AllowAnonymous]
+ [HttpPost("")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public async Task RegisterNewUser(RegisterNewUserRequest request)
+ {
+ var result = await _userAccessModule.ExecuteCommandAsync(new RegisterNewUserCommand(
+ request.Login,
+ request.Password,
+ request.Email,
+ request.FirstName,
+ request.LastName,
+ request.ConfirmLink));
+
+ return result.ToApiResult();
+ }
+
+ [NoPermissionRequired]
+ [AllowAnonymous]
+ [HttpPatch("{userRegistrationId}/confirm")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public async Task ConfirmRegistration(Guid userRegistrationId)
+ {
+ var result = await _userAccessModule.ExecuteCommandAsync(new ConfirmUserRegistrationCommand(userRegistrationId));
+ return result.ToApiResult();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UsersController.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UsersController.cs
new file mode 100644
index 000000000..c2810cf5c
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/UsersController.cs
@@ -0,0 +1,221 @@
+using AutoMapper;
+using CompanyName.MyMeetings.API.Configuration.Authorization;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
+using CompanyName.MyMeetings.BuildingBlocks.Application;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions.ByUserId;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetUserRoles;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.AuthenticatorRegistration.GetAuthenticatorKey;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.AuthenticatorRegistration.RegisterAuthenticator;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.ConfirmEmailAddress;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.CreateUserAccount;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.SetUserPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.SetUserRoles;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.UnlockUserAccount;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.UpdateUserAccount;
+using Microsoft.AspNetCore.Mvc;
+using UserContracts = CompanyName.MyMeetings.Contracts.V1.Users.Users;
+using UsersApplication = CompanyName.MyMeetings.Modules.UserAccessMI.Application.UserAccounts.GetUserAccounts;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users;
+
+[Route("api/userAccess/Users")]
+[ApiExplorerSettings(GroupName = "User Access")]
+public class UsersController : ApplicationController
+{
+ private readonly IMapper _mapper;
+ private readonly IUserAccessModule _userAccessModule;
+ private readonly IExecutionContextAccessor _executionContextAccessor;
+
+ public UsersController(IUserAccessModule userAccessModule, IExecutionContextAccessor executionContextAccessor, IMapper mapper)
+ {
+ _mapper = mapper;
+ _userAccessModule = userAccessModule;
+ _executionContextAccessor = executionContextAccessor;
+ }
+
+ ///
+ /// Gets the user directory.
+ ///
+ /// List of users.
+ [HttpGet]
+ [HasPermission(UsersPermissions.GetUsers)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetUserAccountDirectory()
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new UsersApplication.Directory.GetUserAccountsQuery());
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var users = _mapper.Map>(response.Value);
+ return response.ToApiResult(users);
+ }
+
+ [HttpGet("{userId}")]
+ [HasPermission(UsersPermissions.GetUsers)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetUserAccount(Guid userId)
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new UsersApplication.ById.GetUserAccountsQuery(userId));
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var user = _mapper.Map(response.Value);
+ return response.ToApiResult(user);
+ }
+
+ [HttpPost]
+ [HasPermission(UsersPermissions.CreateUserAccount)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task CreateUserAccount(UserContracts.CreateUserAccountRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(
+ new CreateUserAccountCommand(
+ request.UserName, request.Password, request.Name, request.FirstName, request.LastName, request.EmailAddress));
+
+ return response.ToApiResult();
+ }
+
+ [HttpPut("{userId}")]
+ [HasPermission(UsersPermissions.UpdateUserAccount)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task UpdateUserAccount(Guid userId, UserContracts.UpdateUserAccountRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new UpdateUserAccountCommand(userId, request.Name, request.FirstName, request.LastName));
+ return response.ToApiResult();
+ }
+
+ [HttpPatch("{userId}/unlock")]
+ [HasPermission(UsersPermissions.UnlockUserAccount)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task UnlockUserAccount(Guid userId)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new UnlockUserAccountCommand(userId));
+ return response.ToApiResult();
+ }
+
+ [HttpPost("confirm-email-address")]
+ [HasPermission(UsersPermissions.ConfirmEmailAddress)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task ConfirmEmailAddress(UserContracts.ConfirmEmailAddressRequest confirmEmailAddress)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new ConfirmEmailAddressCommand(confirmEmailAddress.EmailAddress, confirmEmailAddress.Token));
+ return response.ToApiResult();
+ }
+
+ ///
+ /// Get the authenticator key for the current logged in user.
+ /// Use this key to register an new account in an authenticator app.
+ ///
+ /// The authenticator key.
+ [HttpGet("authenticator-key")]
+ [HasPermission(UsersPermissions.GetAuthenticatorKey)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetAuthenticatorKey()
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new GetAuthenticatorKeyQuery(_executionContextAccessor.UserId));
+ return response.ToApiResult();
+ }
+
+ ///
+ /// Enable two-step authentication for the current logged in user by providing the code generated by the authenticator app.
+ ///
+ /// One-Time Password Code.
+ /// Result.
+ [HttpPost("register-authenticator")]
+ [HasPermission(UsersPermissions.RegisterAuthenticator)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task RegisterAuthenticator(string otpCode)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new RegisterAuthenticatorCommand(_executionContextAccessor.UserId, otpCode));
+ return response.ToApiResult();
+ }
+
+ [HttpGet("{userId}/roles")]
+ [HasPermission(UsersPermissions.GetUserRoles)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetUserRoles(Guid userId)
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new GetUserRolesQuery(userId));
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var roles = _mapper.Map>(response.Value);
+ return response.ToApiResult(roles);
+ }
+
+ [HttpPatch("{userId}/roles")]
+ [HasPermission(UsersPermissions.SetUserRoles)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task SetUserRoles(Guid userId, UserContracts.SetUserRolesRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new SetUserRolesCommand(userId, request.RoleIds));
+ return response.ToApiResult();
+ }
+
+ [HttpGet("{userId}/permissions")]
+ [HasPermission(UsersPermissions.GetUserPermissions)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task GetUserPermissions(Guid userId)
+ {
+ var response = await _userAccessModule.ExecuteQueryAsync(new GetPermissionsQuery(userId));
+ if (response.HasError)
+ {
+ return FromResponse(response);
+ }
+
+ var permissions = _mapper.Map>(response.Value);
+ return response.ToApiResult(permissions);
+ }
+
+ [HttpPatch("{userId}/permissions")]
+ [HasPermission(UsersPermissions.SetUserPermissions)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(ApiResult), StatusCodes.Status403Forbidden)]
+ public async Task SetUserPermissions(Guid userId, [FromBody] UserContracts.SetUserPermissionsRequest request)
+ {
+ var response = await _userAccessModule.ExecuteCommandAsync(new SetUserPermissionsCommand(userId, request.Permissions));
+ return response.ToApiResult();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/ConfirmEmailAddressRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/ConfirmEmailAddressRequestValidator.cs
new file mode 100644
index 000000000..51e05e4fe
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/ConfirmEmailAddressRequestValidator.cs
@@ -0,0 +1,14 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Users;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users.Validators;
+
+internal class ConfirmEmailAddressRequestValidator : AbstractValidator
+{
+ public ConfirmEmailAddressRequestValidator()
+ {
+ RuleFor(x => x.Token).CustomNotEmpty();
+ RuleFor(x => x.EmailAddress).CustomEmailAddress();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/CreateUserAccountRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/CreateUserAccountRequestValidator.cs
new file mode 100644
index 000000000..acf381824
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/CreateUserAccountRequestValidator.cs
@@ -0,0 +1,14 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Users;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users.Validators;
+
+internal class CreateUserAccountRequestValidator : AbstractValidator
+{
+ public CreateUserAccountRequestValidator()
+ {
+ RuleFor(x => x.UserName).CustomNotEmpty();
+ RuleFor(x => x.EmailAddress).CustomEmailAddress();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserPermissionsRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserPermissionsRequestValidator.cs
new file mode 100644
index 000000000..0bf60337d
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserPermissionsRequestValidator.cs
@@ -0,0 +1,13 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Users;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users.Validators;
+
+internal class SetUserPermissionsRequestValidator : AbstractValidator
+{
+ public SetUserPermissionsRequestValidator()
+ {
+ RuleFor(x => x.Permissions).CustomNotNull();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserRolesRequestValidator.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserRolesRequestValidator.cs
new file mode 100644
index 000000000..46bc3ede7
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/Users/Validators/SetUserRolesRequestValidator.cs
@@ -0,0 +1,13 @@
+using CompanyName.MyMeetings.Contracts.V1.Users.Users;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application;
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Users.Validators;
+
+internal class SetUserRolesRequestValidator : AbstractValidator
+{
+ public SetUserRolesRequestValidator()
+ {
+ RuleFor(x => x.RoleIds).CustomNotNull();
+ }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UsersPermissions.cs b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UsersPermissions.cs
new file mode 100644
index 000000000..39a15eb76
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.API/Modules/UserAccess/MicrosoftIdentity/UsersPermissions.cs
@@ -0,0 +1,28 @@
+namespace CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity;
+
+internal class UsersPermissions
+{
+ // Identity
+ public const string GetUserAccounts = "Users.GetUserAccounts";
+
+ // Users
+ public const string GetUsers = "Users.GetUsers";
+ public const string CreateUserAccount = "Users.CreateUserAccount";
+ public const string UpdateUserAccount = "Users.UpdateUserAccount";
+ public const string UnlockUserAccount = "Users.UnlockUserAccount";
+ public const string ConfirmEmailAddress = "Users.ConfirmEmailAddress";
+ public const string GetAuthenticatorKey = "Users.GetAuthenticatorKey";
+ public const string RegisterAuthenticator = "Users.RegisterAuthenticator";
+ public const string GetUserRoles = "Users.GetUserRoles";
+ public const string SetUserRoles = "Users.SetUserRoles";
+ public const string GetUserPermissions = "Users.GetUserPermissions";
+ public const string SetUserPermissions = "Users.SetUserPermissions";
+
+ // Roles
+ public const string GetRoles = "Users.GetRoles";
+ public const string AddRole = "Users.AddRole";
+ public const string RenameRole = "Users.RenameRole";
+ public const string DeleteRole = "Users.DeleteRole";
+ public const string GetRolePermissions = "Users.GetRolePermissions";
+ public const string SetRolePermissions = "Users.SetRolePermissions";
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.API/Startup.cs b/src/API/CompanyName.MyMeetings.API/Startup.cs
index c514e745d..5a0f154a2 100644
--- a/src/API/CompanyName.MyMeetings.API/Startup.cs
+++ b/src/API/CompanyName.MyMeetings.API/Startup.cs
@@ -1,4 +1,7 @@
-using Autofac;
+using System.IdentityModel.Tokens.Jwt;
+using System.Reflection;
+using System.Text.Json;
+using Autofac;
using Autofac.Extensions.DependencyInjection;
using CompanyName.MyMeetings.API.Configuration.Authorization;
using CompanyName.MyMeetings.API.Configuration.ExecutionContext;
@@ -7,22 +10,29 @@
using CompanyName.MyMeetings.API.Modules.Administration;
using CompanyName.MyMeetings.API.Modules.Meetings;
using CompanyName.MyMeetings.API.Modules.Payments;
-using CompanyName.MyMeetings.API.Modules.UserAccess;
+using CompanyName.MyMeetings.API.Modules.UserAccess.MicrosoftIdentity.Results;
using CompanyName.MyMeetings.BuildingBlocks.Application;
using CompanyName.MyMeetings.BuildingBlocks.Domain;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.Emails;
+using CompanyName.MyMeetings.Contracts.Results;
using CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration;
using CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration;
using CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.IdentityServer;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.IdentityServer;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Infrastructure.Configuration;
using Hellang.Middleware.ProblemDetails;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Validation;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.IdentityModel.Tokens;
using Serilog;
using Serilog.Formatting.Compact;
using ILogger = Serilog.ILogger;
+using UserAccess = CompanyName.MyMeetings.API.Modules.UserAccess;
+using UserAccessISConfiguration = CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration;
namespace CompanyName.MyMeetings.API
{
@@ -44,7 +54,7 @@ public Startup(IWebHostEnvironment env)
.AddEnvironmentVariables("Meetings_")
.Build();
- _loggerForApi.Information("Connection string:" + _configuration[MeetingsConnectionString]);
+ _loggerForApi.Information("Connection string:" + _configuration["ConnectionStrings:" + MeetingsConnectionString]);
AuthorizationChecker.CheckAllEndpoints();
}
@@ -55,11 +65,73 @@ public void ConfigureServices(IServiceCollection services)
services.AddSwaggerDocumentation();
- ConfigureIdentityServer(services);
-
+ // ConfigureIdentityServer(services);
services.AddSingleton();
services.AddSingleton();
+ services.AddAuthentication()
+ .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, config =>
+ {
+ config.RequireHttpsMetadata = false;
+ config.SaveToken = true;
+
+ var userAccessConfiguration = _configuration.GetUserAccessConfiguration();
+ config.TokenValidationParameters = new TokenValidationParameters
+ {
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = userAccessConfiguration.GetIssuerSigningKey(),
+ ValidIssuer = userAccessConfiguration.GetValidIssuer(),
+ ValidateIssuer = userAccessConfiguration.ShouldValidateIssuer(),
+ ValidAudience = userAccessConfiguration.GetValidAudience(),
+ ValidateAudience = userAccessConfiguration.ShouldValidateAudience(),
+ ValidateLifetime = true,
+ RequireExpirationTime = true,
+
+ // Clock skew compensates for server time drift.
+ ClockSkew = TimeSpan.FromMinutes(5)
+ };
+
+ config.Events = new JwtBearerEvents
+ {
+ OnChallenge = context =>
+ {
+ context.Response.ContentType = "application/json";
+ context.Response.OnStarting(() =>
+ {
+ var error = Errors.Authentication.NotAuthorized();
+ string result = JsonSerializer.Serialize(Result.Error(error.ToErrorMessages()));
+ return context.Response.WriteAsync(result);
+ });
+ return Task.CompletedTask;
+ },
+ OnTokenValidated = context =>
+ {
+ return Task.CompletedTask;
+ },
+ OnAuthenticationFailed = context =>
+ {
+ if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
+ {
+ context.Response.Headers.Append("Token-Expired", "true");
+ }
+
+ return Task.CompletedTask;
+ }
+ };
+ })
+ .AddCookie(IdentityConstants.ApplicationScheme)
+ .AddCookie(IdentityConstants.TwoFactorUserIdScheme);
+ /*
+ Add additional external authentication providers (don't forget to reference the required packages)
+ Package: Microsoft.AspNetCore.Authentication.Google
+ Google portal (APIs und Services) for configuration: https://console.cloud.google.com/apis/library
+ .AddGoogle(googleOptions =>
+ {
+ googleOptions.ClientId = configuration["Authentication:Google:ClientId"];
+ googleOptions.ClientSecret = configuration["Authentication:Google:ClientSecret"];
+ });
+ */
+
services.AddProblemDetails(x =>
{
x.Map(ex => new InvalidCommandProblemDetails(ex));
@@ -75,15 +147,18 @@ public void ConfigureServices(IServiceCollection services)
});
});
- services.AddScoped();
+ // services.AddScoped();
+ services.AddScoped();
+ services.AddAutoMapper(Assembly.GetExecutingAssembly());
}
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule(new MeetingsAutofacModule());
containerBuilder.RegisterModule(new AdministrationAutofacModule());
- containerBuilder.RegisterModule(new UserAccessAutofacModule());
+ containerBuilder.RegisterModule(new UserAccess.IdentityServer.UserAccessAutofacModule());
containerBuilder.RegisterModule(new PaymentsAutofacModule());
+ containerBuilder.RegisterModule(new UserAccess.MicrosoftIdentity.UserAccessAutofacModule());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -100,8 +175,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IService
app.UseSwaggerDocumentation();
- app.UseIdentityServer();
-
+ // app.UseIdentityServer();
if (env.IsDevelopment())
{
app.UseProblemDetails();
@@ -116,6 +190,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IService
app.UseRouting();
+ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
+
// app.UseAuthentication();
app.UseAuthorization();
@@ -148,7 +224,7 @@ private void ConfigureIdentityServer(IServiceCollection services)
.AddProfileService()
.AddDeveloperSigningCredential();
- services.AddTransient();
+ services.AddTransient();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, x =>
@@ -165,31 +241,33 @@ private void InitializeModules(ILifetimeScope container)
var executionContextAccessor = new ExecutionContextAccessor(httpContextAccessor);
var emailsConfiguration = new EmailsConfiguration(_configuration["EmailsConfiguration:FromEmail"]);
+ var userAccessConfiguration = _configuration.GetUserAccessConfiguration();
MeetingsStartup.Initialize(
- _configuration[MeetingsConnectionString],
+ _configuration["ConnectionStrings:" + MeetingsConnectionString],
executionContextAccessor,
_logger,
emailsConfiguration,
null);
AdministrationStartup.Initialize(
- _configuration[MeetingsConnectionString],
+ _configuration["ConnectionStrings:" + MeetingsConnectionString],
executionContextAccessor,
_logger,
null);
UserAccessStartup.Initialize(
- _configuration[MeetingsConnectionString],
+ _configuration["ConnectionStrings:" + MeetingsConnectionString],
executionContextAccessor,
_logger,
emailsConfiguration,
_configuration["Security:TextEncryptionKey"],
null,
- null);
+ null,
+ userAccessConfiguration);
PaymentsStartup.Initialize(
- _configuration[MeetingsConnectionString],
+ _configuration["ConnectionStrings:" + MeetingsConnectionString],
executionContextAccessor,
_logger,
emailsConfiguration,
diff --git a/src/API/CompanyName.MyMeetings.API/appsettings.json b/src/API/CompanyName.MyMeetings.API/appsettings.json
index 8b580c672..185f35b43 100644
--- a/src/API/CompanyName.MyMeetings.API/appsettings.json
+++ b/src/API/CompanyName.MyMeetings.API/appsettings.json
@@ -1,19 +1,38 @@
{
- "Logging": {
- "LogLevel": {
- "Default": "Trace",
- "System": "Information",
- "Microsoft": "None"
- }
+ "Logging": {
+ "LogLevel": {
+ "Default": "Trace",
+ "System": "Information",
+ "Microsoft": "None"
+ }
+
+ },
+ "AllowedHosts": "*",
+
+ "EmailsConfiguration": {
+ "FromEmail": "no-reply@mymeetings.com"
+ },
+ "Security": {
+ /* NOTE! This is sensitive data and should be stored in secure way (not here). Added only for demo purpose. */
+ "TextEncryptionKey": "E546C8DF278CK5990069B522"
+ },
+
+ "ConnectionStrings": {
+ "MeetingsConnectionString": ""
+ },
- },
- "AllowedHosts": "*",
+ "Modules": {
- "EmailsConfiguration": {
- "FromEmail": "no-reply@mymeetings.com"
- },
- "Security": {
- /* NOTE! This is sensitive data and should be stored in secure way (not here). Added only for demo purpose. */
- "TextEncryptionKey": "E546C8DF278CK5990069B522"
+ "UserAccess": {
+ "Security": {
+ /*
+ NOTE! This is sensitive data and should be stored in secure way (not here). Added only for demo purpose.
+ TODO: Generate new key (helper: https://www.browserling.com/tools/random-string)
+ */
+ "JwtSecretKey": "eiURlJpBCvFkZXzQrWKVhAWhHcbfefCPcqUrrbKOTDrkJOxLEOjuAmKiRMcKNKC",
+ "JwtIssuer": "api://mymeetings.com/api",
+ "JwtAudience": "api://mymeetings.com/api"
+ }
}
+ }
}
diff --git a/src/API/CompanyName.MyMeetings.Contracts/CompanyName.MyMeetings.Contracts.csproj b/src/API/CompanyName.MyMeetings.Contracts/CompanyName.MyMeetings.Contracts.csproj
new file mode 100644
index 000000000..fa71b7ae6
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/CompanyName.MyMeetings.Contracts.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/src/API/CompanyName.MyMeetings.Contracts/Results/ErrorMessage.cs b/src/API/CompanyName.MyMeetings.Contracts/Results/ErrorMessage.cs
new file mode 100644
index 000000000..0c86d81e0
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/Results/ErrorMessage.cs
@@ -0,0 +1,14 @@
+namespace CompanyName.MyMeetings.Contracts.Results;
+
+public struct ErrorMessage
+{
+ public ErrorMessage(string code, string? message)
+ {
+ Code = code;
+ Message = message;
+ }
+
+ public string Code { get; set; }
+
+ public string? Message { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/Results/Result.cs b/src/API/CompanyName.MyMeetings.Contracts/Results/Result.cs
new file mode 100644
index 000000000..0cf77273f
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/Results/Result.cs
@@ -0,0 +1,48 @@
+namespace CompanyName.MyMeetings.Contracts.Results;
+
+public class Result
+{
+ public object? Value { get; set; }
+
+ public DateTime TimeGenerated { get; set; }
+
+ public IDictionary>? Errors { get; set; }
+
+ public Result()
+ {
+ }
+
+ internal Result(object? value, IDictionary>? errors)
+ {
+ Value = value;
+ Errors = errors;
+ TimeGenerated = DateTime.UtcNow;
+ }
+
+ public static Result Ok()
+ => Ok(null);
+
+ public static Result Ok(object? value)
+ => new Result(value, null);
+
+ public static Result Error(ErrorMessage error, string? invalidField = null)
+ => Error(new Dictionary>() { { invalidField ?? string.Empty, new[] { error } } });
+
+ public static Result Error(IDictionary> errors)
+ => new Result(null, errors);
+
+ public static Result Error(IEnumerable errors, string? invalidField = null)
+ => new Result(null, new Dictionary>() { { invalidField ?? string.Empty, errors } });
+
+ public static Result Ok()
+ where T : notnull
+ => new Result(default, null);
+
+ public static Result Ok(T? value)
+ where T : notnull
+ => new Result(value, null);
+
+ public static Result Error(IDictionary> errors)
+ where T : notnull
+ => new Result(default, errors);
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/Results/ResultOfT.cs b/src/API/CompanyName.MyMeetings.Contracts/Results/ResultOfT.cs
new file mode 100644
index 000000000..5eb330da0
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/Results/ResultOfT.cs
@@ -0,0 +1,19 @@
+namespace CompanyName.MyMeetings.Contracts.Results;
+
+#pragma warning disable SA1649 // File name should match first type name
+public class Result : Result
+#pragma warning restore SA1649 // File name should match first type name
+ where T : notnull
+{
+ public Result()
+ : base()
+ {
+ }
+
+ internal Result(T? value, IDictionary>? errors)
+ : base(value, errors)
+ {
+ }
+
+ public new T? Value { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationRequest.cs
new file mode 100644
index 000000000..6e0959b7b
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationRequest.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+
+public class AuthenticationRequest
+{
+ public string UserName { get; set; } = null!;
+
+ public string Password { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationResultDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationResultDto.cs
new file mode 100644
index 000000000..07efc486c
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/AuthenticationResultDto.cs
@@ -0,0 +1,16 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+
+public class AuthenticationResultDto
+{
+ public string? AccessToken { get; set; }
+
+ public string? RefreshToken { get; set; }
+
+ public string? UserName { get; set; }
+
+ public bool IsLockedOut { get; set; } = false;
+
+ public bool IsNotAllowed { get; set; } = false;
+
+ public bool RequiresTwoFactor { get; set; } = false;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/ResetPasswordRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/ResetPasswordRequest.cs
new file mode 100644
index 000000000..2d0e3aaee
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/ResetPasswordRequest.cs
@@ -0,0 +1,17 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+
+public class ResetPasswordRequest
+{
+ public string Token { get; set; } = null!;
+
+ public string EmailAddress { get; set; } = null!;
+
+ [DataType(DataType.Password)]
+ public string Password { get; set; } = null!;
+
+ [Compare(nameof(Password))]
+ [DataType(DataType.Password)]
+ public string ConfirmPassword { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenRequest.cs
new file mode 100644
index 000000000..74c89ed61
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenRequest.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+
+public class TokenRequest
+{
+ public string AccessToken { get; set; } = null!;
+
+ public string RefreshToken { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenResultDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenResultDto.cs
new file mode 100644
index 000000000..271c1c79b
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authentication/TokenResultDto.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Authentication;
+
+public class TokenResultDto
+{
+ public string AccessToken { get; set; } = null!;
+
+ public string RefreshToken { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authorization/PermissionDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authorization/PermissionDto.cs
new file mode 100644
index 000000000..1d7c9fbc1
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Authorization/PermissionDto.cs
@@ -0,0 +1,10 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Authorization;
+
+public class PermissionDto
+{
+ public string Code { get; set; } = null!;
+
+ public string Name { get; set; } = null!;
+
+ public string? Description { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserAccountDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserAccountDto.cs
new file mode 100644
index 000000000..999015e10
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserAccountDto.cs
@@ -0,0 +1,18 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Identity;
+
+public class UserAccountDto
+{
+ public Guid Id { get; set; }
+
+ public bool IsActive { get; set; }
+
+ public string UserName { get; set; } = null!;
+
+ public string? Name { get; set; }
+
+ public string? FirstName { get; set; }
+
+ public string? LastName { get; set; }
+
+ public string? EmailAddress { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserPermissionDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserPermissionDto.cs
new file mode 100644
index 000000000..148e21703
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Identity/UserPermissionDto.cs
@@ -0,0 +1,6 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Identity;
+
+public class UserPermissionDto
+{
+ public string Code { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/AddRoleRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/AddRoleRequest.cs
new file mode 100644
index 000000000..4ae6488f0
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/AddRoleRequest.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+
+public class AddRoleRequest
+{
+ public string Name { get; set; } = null!;
+
+ public string[] Permissions { get; set; } = null!;
+}
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/PermissionDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/PermissionDto.cs
new file mode 100644
index 000000000..7e3584724
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/PermissionDto.cs
@@ -0,0 +1,10 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+
+public class PermissionDto
+{
+ public string Code { get; set; } = null!;
+
+ public string Name { get; set; } = null!;
+
+ public string? Description { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RenameRoleRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RenameRoleRequest.cs
new file mode 100644
index 000000000..79bbc6b8a
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RenameRoleRequest.cs
@@ -0,0 +1,6 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+
+public class RenameRoleRequest
+{
+ public string Name { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RoleDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RoleDto.cs
new file mode 100644
index 000000000..5093b9dfa
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/RoleDto.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+
+public class RoleDto
+{
+ public Guid Id { get; set; }
+
+ public string Name { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/SetRolePermissionsRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/SetRolePermissionsRequest.cs
new file mode 100644
index 000000000..c156b8608
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Roles/SetRolePermissionsRequest.cs
@@ -0,0 +1,6 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Roles;
+
+public class SetRolePermissionsRequest
+{
+ public string[] Permissions { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/UserRegistrations/RegisterNewUserRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/UserRegistrations/RegisterNewUserRequest.cs
new file mode 100644
index 000000000..ee4bf6681
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/UserRegistrations/RegisterNewUserRequest.cs
@@ -0,0 +1,16 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.UserRegistrations;
+
+public class RegisterNewUserRequest
+{
+ public string Login { get; set; } = null!;
+
+ public string Password { get; set; } = null!;
+
+ public string Email { get; set; } = null!;
+
+ public string FirstName { get; set; } = null!;
+
+ public string LastName { get; set; } = null!;
+
+ public string ConfirmLink { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/ConfirmEmailAddressRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/ConfirmEmailAddressRequest.cs
new file mode 100644
index 000000000..405d91cb4
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/ConfirmEmailAddressRequest.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class ConfirmEmailAddressRequest
+{
+ public string Token { get; set; } = null!;
+
+ public string EmailAddress { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/CreateUserAccountRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/CreateUserAccountRequest.cs
new file mode 100644
index 000000000..b568333c6
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/CreateUserAccountRequest.cs
@@ -0,0 +1,19 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class CreateUserAccountRequest
+{
+ public string UserName { get; set; } = null!;
+
+ [DataType(DataType.Password)]
+ public string? Password { get; set; }
+
+ public string? Name { get; set; }
+
+ public string? FirstName { get; set; }
+
+ public string? LastName { get; set; }
+
+ public string EmailAddress { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/PermissionDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/PermissionDto.cs
new file mode 100644
index 000000000..e35adb513
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/PermissionDto.cs
@@ -0,0 +1,10 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class PermissionDto
+{
+ public string Code { get; set; } = null!;
+
+ public string Name { get; set; } = null!;
+
+ public string? Description { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/RoleDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/RoleDto.cs
new file mode 100644
index 000000000..a70b3a445
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/RoleDto.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class RoleDto
+{
+ public Guid Id { get; set; }
+
+ public string Name { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserPermissionsRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserPermissionsRequest.cs
new file mode 100644
index 000000000..ef73d21b2
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserPermissionsRequest.cs
@@ -0,0 +1,6 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class SetUserPermissionsRequest
+{
+ public string[] Permissions { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserRolesRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserRolesRequest.cs
new file mode 100644
index 000000000..bfbb17d41
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/SetUserRolesRequest.cs
@@ -0,0 +1,6 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class SetUserRolesRequest
+{
+ public Guid[] RoleIds { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UpdateUserAccountRequest.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UpdateUserAccountRequest.cs
new file mode 100644
index 000000000..c316b046a
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UpdateUserAccountRequest.cs
@@ -0,0 +1,10 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class UpdateUserAccountRequest
+{
+ public string? Name { get; set; }
+
+ public string? FirstName { get; set; }
+
+ public string? LastName { get; set; }
+}
\ No newline at end of file
diff --git a/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UserAccountDto.cs b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UserAccountDto.cs
new file mode 100644
index 000000000..a659e996f
--- /dev/null
+++ b/src/API/CompanyName.MyMeetings.Contracts/V1/Users/Users/UserAccountDto.cs
@@ -0,0 +1,71 @@
+namespace CompanyName.MyMeetings.Contracts.V1.Users.Users;
+
+public class UserAccountDto
+{
+ public Guid Id { get; init; }
+
+ public string? Name { get; init; }
+
+ public string? FirstName { get; init; }
+
+ public string? LastName { get; init; }
+
+ ///
+ /// Gets or sets the date and time, in UTC, when any user lockout ends.
+ /// A value in the past means the user is not locked out.
+ ///
+ public virtual DateTimeOffset? LockoutEnd { get; init; }
+
+ ///
+ /// Gets or sets a flag indicating if two factor authentication is enabled for this user.
+ /// True if 2fa is enabled, otherwise false.
+ ///
+ public virtual bool TwoFactorEnabled { get; init; }
+
+ ///
+ /// Gets or sets a flag indicating if a user has confirmed their telephone address.
+ /// True if the telephone number has been confirmed, otherwise false.
+ ///
+ public virtual bool PhoneNumberConfirmed { get; init; }
+
+ ///
+ /// Gets or sets a telephone number for the user.
+ ///
+ public virtual string? PhoneNumber { get; init; }
+
+ ///
+ /// Gets or sets a flag indicating if a user has confirmed their email address.
+ /// True if the email address has been confirmed, otherwise false.
+ ///
+ public virtual bool EmailConfirmed { get; init; }
+
+ ///
+ /// Gets or sets the normalized email address for this user.
+ ///
+ public virtual string NormalizedEmail { get; init; } = null!;
+
+ ///
+ /// Gets or sets the email address for this user.
+ ///
+ public virtual string Email { get; init; } = null!;
+
+ ///
+ /// Gets or sets the normalized user name for this user.
+ ///
+ public virtual string NormalizedUserName { get; init; } = null!;
+
+ ///
+ /// Gets or sets the login for this user.
+ ///
+ public virtual string UserName { get; init; } = null!;
+
+ ///
+ /// True if the user could be locked out, otherwise false.
+ ///
+ public virtual bool LockoutEnabled { get; init; }
+
+ ///
+ /// Gets or sets the number of failed login attempts for the current user.
+ ///
+ public virtual int AccessFailedCount { get; init; }
+}
\ No newline at end of file
diff --git a/src/BuildingBlocks/Application/Data/IDatabaseConfiguration.cs b/src/BuildingBlocks/Application/Data/IDatabaseConfiguration.cs
new file mode 100644
index 000000000..964420940
--- /dev/null
+++ b/src/BuildingBlocks/Application/Data/IDatabaseConfiguration.cs
@@ -0,0 +1,6 @@
+namespace CompanyName.MyMeetings.BuildingBlocks.Application.Data;
+
+public interface IDatabaseConfiguration
+{
+ string ConnectionString { get; }
+}
\ No newline at end of file
diff --git a/src/BuildingBlocks/Application/IExecutionContextAccessor.cs b/src/BuildingBlocks/Application/IExecutionContextAccessor.cs
index c534528b6..fe5d788ca 100644
--- a/src/BuildingBlocks/Application/IExecutionContextAccessor.cs
+++ b/src/BuildingBlocks/Application/IExecutionContextAccessor.cs
@@ -7,5 +7,7 @@ public interface IExecutionContextAccessor
Guid CorrelationId { get; }
bool IsAvailable { get; }
+
+ bool IsAuthenticated { get; }
}
}
\ No newline at end of file
diff --git a/src/BuildingBlocks/Domain/Entity.cs b/src/BuildingBlocks/Domain/Entity.cs
index bfc9c7db1..84c92ce72 100644
--- a/src/BuildingBlocks/Domain/Entity.cs
+++ b/src/BuildingBlocks/Domain/Entity.cs
@@ -1,6 +1,6 @@
namespace CompanyName.MyMeetings.BuildingBlocks.Domain
{
- public abstract class Entity
+ public abstract class Entity : IEntity
{
private List _domainEvents;
diff --git a/src/BuildingBlocks/Domain/IEntity.cs b/src/BuildingBlocks/Domain/IEntity.cs
new file mode 100644
index 000000000..aa0e009cb
--- /dev/null
+++ b/src/BuildingBlocks/Domain/IEntity.cs
@@ -0,0 +1,12 @@
+namespace CompanyName.MyMeetings.BuildingBlocks.Domain
+{
+ public interface IEntity
+ {
+ void ClearDomainEvents();
+
+ ///
+ /// Domain events occurred.
+ ///
+ IReadOnlyCollection DomainEvents { get; }
+ }
+}
diff --git a/src/BuildingBlocks/Infrastructure/DatabaseConfiguration.cs b/src/BuildingBlocks/Infrastructure/DatabaseConfiguration.cs
new file mode 100644
index 000000000..d94438067
--- /dev/null
+++ b/src/BuildingBlocks/Infrastructure/DatabaseConfiguration.cs
@@ -0,0 +1,13 @@
+using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
+
+namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
+
+public class DatabaseConfiguration : IDatabaseConfiguration
+{
+ public DatabaseConfiguration(string connectionString)
+ {
+ ConnectionString = connectionString;
+ }
+
+ public string ConnectionString { get; }
+}
\ No newline at end of file
diff --git a/src/BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs b/src/BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs
index bd06a9221..70b4bbd18 100644
--- a/src/BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs
+++ b/src/BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs
@@ -5,7 +5,7 @@
namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure
{
///
- /// Based on https://andrewlock.net/strongly-typed-ids-in-ef-core-using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-4/
+ /// Based on https://andrewlock.net/strongly-typed-ids-in-ef-core-using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-4/.
///
public class StronglyTypedIdValueConverterSelector : ValueConverterSelector
{
diff --git a/src/CompanyName.MyMeetings.sln b/src/CompanyName.MyMeetings.sln
index 5e68c9248..a025009fe 100644
--- a/src/CompanyName.MyMeetings.sln
+++ b/src/CompanyName.MyMeetings.sln
@@ -15,7 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UserAccess", "UserAccess",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{BC9DDFD1-FB81-4996-812A-68BEBCA33A97}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccess.Application", "Modules\UserAccess\Application\CompanyName.MyMeetings.Modules.UserAccess.Application.csproj", "{F34C6504-590B-480A-A239-F230CDFF8CED}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.Application", "Modules\UserAccess\Application\CompanyName.MyMeetings.Modules.UserAccessIS.Application.csproj", "{F34C6504-590B-480A-A239-F230CDFF8CED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.Meetings.Application", "Modules\Meetings\Application\CompanyName.MyMeetings.Modules.Meetings.Application.csproj", "{5C2C1630-8A7A-451F-81A8-8547C939F5FD}"
EndProject
@@ -41,11 +41,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Database", "Database", "{C7
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.Administration.IntegrationEvents", "Modules\Administration\IntegrationEvents\CompanyName.MyMeetings.Modules.Administration.IntegrationEvents.csproj", "{396817BD-94A7-4559-A7F1-2FAB8009BCF8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccess.Infrastructure", "Modules\UserAccess\Infrastructure\CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.csproj", "{55E1C531-2B9B-49B1-BDFE-9DE322E7FE00}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure", "Modules\UserAccess\Infrastructure\CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.csproj", "{55E1C531-2B9B-49B1-BDFE-9DE322E7FE00}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccess.Domain", "Modules\UserAccess\Domain\CompanyName.MyMeetings.Modules.UserAccess.Domain.csproj", "{F364B0C4-1882-46A1-9B08-22587BEF05A2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.Domain", "Modules\UserAccess\Domain\CompanyName.MyMeetings.Modules.UserAccessIS.Domain.csproj", "{F364B0C4-1882-46A1-9B08-22587BEF05A2}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents", "Modules\UserAccess\IntegrationEvents\CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents.csproj", "{0C31EA31-6A10-47D0-82E5-6D224E1CE532}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents", "Modules\UserAccess\IntegrationEvents\CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents.csproj", "{0C31EA31-6A10-47D0-82E5-6D224E1CE532}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Payments", "Payments", "{13E4D721-2E96-497E-9657-503D09468F9F}"
EndProject
@@ -63,7 +63,7 @@ Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "CompanyName.MyMeetings.Data
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{0FF699EF-8156-43CB-8D18-8EA28F30E9EE}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests", "Modules\UserAccess\Tests\UnitTests\CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.csproj", "{0BC12804-A858-427B-88E2-F9CDE9E97986}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests", "Modules\UserAccess\Tests\UnitTests\CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.csproj", "{0BC12804-A858-427B-88E2-F9CDE9E97986}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{53E4F002-E708-45F7-8444-19EB8977B5C9}"
EndProject
@@ -87,9 +87,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.Payments.ArchTests", "Modules\Payments\Tests\ArchTests\CompanyName.MyMeetings.Modules.Payments.ArchTests.csproj", "{1885C71E-1624-4673-B0BC-BF4035CFFE72}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccess.ArchTests", "Modules\UserAccess\Tests\ArchTests\CompanyName.MyMeetings.Modules.UserAccess.ArchTests.csproj", "{F8EE61DA-0E8B-4074-A0AF-433244EC1FB8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests", "Modules\UserAccess\Tests\ArchTests\CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.csproj", "{F8EE61DA-0E8B-4074-A0AF-433244EC1FB8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests", "Modules\UserAccess\Tests\IntegrationTests\CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.csproj", "{396A6C3F-74BA-4D85-8BF3-1182F9DE9D95}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests", "Modules\UserAccess\Tests\IntegrationTests\CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.csproj", "{396A6C3F-74BA-4D85-8BF3-1182F9DE9D95}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.Payments.IntegrationTests", "Modules\Payments\Tests\IntegrationTests\CompanyName.MyMeetings.Modules.Payments.IntegrationTests.csproj", "{B448FDC3-5F85-47EE-9F4A-2654E8CC67E1}"
EndProject
@@ -136,6 +136,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RequestExamples", "RequestE
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.SUT", "Tests\SUT\CompanyName.MyMeetings.SUT.csproj", "{1853847F-9988-43A1-B3E1-DDBE4B2F3365}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IdentityServer", "IdentityServer", "{1761E09E-402B-4273-BDE5-0A8D9BD2BAC0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MicrosoftIdentity", "MicrosoftIdentity", "{10AFBD87-F071-47A5-B3E6-F7B4C63E1207}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessMI.Domain", "Modules\UserAccessMI\Domain\CompanyName.MyMeetings.Modules.UserAccessMI.Domain.csproj", "{44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessMI.Infrastructure", "Modules\UserAccessMI\Infrastructure\CompanyName.MyMeetings.Modules.UserAccessMI.Infrastructure.csproj", "{D98E656A-90DB-449D-9E37-19E315B6C13F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessMI.Application", "Modules\UserAccessMI\Application\CompanyName.MyMeetings.Modules.UserAccessMI.Application.csproj", "{738C7BA8-036F-4B73-B90E-6D26F076D53C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents", "Modules\UserAccessMI\IntegrationEvents\CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents.csproj", "{CDD3A192-432E-478D-AE93-A16707FCF801}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompanyName.MyMeetings.Contracts", "API\CompanyName.MyMeetings.Contracts\CompanyName.MyMeetings.Contracts.csproj", "{45821070-B75C-458C-A25E-2EDD86E47152}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -385,6 +399,36 @@ Global
{1853847F-9988-43A1-B3E1-DDBE4B2F3365}.Production|Any CPU.Build.0 = Debug|Any CPU
{1853847F-9988-43A1-B3E1-DDBE4B2F3365}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1853847F-9988-43A1-B3E1-DDBE4B2F3365}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}.Production|Any CPU.ActiveCfg = Production|Any CPU
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}.Production|Any CPU.Build.0 = Production|Any CPU
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D98E656A-90DB-449D-9E37-19E315B6C13F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D98E656A-90DB-449D-9E37-19E315B6C13F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D98E656A-90DB-449D-9E37-19E315B6C13F}.Production|Any CPU.ActiveCfg = Production|Any CPU
+ {D98E656A-90DB-449D-9E37-19E315B6C13F}.Production|Any CPU.Build.0 = Production|Any CPU
+ {D98E656A-90DB-449D-9E37-19E315B6C13F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D98E656A-90DB-449D-9E37-19E315B6C13F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C}.Production|Any CPU.ActiveCfg = Production|Any CPU
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C}.Production|Any CPU.Build.0 = Production|Any CPU
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CDD3A192-432E-478D-AE93-A16707FCF801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CDD3A192-432E-478D-AE93-A16707FCF801}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CDD3A192-432E-478D-AE93-A16707FCF801}.Production|Any CPU.ActiveCfg = Production|Any CPU
+ {CDD3A192-432E-478D-AE93-A16707FCF801}.Production|Any CPU.Build.0 = Production|Any CPU
+ {CDD3A192-432E-478D-AE93-A16707FCF801}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CDD3A192-432E-478D-AE93-A16707FCF801}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45821070-B75C-458C-A25E-2EDD86E47152}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45821070-B75C-458C-A25E-2EDD86E47152}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45821070-B75C-458C-A25E-2EDD86E47152}.Production|Any CPU.ActiveCfg = Production|Any CPU
+ {45821070-B75C-458C-A25E-2EDD86E47152}.Production|Any CPU.Build.0 = Production|Any CPU
+ {45821070-B75C-458C-A25E-2EDD86E47152}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45821070-B75C-458C-A25E-2EDD86E47152}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -393,7 +437,7 @@ Global
{49D08B64-AC8E-4607-820F-8A0B989CFD33} = {BC9DDFD1-FB81-4996-812A-68BEBCA33A97}
{9CD43CAC-C149-41E1-9654-157D578143B7} = {BCE1EE3C-ADB1-48CC-9FD1-C7324D886964}
{AE6D0618-60E1-40B2-A46F-664A19C9503C} = {BCE1EE3C-ADB1-48CC-9FD1-C7324D886964}
- {F34C6504-590B-480A-A239-F230CDFF8CED} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
+ {F34C6504-590B-480A-A239-F230CDFF8CED} = {1761E09E-402B-4273-BDE5-0A8D9BD2BAC0}
{5C2C1630-8A7A-451F-81A8-8547C939F5FD} = {9CD43CAC-C149-41E1-9654-157D578143B7}
{F71CFDA8-0770-4761-896A-FB0098113F87} = {9CD43CAC-C149-41E1-9654-157D578143B7}
{93F3D023-37BD-4C5C-9442-DE2631CD4954} = {9CD43CAC-C149-41E1-9654-157D578143B7}
@@ -405,9 +449,9 @@ Global
{CD765A37-EB16-4E35-AA03-6E706D70E8A0} = {5F398170-87FD-4368-9930-FAAAD2D9FDCC}
{3ED61776-83A0-426C-9B3A-3AB755DA01EF} = {9CD43CAC-C149-41E1-9654-157D578143B7}
{396817BD-94A7-4559-A7F1-2FAB8009BCF8} = {5F398170-87FD-4368-9930-FAAAD2D9FDCC}
- {55E1C531-2B9B-49B1-BDFE-9DE322E7FE00} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
- {F364B0C4-1882-46A1-9B08-22587BEF05A2} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
- {0C31EA31-6A10-47D0-82E5-6D224E1CE532} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
+ {55E1C531-2B9B-49B1-BDFE-9DE322E7FE00} = {1761E09E-402B-4273-BDE5-0A8D9BD2BAC0}
+ {F364B0C4-1882-46A1-9B08-22587BEF05A2} = {1761E09E-402B-4273-BDE5-0A8D9BD2BAC0}
+ {0C31EA31-6A10-47D0-82E5-6D224E1CE532} = {1761E09E-402B-4273-BDE5-0A8D9BD2BAC0}
{13E4D721-2E96-497E-9657-503D09468F9F} = {BCE1EE3C-ADB1-48CC-9FD1-C7324D886964}
{6E013582-9E44-4D7E-8CFE-5F6FB6757B03} = {13E4D721-2E96-497E-9657-503D09468F9F}
{C457929B-91BE-48CC-A714-217D9CABD3CC} = {13E4D721-2E96-497E-9657-503D09468F9F}
@@ -415,7 +459,7 @@ Global
{8DF88C85-594D-45D7-B12E-6B641D497853} = {13E4D721-2E96-497E-9657-503D09468F9F}
{9EAA687B-951E-4D89-8857-99151FF1BCD7} = {E91D4BE3-61FE-441C-A227-29850D414216}
{43DBBB02-CA43-42AD-BE21-04AC867BA168} = {C733D087-7051-4E35-BCDB-081252A108E5}
- {0FF699EF-8156-43CB-8D18-8EA28F30E9EE} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
+ {0FF699EF-8156-43CB-8D18-8EA28F30E9EE} = {1761E09E-402B-4273-BDE5-0A8D9BD2BAC0}
{0BC12804-A858-427B-88E2-F9CDE9E97986} = {0FF699EF-8156-43CB-8D18-8EA28F30E9EE}
{53E4F002-E708-45F7-8444-19EB8977B5C9} = {13E4D721-2E96-497E-9657-503D09468F9F}
{602768DD-F063-469D-9CD3-95CB02F6E441} = {53E4F002-E708-45F7-8444-19EB8977B5C9}
@@ -440,6 +484,13 @@ Global
{165E76B9-DB0C-49B7-B3DC-52DFBEA55A79} = {C733D087-7051-4E35-BCDB-081252A108E5}
{00B904C6-D29A-4F26-B7AD-116C701DB73F} = {BC9DDFD1-FB81-4996-812A-68BEBCA33A97}
{1853847F-9988-43A1-B3E1-DDBE4B2F3365} = {8B08A9EE-CE27-4CC3-ACB3-3BD9628E5479}
+ {1761E09E-402B-4273-BDE5-0A8D9BD2BAC0} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
+ {10AFBD87-F071-47A5-B3E6-F7B4C63E1207} = {AE6D0618-60E1-40B2-A46F-664A19C9503C}
+ {44FD1665-B9E0-4B6C-BAE2-043E8EB9DCEB} = {10AFBD87-F071-47A5-B3E6-F7B4C63E1207}
+ {D98E656A-90DB-449D-9E37-19E315B6C13F} = {10AFBD87-F071-47A5-B3E6-F7B4C63E1207}
+ {738C7BA8-036F-4B73-B90E-6D26F076D53C} = {10AFBD87-F071-47A5-B3E6-F7B4C63E1207}
+ {CDD3A192-432E-478D-AE93-A16707FCF801} = {10AFBD87-F071-47A5-B3E6-F7B4C63E1207}
+ {45821070-B75C-458C-A25E-2EDD86E47152} = {BC9DDFD1-FB81-4996-812A-68BEBCA33A97}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6B94C21A-AA6D-4D82-963E-C69C0353B938}
diff --git a/src/Database/CompanyName.MyMeetings.Database/CompanyName.MyMeetings.Database.sqlproj b/src/Database/CompanyName.MyMeetings.Database/CompanyName.MyMeetings.Database.sqlproj
index 350ad2505..69295181a 100644
--- a/src/Database/CompanyName.MyMeetings.Database/CompanyName.MyMeetings.Database.sqlproj
+++ b/src/Database/CompanyName.MyMeetings.Database/CompanyName.MyMeetings.Database.sqlproj
@@ -89,6 +89,9 @@
+
+
+
@@ -172,8 +175,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Scripts/CreateStructure.sql b/src/Database/CompanyName.MyMeetings.Database/Scripts/CreateStructure.sql
index a28aaeb1a..296ff7fc7 100644
--- a/src/Database/CompanyName.MyMeetings.Database/Scripts/CreateStructure.sql
+++ b/src/Database/CompanyName.MyMeetings.Database/Scripts/CreateStructure.sql
@@ -34,6 +34,15 @@ CREATE SCHEMA [users]
AUTHORIZATION [dbo];
+GO
+PRINT N'Creating [usersmi]...';
+
+
+GO
+CREATE SCHEMA [usersmi]
+ AUTHORIZATION [dbo];
+
+
GO
PRINT N'Creating [payments].[NewStreamMessages]...';
@@ -717,6 +726,279 @@ CREATE TABLE [users].[OutboxMessages] (
);
+GO
+PRINT N'Tabelle "[usersmi].[Permissions]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[Permissions] (
+ [Code] VARCHAR (100) NOT NULL,
+ [Name] VARCHAR (100) NOT NULL,
+ [Description] VARCHAR (255) NULL,
+ CONSTRAINT [PK_Permission_Code] PRIMARY KEY CLUSTERED ([Code] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[Roles]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[Roles] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [Name] NVARCHAR (256) NULL,
+ [NormalizedName] NVARCHAR (256) NULL,
+ [ConcurrencyStamp] NVARCHAR (MAX) NULL,
+ CONSTRAINT [PK_Role_Id] PRIMARY KEY CLUSTERED ([Id] ASC),
+ CONSTRAINT [UQ_Role_Name] UNIQUE NONCLUSTERED ([Name] ASC),
+ CONSTRAINT [UQ_Role_NormalizedName] UNIQUE NONCLUSTERED ([NormalizedName] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[RoleClaims]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[RoleClaims] (
+ [Id] INT IDENTITY (1, 1) NOT NULL,
+ [RoleId] UNIQUEIDENTIFIER NOT NULL,
+ [ClaimType] NVARCHAR (MAX) NULL,
+ [ClaimValue] NVARCHAR (MAX) NULL,
+ CONSTRAINT [PK_RoleClaim_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[Users]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[Users] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [Name] NVARCHAR (255) NULL,
+ [FirstName] NVARCHAR (100) NULL,
+ [LastName] NVARCHAR (100) NULL,
+ [UserName] NVARCHAR (256) NULL,
+ [NormalizedUserName] NVARCHAR (256) NULL,
+ [Email] NVARCHAR (256) NULL,
+ [NormalizedEmail] NVARCHAR (256) NULL,
+ [EmailConfirmed] BIT NOT NULL,
+ [PasswordHash] NVARCHAR (MAX) NULL,
+ [SecurityStamp] NVARCHAR (MAX) NULL,
+ [ConcurrencyStamp] NVARCHAR (MAX) NULL,
+ [PhoneNumber] NVARCHAR (MAX) NULL,
+ [PhoneNumberConfirmed] BIT NOT NULL,
+ [TwoFactorEnabled] BIT NOT NULL,
+ [LockoutEnd] DATETIMEOFFSET (7) NULL,
+ [LockoutEnabled] BIT NOT NULL,
+ [AccessFailedCount] INT NOT NULL,
+ CONSTRAINT [PK_User_Id] PRIMARY KEY CLUSTERED ([Id] ASC),
+ CONSTRAINT [UQ_User_NormalizedUserName] UNIQUE NONCLUSTERED ([NormalizedUserName] ASC),
+ CONSTRAINT [UQ_User_UserName] UNIQUE NONCLUSTERED ([UserName] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[UserClaims]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[UserClaims] (
+ [Id] INT IDENTITY (1, 1) NOT NULL,
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [ClaimType] NVARCHAR (MAX) NULL,
+ [ClaimValue] NVARCHAR (MAX) NULL,
+ CONSTRAINT [PK_UserClaim_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[UserLogins]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[UserLogins] (
+ [LoginProvider] NVARCHAR (450) NOT NULL,
+ [ProviderKey] NVARCHAR (450) NOT NULL,
+ [ProviderDisplayName] NVARCHAR (MAX) NULL,
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ CONSTRAINT [PK_UserLogin_LoginProvider_ProviderKey] PRIMARY KEY CLUSTERED ([LoginProvider] ASC, [ProviderKey] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[UserRefreshTokens]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[UserRefreshTokens] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [Token] NVARCHAR (MAX) NOT NULL,
+ [JwtId] NVARCHAR (MAX) NOT NULL,
+ [IsRevoked] BIT NOT NULL,
+ [AddedDate] DATETIME2 (7) NOT NULL,
+ [ExpiryDate] DATETIME2 (7) NOT NULL,
+ CONSTRAINT [PK_UserRefreshToken_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[UserRoles]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[UserRoles] (
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [RoleId] UNIQUEIDENTIFIER NOT NULL,
+ CONSTRAINT [PK_UserRole_UserId_RoleId] PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[UserTokens]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[UserTokens] (
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [LoginProvider] NVARCHAR (450) NOT NULL,
+ [Name] NVARCHAR (450) NOT NULL,
+ [Value] NVARCHAR (MAX) NULL,
+ CONSTRAINT [PK_UserToken_UserId_LoginProvider_Name] PRIMARY KEY CLUSTERED ([UserId] ASC, [LoginProvider] ASC, [Name] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[InboxMessages]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[InboxMessages] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [OccurredOn] DATETIME2 (7) NOT NULL,
+ [Type] VARCHAR (255) NOT NULL,
+ [Data] VARCHAR (MAX) NOT NULL,
+ [ProcessedDate] DATETIME2 (7) NULL,
+ CONSTRAINT [PK_InboxMessages_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[InternalCommands]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[InternalCommands] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [EnqueueDate] DATETIME2 (7) NOT NULL,
+ [Type] VARCHAR (255) NOT NULL,
+ [Data] VARCHAR (MAX) NOT NULL,
+ [ProcessedDate] DATETIME2 (7) NULL,
+ [Error] NVARCHAR (MAX) NULL,
+ CONSTRAINT [PK_InternalCommands_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[OutboxMessages]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[OutboxMessages] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [OccurredOn] DATETIME2 (7) NOT NULL,
+ [Type] VARCHAR (255) NOT NULL,
+ [Data] VARCHAR (MAX) NOT NULL,
+ [ProcessedDate] DATETIME2 (7) NULL,
+ CONSTRAINT [PK_OutboxMessages_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Tabelle "[usersmi].[UserRegistrations]" wird erstellt...';
+
+
+GO
+CREATE TABLE [usersmi].[UserRegistrations] (
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [UserName] NVARCHAR (100) NOT NULL,
+ [Email] NVARCHAR (255) NOT NULL,
+ [Password] NVARCHAR (255) NOT NULL,
+ [FirstName] NVARCHAR (50) NOT NULL,
+ [LastName] NVARCHAR (50) NOT NULL,
+ [Name] NVARCHAR (255) NOT NULL,
+ [StatusCode] VARCHAR (50) NOT NULL,
+ [RegisterDate] DATETIME NOT NULL,
+ [ConfirmedDate] DATETIME NULL,
+ CONSTRAINT [PK_UserRegistrations_Id] PRIMARY KEY CLUSTERED ([Id] ASC)
+);
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_RoleClaim_RoleId_Role_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[RoleClaims] WITH NOCHECK
+ ADD CONSTRAINT [FK_RoleClaim_RoleId_Role_Id] FOREIGN KEY ([RoleId]) REFERENCES [usersmi].[Roles] ([Id]) ON DELETE CASCADE;
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_UserClaim_UserId_User_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[UserClaims] WITH NOCHECK
+ ADD CONSTRAINT [FK_UserClaim_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE;
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_UserLogin_UserId_User_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[UserLogins] WITH NOCHECK
+ ADD CONSTRAINT [FK_UserLogin_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE;
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_UserRefreshToken_UserId_User_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[UserRefreshTokens] WITH NOCHECK
+ ADD CONSTRAINT [FK_UserRefreshToken_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE;
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_UserRole_RoleId_Role_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[UserRoles] WITH NOCHECK
+ ADD CONSTRAINT [FK_UserRole_RoleId_Role_Id] FOREIGN KEY ([RoleId]) REFERENCES [usersmi].[Roles] ([Id]) ON DELETE CASCADE;
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_UserRole_UserId_User_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[UserRoles] WITH NOCHECK
+ ADD CONSTRAINT [FK_UserRole_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE;
+
+
+GO
+PRINT N'Fremdschlüssel "[usersmi].[FK_UserToken_UserId_User_Id]" wird erstellt...';
+
+
+GO
+ALTER TABLE [usersmi].[UserTokens] WITH NOCHECK
+ ADD CONSTRAINT [FK_UserToken_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE;
+
+
GO
PRINT N'Creating [payments].[DF_payments_Streams_Version]...';
@@ -911,6 +1193,69 @@ SELECT
FROM [users].UserRoles AS [UserRole]
INNER JOIN [users].RolesToPermissions AS [RolesToPermission]
ON [UserRole].RoleCode = [RolesToPermission].RoleCode
+GO
+
+PRINT N'Sicht "[usersmi].[v_UserPermissions]" wird erstellt...';
+
+
+GO
+CREATE VIEW [usersmi].[v_UserPermissions]
+AS
+SELECT
+ DISTINCT
+ [UserRole].[UserId] AS [UserId],
+ [RoleClaim].[ClaimValue] AS [PermissionCode]
+FROM [usersmi].UserRoles AS [UserRole]
+ INNER JOIN [usersmi].[RoleClaims] AS [RoleClaim]
+ ON [UserRole].[RoleId] = [RoleClaim].[RoleId]
+GO
+PRINT N'Sicht "[usersmi].[v_UserRegistrations]" wird erstellt...';
+
+
+GO
+CREATE VIEW [usersmi].[v_UserRegistrations]
+AS
+SELECT
+ [UserRegistration].[Id],
+ [UserRegistration].[UserName],
+ [UserRegistration].[Email],
+ [UserRegistration].[FirstName],
+ [UserRegistration].[LastName],
+ [UserRegistration].[Name],
+ [UserRegistration].[StatusCode]
+FROM [usersmi].[UserRegistrations] AS [UserRegistration]
+GO
+PRINT N'Sicht "[usersmi].[v_UserRoles]" wird erstellt...';
+
+
+GO
+CREATE VIEW [usersmi].[v_UserRoles]
+AS
+SELECT
+ [UserRole].[UserId],
+ [Role].[Name]
+FROM [usersmi].[UserRoles] AS [UserRole]
+ INNER JOIN [usersmi].[Roles] AS [Role]
+ ON [UserRole].[UserId] = [Role].[Id]
+GO
+PRINT N'Sicht "[usersmi].[v_Users]" wird erstellt...';
+
+
+GO
+CREATE VIEW [usersmi].[v_Users]
+AS
+SELECT
+ [User].[Id],
+ IIF([User].[LockoutEnabled] = 1, 0, 1) AS [IsActive],
+ [User].[UserName] AS [Login],
+ [User].[PasswordHash] AS [Password],
+ [User].[Email],
+ [User].[Name]
+FROM [usersmi].[Users] AS [User]
+GO
+PRINT N'Update abgeschlossen.';
+
+
GO
PRINT N'Checking existing data against newly created constraints';
diff --git a/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0002_SeedPermissions.sql b/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0002_SeedPermissions.sql
new file mode 100644
index 000000000..76fb42993
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0002_SeedPermissions.sql
@@ -0,0 +1,91 @@
+INSERT INTO [usersmi].[Permissions] ([Code], [Name], [Description])
+ VALUES
+
+ -- ##############################################################################################################
+ -- # *** APPLICATION *** #
+ -- ##############################################################################################################
+ ('Application.Administrator', 'Administrator', NULL),
+
+
+ -- ##############################################################################################################
+ -- # *** USERS *** #
+ -- ##############################################################################################################
+
+ -- Identity
+ ('Users.GetUserAccounts', 'GetUserAccounts', NULL),
+
+ -- Users
+ ('Users.GetUsers', 'GetUsers', NULL),
+ ('Users.CreateUserAccount', 'CreateUserAccount', NULL),
+ ('Users.UpdateUserAccount', 'UpdateUserAccount', NULL),
+ ('Users.UnlockUserAccount', 'UnlockUserAccount', NULL),
+ ('Users.ConfirmEmailAddress', 'ConfirmEmailAddress', NULL),
+ ('Users.GetAuthenticatorKey', 'GetAuthenticatorKey', NULL),
+ ('Users.RegisterAuthenticator', 'RegisterAuthenticator', NULL),
+ ('Users.GetUserRoles', 'GetUserRoles', NULL),
+ ('Users.SetUserRoles', 'SetUserRoles', NULL),
+ ('Users.GetUserPermissions', 'GetUserPermissions', NULL),
+ ('Users.SetUserPermissions', 'SetUserPermissions', NULL),
+
+ -- User roles
+ ('Users.GetRoles', 'GetRoles', NULL),
+ ('Users.AddRole', 'AddRole', NULL),
+ ('Users.RenameRole', 'RenameRole', NULL),
+ ('Users.DeleteRole', 'DeleteRole', NULL),
+ ('Users.GetRolePermissions', 'GetRolePermissions', NULL),
+ ('Users.SetRolePermissions', 'SetRolePermissions', NULL),
+
+ -- ##############################################################################################################
+ -- # *** MEETINGS *** #
+ -- ##############################################################################################################
+ ('GetMeetingGroupProposals', 'GetMeetingGroupProposals', NULL),
+ ('ProposeMeetingGroup', 'ProposeMeetingGroup', NULL),
+ ('CreateNewMeeting', 'CreateNewMeeting', NULL),
+ ('EditMeeting', 'EditMeeting', NULL),
+ ('AddMeetingAttendee', 'AddMeetingAttendee', NULL),
+ ('RemoveMeetingAttendee', 'RemoveMeetingAttendee', NULL),
+ ('AddNotAttendee', 'AddNotAttendee', NULL),
+ ('ChangeNotAttendeeDecision', 'ChangeNotAttendeeDecision', NULL),
+ ('SignUpMemberToWaitlist', 'SignUpMemberToWaitlist', NULL),
+ ('SignOffMemberFromWaitlist', 'SignOffMemberFromWaitlist', NULL),
+ ('SetMeetingHostRole', 'SetMeetingHostRole', NULL),
+ ('SetMeetingAttendeeRole', 'SetMeetingAttendeeRole', NULL),
+ ('CancelMeeting', 'CancelMeeting', NULL),
+ ('GetAllMeetingGroups', 'GetAllMeetingGroups', NULL),
+ ('EditMeetingGroupGeneralAttributes', 'EditMeetingGroupGeneralAttributes', NULL),
+ ('JoinToGroup', 'JoinToGroup', NULL),
+ ('LeaveMeetingGroup', 'LeaveMeetingGroup', NULL),
+ ('AddMeetingComment', 'AddMeetingComment', NULL),
+ ('EditMeetingComment', 'EditMeetingComment', NULL),
+ ('RemoveMeetingComment', 'RemoveMeetingComment', NULL),
+ ('AddMeetingCommentReply', 'AddMeetingCommentReply', NULL),
+ ('LikeMeetingComment', 'LikeMeetingComment', NULL),
+ ('UnlikeMeetingComment', 'UnlikeMeetingComment', NULL),
+ ('EnableMeetingCommenting', 'EnableMeetingCommenting', NULL),
+ ('DisableMeetingCommenting', 'DisableMeetingCommenting', NULL),
+ ('MyMeetingGroupsView', 'MyMeetingGroupsView', NULL),
+ ('AllMeetingGroupsView', 'AllMeetingGroupsView', NULL),
+ ('SubscriptionView', 'SubscriptionView', NULL),
+ ('EmailsView', 'EmailsView', NULL),
+ ('MyMeetingsView', 'MyMeetingsView', NULL),
+ ('GetAuthenticatedMemberMeetings', 'GetAuthenticatedMemberMeetings', NULL),
+
+ -- ##############################################################################################################
+ -- # *** ADMINISTRATION *** #
+ -- ##############################################################################################################
+ --
+ ('AcceptMeetingGroupProposal', 'AcceptMeetingGroupProposal', NULL),
+ ('AdministrationsView', 'AdministrationsView', NULL),
+
+ -- ##############################################################################################################
+ -- # *** PAYMENTS *** #
+ -- ##############################################################################################################
+ ('RegisterPayment', 'RegisterPayment', NULL),
+ ('BuySubscription', 'BuySubscription', NULL),
+ ('RenewSubscription', 'RenewSubscription', NULL),
+ ('CreatePriceListItem', 'CreatePriceListItem', NULL),
+ ('ActivatePriceListItem', 'ActivatePriceListItem', NULL),
+ ('DeactivatePriceListItem', 'DeactivatePriceListItem', NULL),
+ ('ChangePriceListItemAttributes', 'ChangePriceListItemAttributes', NULL),
+ ('GetAuthenticatedPayerSubscription', 'GetAuthenticatedPayerSubscription', NULL),
+ ('GetPriceListItem', 'GetPriceListItem', NULL);
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0003_SeedRoles.sql b/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0003_SeedRoles.sql
new file mode 100644
index 000000000..796f4c2d8
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0003_SeedRoles.sql
@@ -0,0 +1,60 @@
+INSERT INTO [usersmi].[Roles]
+ ([Id], [Name], [NormalizedName], [ConcurrencyStamp])
+ VALUES
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Administrator', 'ADMINISTRATOR', 'ff5d947e-723d-4bf6-b6b9-0c1487c72f73'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Member', 'MEMBER', 'ad88d3f5-37ef-473e-addc-9ee10184e7d0');
+
+
+INSERT INTO [usersmi].[RoleClaims]
+ ([RoleId], [ClaimType], [ClaimValue])
+ VALUES
+ -- Administator
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'AcceptMeetingGroupProposal'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'AdministrationsView'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'CreatePriceListItem'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'ActivatePriceListItem'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'DeactivatePriceListItem'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'ChangePriceListItemAttributes'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'GetPriceListItem'),
+ ('1E5A7F47-A258-4127-42A1-08DC00AA0515', 'Application.Permission', 'Users.GetUserAccounts'),
+
+ -- Member
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetMeetingGroupProposals'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'ProposeMeetingGroup'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'CreateNewMeeting'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'EditMeeting'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'AddMeetingAttendee'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'RemoveMeetingAttendee'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'AddNotAttendee'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'ChangeNotAttendeeDecision'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'SignUpMemberToWaitlist'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'SignOffMemberFromWaitlist'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'SetMeetingHostRole'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'SetMeetingAttendeeRole'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'CancelMeeting'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetAllMeetingGroups'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'EditMeetingGroupGeneralAttributes'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'JoinToGroup'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'LeaveMeetingGroup'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'AddMeetingComment'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'EditMeetingComment'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'RemoveMeetingComment'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'AddMeetingCommentReply'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'LikeMeetingComment'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'UnlikeMeetingComment'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetAuthenticatedMemberMeetingGroups'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetMeetingGroupDetails'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetMeetingDetails'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetMeetingAttendees'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'MyMeetingsGroupsView'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'SubscriptionView'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'EmailsView'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'AllMeetingGroupsView'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'MyMeetingsView'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetAuthenticatedMemberMeetings'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'RegisterPayment'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'BuySubscription'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'RenewSubscription'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetAuthenticatedPayerSubscription'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'GetPriceListItem'),
+ ('9CE09287-D003-439F-42A0-08DC00AA0515', 'Application.Permission', 'Users.GetUserAccounts');
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0004_SeedUsers.sql b/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0004_SeedUsers.sql
new file mode 100644
index 000000000..6d26e4ac5
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Scripts/Seeds/0004_SeedUsers.sql
@@ -0,0 +1,48 @@
+-- Global administrator
+INSERT INTO [usersmi].[Users] ([Id], [Name], [FirstName], [LastName], [UserName], [NormalizedUserName], [Email], [NormalizedEmail], [EmailConfirmed], [PasswordHash], [SecurityStamp], [ConcurrencyStamp], [PhoneNumber], [PhoneNumberConfirmed], [TwoFactorEnabled], [LockoutEnd], [LockoutEnabled], [AccessFailedCount])
+ VALUES
+ ('39C63EC6-9AFF-473D-010F-08DBFFF6E9DF',
+ 'Administrator',
+ NULL,
+ NULL,
+ 'administrator',
+ 'ADMINISTRATOR',
+ 'administrator@mymeetings.com',
+ 'ADMINISTRATOR@MYMEETINGS.COM',
+ 1,
+ 'AQAAAAIAAYagAAAAEMWzWgeHA5LEvzLC9ke6LfqO/ju2RvcguKHjDONHn/CZuOaXwk4WMg8CXP2OOKLHsw==', -- AdminP@$$123.
+ 'CELIHCK47VKN4IL3ZGTYRVL4WX7AKTS6',
+ '60c49c98-2932-43b0-9363-099906901875',
+ NULL,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0);
+
+-- Assign permission to administrator
+INSERT INTO [usersmi].[UserClaims]
+ ([ClaimType], [ClaimValue], [UserId])
+ VALUES ('Application.Permission', 'Application.Administrator', '39C63EC6-9AFF-473D-010F-08DBFFF6E9DF');
+
+
+-- Test users
+INSERT INTO [usersmi].[UserRegistrations]
+ ([Id], [UserName], [Email], [Password], [FirstName], [LastName], [Name], [StatusCode], [RegisterDate], [ConfirmedDate])
+ VALUES
+ ('2EBFECFC-ED13-43B8-B516-6AC89D51C510', 'testMember@mail.com', 'testMember@mail.com', 'testMemberPass', 'John', 'Doe', 'John Doe', 'Confirmed', GETDATE(), GETDATE()),
+ ('4065630E-4A4C-4F01-9142-0BACF6B8C64D', 'testAdmin@mail.com', 'testAdmin@mail.com', 'testAdminPass', 'Jane', 'Doe', 'Jane Doe', 'Confirmed', GETDATE(), GETDATE());
+
+INSERT INTO [usersmi].[Users]
+ ([Id], [Name], [FirstName], [LastName], [UserName], [NormalizedUserName], [Email], [NormalizedEmail], [EmailConfirmed], [PasswordHash], [SecurityStamp], [ConcurrencyStamp], [PhoneNumber], [PhoneNumberConfirmed], [TwoFactorEnabled], [LockoutEnd], [LockoutEnabled], [AccessFailedCount])
+ VALUES
+ ('2EBFECFC-ED13-43B8-B516-6AC89D51C510', 'John Doe', 'John', 'Doe', 'testMember@mail.com', 'TESTMEMBER@MAIL.COM', 'testMember@mail.com', 'TESTMEMBER@MAIL.COM', 0, 'AQAAAAIAAYagAAAAEBRXigjUOJjPf/7wwJV1YlCOk2MzBOne1zLXXQoHzZNVqTnl5UuQWwM94ORZqOTR3g==', 'NMMJRCDE4JDHMJB32D43US57X5WALBPV', 'b7eb06fb-a904-492e-9717-6771cb6ad4af', NULL, 0, 0, NULL, 1, 0),
+ ('4065630E-4A4C-4F01-9142-0BACF6B8C64D', 'Jane Doe', 'Jane', 'Doe', 'testAdmin@mail.com', 'TESTADMIN@MAIL.COM', 'testAdmin@mail.com', 'TESTADMIN@MAIL.COM', 0, 'AQAAAAIAAYagAAAAEFjQQOh8ii3LbgV0+0C69GCmygp0I8Z9FV0n6SQCFRK+bN/uFkd5ksBjbWNSiz9/Ag==', 'FTD34O4LXMPZFBMJ4DGS5LN2VVUNCHU5', '29467032-0908-4bd8-9ef5-62676a4e5009', NULL, 0, 0, NULL, 1, 0);
+
+
+-- Assign Roles to Users
+INSERT INTO [usersmi].[UserRoles]
+ ([UserId], [RoleId])
+ VALUES
+ ('2EBFECFC-ED13-43B8-B516-6AC89D51C510', '9CE09287-D003-439F-42A0-08DC00AA0515'), -- John Doe / Member
+ ('4065630E-4A4C-4F01-9142-0BACF6B8C64D', '1E5A7F47-A258-4127-42A1-08DC00AA0515'); -- Jane Doe / Administrator
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/Security/Schemas.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/Security/Schemas.sql
index 18d3cd7f8..0ce03a6f0 100644
--- a/src/Database/CompanyName.MyMeetings.Database/Structure/Security/Schemas.sql
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/Security/Schemas.sql
@@ -11,4 +11,7 @@ CREATE SCHEMA users AUTHORIZATION dbo
GO
CREATE SCHEMA payments AUTHORIZATION dbo
+GO
+
+CREATE SCHEMA usersmi AUTHORIZATION dbo
GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InboxMessages.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InboxMessages.sql
new file mode 100644
index 000000000..b4611c485
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InboxMessages.sql
@@ -0,0 +1,10 @@
+CREATE TABLE [usersmi].InboxMessages
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [OccurredOn] DATETIME2 NOT NULL,
+ [Type] VARCHAR(255) NOT NULL,
+ [Data] VARCHAR(MAX) NOT NULL,
+ [ProcessedDate] DATETIME2 NULL,
+ CONSTRAINT [PK_InboxMessages_Id] PRIMARY KEY ([Id] ASC)
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InternalCommands.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InternalCommands.sql
new file mode 100644
index 000000000..84aa2240a
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/InternalCommands.sql
@@ -0,0 +1,11 @@
+CREATE TABLE [usersmi].InternalCommands
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [EnqueueDate] DATETIME2 NOT NULL,
+ [Type] VARCHAR(255) NOT NULL,
+ [Data] VARCHAR(MAX) NOT NULL,
+ [ProcessedDate] DATETIME2 NULL,
+ [Error] NVARCHAR(MAX) NULL,
+ CONSTRAINT [PK_InternalCommands_Id] PRIMARY KEY ([Id] ASC)
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/OutboxMessages.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/OutboxMessages.sql
new file mode 100644
index 000000000..06526d471
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/OutboxMessages.sql
@@ -0,0 +1,10 @@
+CREATE TABLE [usersmi].OutboxMessages
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [OccurredOn] DATETIME2 NOT NULL,
+ [Type] VARCHAR(255) NOT NULL,
+ [Data] VARCHAR(MAX) NOT NULL,
+ [ProcessedDate] DATETIME2 NULL,
+ CONSTRAINT [PK_OutboxMessages_Id] PRIMARY KEY ([Id] ASC)
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Permission.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Permission.sql
new file mode 100644
index 000000000..ae8820002
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Permission.sql
@@ -0,0 +1,8 @@
+CREATE TABLE [usersmi].[Permissions]
+(
+ [Code] VARCHAR(100) NOT NULL,
+ [Name] VARCHAR(100) NOT NULL,
+ [Description] VARCHAR(255) NULL,
+ CONSTRAINT [PK_Permission_Code] PRIMARY KEY ([Code])
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Role.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Role.sql
new file mode 100644
index 000000000..64041e627
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/Role.sql
@@ -0,0 +1,11 @@
+CREATE TABLE [usersmi].[Roles]
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [Name] NVARCHAR(256) NULL,
+ [NormalizedName] NVARCHAR(256) NULL,
+ [ConcurrencyStamp] NVARCHAR(max) NULL,
+ CONSTRAINT [PK_Role_Id] PRIMARY KEY ([Id]),
+ CONSTRAINT [UQ_Role_Name] UNIQUE([Name]),
+ CONSTRAINT [UQ_Role_NormalizedName] UNIQUE([NormalizedName])
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/RoleClaim.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/RoleClaim.sql
new file mode 100644
index 000000000..9fa263ff1
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/RoleClaim.sql
@@ -0,0 +1,10 @@
+CREATE TABLE [usersmi].[RoleClaims]
+(
+ [Id] int NOT NULL IDENTITY,
+ [RoleId] UNIQUEIDENTIFIER NOT NULL,
+ [ClaimType] NVARCHAR(max) NULL,
+ [ClaimValue] NVARCHAR(max) NULL,
+ CONSTRAINT [PK_RoleClaim_Id] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_RoleClaim_RoleId_Role_Id] FOREIGN KEY ([RoleId]) REFERENCES [usersmi].[Roles] ([Id]) ON DELETE CASCADE
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/User.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/User.sql
new file mode 100644
index 000000000..d01496f83
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/User.sql
@@ -0,0 +1,25 @@
+CREATE TABLE [usersmi].[Users]
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [Name] NVARCHAR(255) NULL,
+ [FirstName] NVARCHAR(100) NULL,
+ [LastName] NVARCHAR(100) NULL,
+ [UserName] NVARCHAR(256) NULL,
+ [NormalizedUserName] NVARCHAR(256) NULL,
+ [Email] NVARCHAR(256) NULL,
+ [NormalizedEmail] NVARCHAR(256) NULL,
+ [EmailConfirmed] BIT NOT NULL,
+ [PasswordHash] NVARCHAR(max) NULL,
+ [SecurityStamp] NVARCHAR(max) NULL,
+ [ConcurrencyStamp] NVARCHAR(max) NULL,
+ [PhoneNumber] NVARCHAR(max) NULL,
+ [PhoneNumberConfirmed] BIT NOT NULL,
+ [TwoFactorEnabled] BIT NOT NULL,
+ [LockoutEnd] DATETIMEOFFSET NULL,
+ [LockoutEnabled] BIT NOT NULL,
+ [AccessFailedCount] INT NOT NULL,
+ CONSTRAINT [PK_User_Id] PRIMARY KEY ([Id]),
+ CONSTRAINT [UQ_User_UserName] UNIQUE([UserName]),
+ CONSTRAINT [UQ_User_NormalizedUserName] UNIQUE([NormalizedUserName])
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserClaim.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserClaim.sql
new file mode 100644
index 000000000..a050db775
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserClaim.sql
@@ -0,0 +1,10 @@
+CREATE TABLE [usersmi].[UserClaims]
+(
+ [Id] INT NOT NULL IDENTITY,
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [ClaimType] NVARCHAR(max) NULL,
+ [ClaimValue] NVARCHAR(max) NULL,
+ CONSTRAINT [PK_UserClaim_Id] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_UserClaim_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserLogin.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserLogin.sql
new file mode 100644
index 000000000..3e630bfcb
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserLogin.sql
@@ -0,0 +1,10 @@
+CREATE TABLE [usersmi].[UserLogins]
+(
+ [LoginProvider] NVARCHAR(450) NOT NULL,
+ [ProviderKey] NVARCHAR(450) NOT NULL,
+ [ProviderDisplayName] NVARCHAR(max) NULL,
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ CONSTRAINT [PK_UserLogin_LoginProvider_ProviderKey] PRIMARY KEY ([LoginProvider], [ProviderKey]),
+ CONSTRAINT [FK_UserLogin_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRefreshToken.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRefreshToken.sql
new file mode 100644
index 000000000..7d1832d24
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRefreshToken.sql
@@ -0,0 +1,13 @@
+CREATE TABLE [usersmi].[UserRefreshTokens]
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [Token] NVARCHAR(max) NOT NULL,
+ [JwtId] NVARCHAR(max) NOT NULL,
+ [IsRevoked] BIT NOT NULL,
+ [AddedDate] DATETIME2 NOT NULL,
+ [ExpiryDate] DATETIME2 NOT NULL,
+ CONSTRAINT [PK_UserRefreshToken_Id] PRIMARY KEY ([Id]),
+ CONSTRAINT [FK_UserRefreshToken_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRegistrations.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRegistrations.sql
new file mode 100644
index 000000000..1bf47c253
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRegistrations.sql
@@ -0,0 +1,15 @@
+CREATE TABLE [usersmi].[UserRegistrations]
+(
+ [Id] UNIQUEIDENTIFIER NOT NULL,
+ [UserName] NVARCHAR(100) NOT NULL,
+ [Email] NVARCHAR (255) NOT NULL,
+ [Password] NVARCHAR(255) NOT NULL,
+ [FirstName] NVARCHAR(50) NOT NULL,
+ [LastName] NVARCHAR(50) NOT NULL,
+ [Name] NVARCHAR (255) NOT NULL,
+ [StatusCode] VARCHAR(50) NOT NULL,
+ [RegisterDate] DATETIME NOT NULL,
+ [ConfirmedDate] DATETIME NULL,
+ CONSTRAINT [PK_UserRegistrations_Id] PRIMARY KEY ([Id] ASC)
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRole.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRole.sql
new file mode 100644
index 000000000..58a502bdb
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserRole.sql
@@ -0,0 +1,9 @@
+CREATE TABLE [usersmi].[UserRoles]
+(
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [RoleId] UNIQUEIDENTIFIER NOT NULL,
+ CONSTRAINT [PK_UserRole_UserId_RoleId] PRIMARY KEY ([UserId], [RoleId]),
+ CONSTRAINT [FK_UserRole_RoleId_Role_Id] FOREIGN KEY ([RoleId]) REFERENCES [usersmi].[Roles] ([Id]) ON DELETE CASCADE,
+ CONSTRAINT [FK_UserRole_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserToken.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserToken.sql
new file mode 100644
index 000000000..0fa2c2232
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Tables/UserToken.sql
@@ -0,0 +1,10 @@
+CREATE TABLE [usersmi].[UserTokens]
+(
+ [UserId] UNIQUEIDENTIFIER NOT NULL,
+ [LoginProvider] NVARCHAR(450) NOT NULL,
+ [Name] NVARCHAR(450) NOT NULL,
+ [Value] NVARCHAR(max) NULL,
+ CONSTRAINT [PK_UserToken_UserId_LoginProvider_Name] PRIMARY KEY ([UserId], [LoginProvider], [Name]),
+ CONSTRAINT [FK_UserToken_UserId_User_Id] FOREIGN KEY ([UserId]) REFERENCES [usersmi].[Users] ([Id]) ON DELETE CASCADE
+)
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserPermissions.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserPermissions.sql
new file mode 100644
index 000000000..847a4a571
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserPermissions.sql
@@ -0,0 +1,10 @@
+CREATE VIEW [usersmi].[v_UserPermissions]
+AS
+SELECT
+ DISTINCT
+ [UserRole].[UserId] AS [UserId],
+ [RoleClaim].[ClaimValue] AS [PermissionCode]
+FROM [usersmi].UserRoles AS [UserRole]
+ INNER JOIN [usersmi].[RoleClaims] AS [RoleClaim]
+ ON [UserRole].[RoleId] = [RoleClaim].[RoleId]
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRegistrations.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRegistrations.sql
new file mode 100644
index 000000000..162bd6db9
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRegistrations.sql
@@ -0,0 +1,12 @@
+CREATE VIEW [usersmi].[v_UserRegistrations]
+AS
+SELECT
+ [UserRegistration].[Id],
+ [UserRegistration].[UserName],
+ [UserRegistration].[Email],
+ [UserRegistration].[FirstName],
+ [UserRegistration].[LastName],
+ [UserRegistration].[Name],
+ [UserRegistration].[StatusCode]
+FROM [usersmi].[UserRegistrations] AS [UserRegistration]
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRoles.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRoles.sql
new file mode 100644
index 000000000..558a5dc98
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_UserRoles.sql
@@ -0,0 +1,8 @@
+CREATE VIEW [usersmi].[v_UserRoles]
+AS
+SELECT [UserRole].[UserId] AS [UserId],
+ [Role].[Name] AS [RoleCode]
+ FROM [usersmi].[UserRoles] AS [UserRole]
+ INNER JOIN [usersmi].[Roles] AS [Role]
+ ON [UserRole].[RoleId] = [Role].[Id]
+GO
\ No newline at end of file
diff --git a/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_Users.sql b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_Users.sql
new file mode 100644
index 000000000..f603e1826
--- /dev/null
+++ b/src/Database/CompanyName.MyMeetings.Database/Structure/usersmi/Views/v_Users.sql
@@ -0,0 +1,11 @@
+CREATE VIEW [usersmi].[v_Users]
+AS
+SELECT
+ [User].[Id],
+ IIF([User].[LockoutEnabled] = 1, 0, 1) AS [IsActive],
+ [User].[UserName] AS [Login],
+ [User].[PasswordHash] AS [Password],
+ [User].[Email],
+ [User].[Name]
+FROM [usersmi].[Users] AS [User]
+GO
\ No newline at end of file
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 64e1191c3..3d2b3285c 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -6,6 +6,7 @@
Copyright © $(Company) $([System.DateTime]::Now.Year)
$(Company)™
$(Company) Projects
+
@@ -21,7 +22,7 @@
True
True
True
- True
+
true
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
index a98909f23..27d418490 100644
--- a/src/Directory.Build.targets
+++ b/src/Directory.Build.targets
@@ -19,6 +19,7 @@
+
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 07ff07dc6..335b42753 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -7,6 +7,8 @@
+
+
@@ -19,7 +21,8 @@
-
+
+
diff --git a/src/Modules/Administration/Application/CompanyName.MyMeetings.Modules.Administration.Application.csproj b/src/Modules/Administration/Application/CompanyName.MyMeetings.Modules.Administration.Application.csproj
index 8f337a235..dbac45113 100644
--- a/src/Modules/Administration/Application/CompanyName.MyMeetings.Modules.Administration.Application.csproj
+++ b/src/Modules/Administration/Application/CompanyName.MyMeetings.Modules.Administration.Application.csproj
@@ -1,6 +1,6 @@
-
+
diff --git a/src/Modules/Administration/Application/Members/NewUserRegisteredIntegrationEventHandler.cs b/src/Modules/Administration/Application/Members/NewUserRegisteredIntegrationEventHandler.cs
index 4455f317c..0c329774a 100644
--- a/src/Modules/Administration/Application/Members/NewUserRegisteredIntegrationEventHandler.cs
+++ b/src/Modules/Administration/Application/Members/NewUserRegisteredIntegrationEventHandler.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.Modules.Administration.Application.Configuration.Commands;
using CompanyName.MyMeetings.Modules.Administration.Application.Members.CreateMember;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents;
using MediatR;
namespace CompanyName.MyMeetings.Modules.Administration.Application.Members
diff --git a/src/Modules/Administration/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs b/src/Modules/Administration/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
index 7b18b98cc..f9c3192ff 100644
--- a/src/Modules/Administration/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
+++ b/src/Modules/Administration/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
@@ -1,7 +1,7 @@
using Autofac;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
using CompanyName.MyMeetings.Modules.Meetings.IntegrationEvents;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents;
using Serilog;
namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.EventsBus
diff --git a/src/Modules/Administration/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs b/src/Modules/Administration/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
index fe53237c4..0387e14f7 100644
--- a/src/Modules/Administration/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
+++ b/src/Modules/Administration/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
@@ -14,5 +14,7 @@ public ExecutionContextMock(Guid userId)
public Guid CorrelationId { get; }
public bool IsAvailable { get; }
+
+ public bool IsAuthenticated { get; }
}
}
\ No newline at end of file
diff --git a/src/Modules/Meetings/Application/CompanyName.MyMeetings.Modules.Meetings.Application.csproj b/src/Modules/Meetings/Application/CompanyName.MyMeetings.Modules.Meetings.Application.csproj
index 717ad07d6..3a9d78b3e 100644
--- a/src/Modules/Meetings/Application/CompanyName.MyMeetings.Modules.Meetings.Application.csproj
+++ b/src/Modules/Meetings/Application/CompanyName.MyMeetings.Modules.Meetings.Application.csproj
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/src/Modules/Meetings/Application/Members/CreateMember/NewUserRegisteredIntegrationEventHandler.cs b/src/Modules/Meetings/Application/Members/CreateMember/NewUserRegisteredIntegrationEventHandler.cs
index 8b55061c2..52546e647 100644
--- a/src/Modules/Meetings/Application/Members/CreateMember/NewUserRegisteredIntegrationEventHandler.cs
+++ b/src/Modules/Meetings/Application/Members/CreateMember/NewUserRegisteredIntegrationEventHandler.cs
@@ -1,5 +1,5 @@
using CompanyName.MyMeetings.Modules.Meetings.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents;
using MediatR;
namespace CompanyName.MyMeetings.Modules.Meetings.Application.Members.CreateMember
diff --git a/src/Modules/Meetings/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs b/src/Modules/Meetings/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
index ce0691773..0cfce84d3 100644
--- a/src/Modules/Meetings/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
+++ b/src/Modules/Meetings/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
@@ -2,7 +2,7 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
using CompanyName.MyMeetings.Modules.Administration.IntegrationEvents.MeetingGroupProposals;
using CompanyName.MyMeetings.Modules.Payments.IntegrationEvents;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents;
using Serilog;
namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.EventsBus
diff --git a/src/Modules/Meetings/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs b/src/Modules/Meetings/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
index 2c1387401..a43080ff3 100644
--- a/src/Modules/Meetings/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
+++ b/src/Modules/Meetings/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
@@ -14,5 +14,7 @@ public ExecutionContextMock(Guid userId)
public Guid CorrelationId { get; }
public bool IsAvailable { get; }
+
+ public bool IsAuthenticated { get; }
}
}
\ No newline at end of file
diff --git a/src/Modules/Payments/Application/CompanyName.MyMeetings.Modules.Payments.Application.csproj b/src/Modules/Payments/Application/CompanyName.MyMeetings.Modules.Payments.Application.csproj
index aa2b1916f..fd963b8e5 100644
--- a/src/Modules/Payments/Application/CompanyName.MyMeetings.Modules.Payments.Application.csproj
+++ b/src/Modules/Payments/Application/CompanyName.MyMeetings.Modules.Payments.Application.csproj
@@ -2,6 +2,6 @@
-
+
diff --git a/src/Modules/Payments/Application/Payers/CreatePayer/NewUserRegisteredIntegrationEventHandler.cs b/src/Modules/Payments/Application/Payers/CreatePayer/NewUserRegisteredIntegrationEventHandler.cs
index bd1a6df0a..af8ac57e3 100644
--- a/src/Modules/Payments/Application/Payers/CreatePayer/NewUserRegisteredIntegrationEventHandler.cs
+++ b/src/Modules/Payments/Application/Payers/CreatePayer/NewUserRegisteredIntegrationEventHandler.cs
@@ -1,5 +1,5 @@
using CompanyName.MyMeetings.Modules.Payments.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents;
using MediatR;
namespace CompanyName.MyMeetings.Modules.Payments.Application.Payers.CreatePayer
diff --git a/src/Modules/Payments/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs b/src/Modules/Payments/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
index 5c448de6d..60a37985c 100644
--- a/src/Modules/Payments/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
+++ b/src/Modules/Payments/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
@@ -2,7 +2,7 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
using CompanyName.MyMeetings.Modules.Administration.IntegrationEvents.MeetingGroupProposals;
using CompanyName.MyMeetings.Modules.Meetings.IntegrationEvents;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessMI.IntegrationEvents;
using Serilog;
namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.EventsBus
diff --git a/src/Modules/Payments/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs b/src/Modules/Payments/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
index 0e4e19700..38602f606 100644
--- a/src/Modules/Payments/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
+++ b/src/Modules/Payments/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
@@ -14,5 +14,7 @@ public ExecutionContextMock(Guid userId)
public Guid CorrelationId { get; }
public bool IsAvailable { get; }
+
+ public bool IsAuthenticated { get; }
}
}
\ No newline at end of file
diff --git a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommand.cs b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommand.cs
index dbca797e0..a5f7bb314 100644
--- a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommand.cs
+++ b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommand.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication.Authenticate
{
public class AuthenticateCommand : CommandBase
{
diff --git a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandHandler.cs b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandHandler.cs
index 0b9208394..b1942a0ab 100644
--- a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandHandler.cs
+++ b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandHandler.cs
@@ -1,10 +1,10 @@
using System.Security.Claims;
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication.Authenticate
{
internal class AuthenticateCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandValidator.cs b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandValidator.cs
index 53eac0d9e..bb446e8a0 100644
--- a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandValidator.cs
+++ b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandValidator.cs
@@ -1,6 +1,6 @@
using FluentValidation;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication.Authenticate
{
internal class AuthenticateCommandValidator : AbstractValidator
{
diff --git a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticationResult.cs b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticationResult.cs
index 1446b4450..578e34798 100644
--- a/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticationResult.cs
+++ b/src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticationResult.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication.Authenticate
{
public class AuthenticationResult
{
diff --git a/src/Modules/UserAccess/Application/Authentication/Authenticate/UserDto.cs b/src/Modules/UserAccess/Application/Authentication/Authenticate/UserDto.cs
index b7911a0e1..71caa8490 100644
--- a/src/Modules/UserAccess/Application/Authentication/Authenticate/UserDto.cs
+++ b/src/Modules/UserAccess/Application/Authentication/Authenticate/UserDto.cs
@@ -1,6 +1,6 @@
using System.Security.Claims;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication.Authenticate
{
public class UserDto
{
diff --git a/src/Modules/UserAccess/Application/Authentication/PasswordManager.cs b/src/Modules/UserAccess/Application/Authentication/PasswordManager.cs
index ea7af0666..b00795fb0 100644
--- a/src/Modules/UserAccess/Application/Authentication/PasswordManager.cs
+++ b/src/Modules/UserAccess/Application/Authentication/PasswordManager.cs
@@ -1,7 +1,7 @@
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication
{
public class PasswordManager
{
diff --git a/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQuery.cs b/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQuery.cs
index 99824cfb5..f06d3a9f1 100644
--- a/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQuery.cs
+++ b/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQuery.cs
@@ -1,7 +1,7 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetAuthenticatedUserPermissions
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetAuthenticatedUserPermissions
{
public class GetAuthenticatedUserPermissionsQuery : QueryBase>
{
diff --git a/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQueryHandler.cs b/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQueryHandler.cs
index 4daffd4e1..a5a02289e 100644
--- a/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQueryHandler.cs
@@ -1,10 +1,10 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetAuthenticatedUserPermissions
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetAuthenticatedUserPermissions
{
internal class GetAuthenticatedUserPermissionsQueryHandler : IQueryHandler>
{
diff --git a/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQuery.cs b/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQuery.cs
index b7fd6db40..cfb03d8d6 100644
--- a/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQuery.cs
+++ b/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQuery.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions
{
public class GetUserPermissionsQuery : QueryBase>
{
diff --git a/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQueryHandler.cs b/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQueryHandler.cs
index 5c9270b7e..bf9fd7c8a 100644
--- a/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQueryHandler.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions
{
internal class GetUserPermissionsQueryHandler : IQueryHandler>
{
diff --git a/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/UserPermissionDto.cs b/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/UserPermissionDto.cs
index 65af856d8..2683c9815 100644
--- a/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/UserPermissionDto.cs
+++ b/src/Modules/UserAccess/Application/Authorization/GetUserPermissions/UserPermissionDto.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authorization.GetUserPermissions
{
public class UserPermissionDto
{
diff --git a/src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccess.Application.csproj b/src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccessIS.Application.csproj
similarity index 68%
rename from src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccess.Application.csproj
rename to src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccessIS.Application.csproj
index 3252d9bd8..7608b9ffb 100644
--- a/src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccess.Application.csproj
+++ b/src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccessIS.Application.csproj
@@ -2,7 +2,4 @@
-
-
-
\ No newline at end of file
diff --git a/src/Modules/UserAccess/Application/Configuration/Commands/ICommandHandler.cs b/src/Modules/UserAccess/Application/Configuration/Commands/ICommandHandler.cs
index 652c8358b..bc5ae91ea 100644
--- a/src/Modules/UserAccess/Application/Configuration/Commands/ICommandHandler.cs
+++ b/src/Modules/UserAccess/Application/Configuration/Commands/ICommandHandler.cs
@@ -1,7 +1,7 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands
{
public interface ICommandHandler : IRequestHandler
where TCommand : ICommand
diff --git a/src/Modules/UserAccess/Application/Configuration/Commands/ICommandsScheduler.cs b/src/Modules/UserAccess/Application/Configuration/Commands/ICommandsScheduler.cs
index 876fd61be..3eebcb4e3 100644
--- a/src/Modules/UserAccess/Application/Configuration/Commands/ICommandsScheduler.cs
+++ b/src/Modules/UserAccess/Application/Configuration/Commands/ICommandsScheduler.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands
{
public interface ICommandsScheduler
{
diff --git a/src/Modules/UserAccess/Application/Configuration/Commands/InternalCommandBase.cs b/src/Modules/UserAccess/Application/Configuration/Commands/InternalCommandBase.cs
index d975e270a..f18d712ad 100644
--- a/src/Modules/UserAccess/Application/Configuration/Commands/InternalCommandBase.cs
+++ b/src/Modules/UserAccess/Application/Configuration/Commands/InternalCommandBase.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands
{
public abstract class InternalCommandBase : ICommand
{
diff --git a/src/Modules/UserAccess/Application/Configuration/Queries/IQueryHandler.cs b/src/Modules/UserAccess/Application/Configuration/Queries/IQueryHandler.cs
index 3b8e2a81d..cd896b35c 100644
--- a/src/Modules/UserAccess/Application/Configuration/Queries/IQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/Configuration/Queries/IQueryHandler.cs
@@ -1,7 +1,7 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries
{
public interface IQueryHandler :
IRequestHandler
diff --git a/src/Modules/UserAccess/Application/Contracts/CommandBase.cs b/src/Modules/UserAccess/Application/Contracts/CommandBase.cs
index 979d4905b..b307689da 100644
--- a/src/Modules/UserAccess/Application/Contracts/CommandBase.cs
+++ b/src/Modules/UserAccess/Application/Contracts/CommandBase.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public abstract class CommandBase : ICommand
{
diff --git a/src/Modules/UserAccess/Application/Contracts/CustomClaimTypes.cs b/src/Modules/UserAccess/Application/Contracts/CustomClaimTypes.cs
index 219d54dc6..3286ff5ac 100644
--- a/src/Modules/UserAccess/Application/Contracts/CustomClaimTypes.cs
+++ b/src/Modules/UserAccess/Application/Contracts/CustomClaimTypes.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
internal class CustomClaimTypes
{
diff --git a/src/Modules/UserAccess/Application/Contracts/ICommand.cs b/src/Modules/UserAccess/Application/Contracts/ICommand.cs
index dbc194e04..d9d3f80ed 100644
--- a/src/Modules/UserAccess/Application/Contracts/ICommand.cs
+++ b/src/Modules/UserAccess/Application/Contracts/ICommand.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public interface ICommand : IRequest
{
diff --git a/src/Modules/UserAccess/Application/Contracts/IQuery.cs b/src/Modules/UserAccess/Application/Contracts/IQuery.cs
index 874e8e147..937bfbf7b 100644
--- a/src/Modules/UserAccess/Application/Contracts/IQuery.cs
+++ b/src/Modules/UserAccess/Application/Contracts/IQuery.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public interface IQuery : IRequest
{
diff --git a/src/Modules/UserAccess/Application/Contracts/IRecurringCommand.cs b/src/Modules/UserAccess/Application/Contracts/IRecurringCommand.cs
index b7bfd7671..c1db782af 100644
--- a/src/Modules/UserAccess/Application/Contracts/IRecurringCommand.cs
+++ b/src/Modules/UserAccess/Application/Contracts/IRecurringCommand.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public interface IRecurringCommand
{
diff --git a/src/Modules/UserAccess/Application/Contracts/IUserAccessModule.cs b/src/Modules/UserAccess/Application/Contracts/IUserAccessModule.cs
index 41043fc88..2744e9c1b 100644
--- a/src/Modules/UserAccess/Application/Contracts/IUserAccessModule.cs
+++ b/src/Modules/UserAccess/Application/Contracts/IUserAccessModule.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public interface IUserAccessModule
{
diff --git a/src/Modules/UserAccess/Application/Contracts/QueryBase.cs b/src/Modules/UserAccess/Application/Contracts/QueryBase.cs
index c0105a3b4..5e282c6f5 100644
--- a/src/Modules/UserAccess/Application/Contracts/QueryBase.cs
+++ b/src/Modules/UserAccess/Application/Contracts/QueryBase.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public abstract class QueryBase : IQuery
{
diff --git a/src/Modules/UserAccess/Application/Contracts/Roles.cs b/src/Modules/UserAccess/Application/Contracts/Roles.cs
index 7eb199d1d..7f6a34bf4 100644
--- a/src/Modules/UserAccess/Application/Contracts/Roles.cs
+++ b/src/Modules/UserAccess/Application/Contracts/Roles.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts
{
public class Roles
{
diff --git a/src/Modules/UserAccess/Application/Emails/EmailDto.cs b/src/Modules/UserAccess/Application/Emails/EmailDto.cs
index 71793f760..cba8af6df 100644
--- a/src/Modules/UserAccess/Application/Emails/EmailDto.cs
+++ b/src/Modules/UserAccess/Application/Emails/EmailDto.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Emails
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Emails
{
public class EmailDto
{
diff --git a/src/Modules/UserAccess/Application/Emails/GetAllEmailsQuery.cs b/src/Modules/UserAccess/Application/Emails/GetAllEmailsQuery.cs
index 228d01912..44af63344 100644
--- a/src/Modules/UserAccess/Application/Emails/GetAllEmailsQuery.cs
+++ b/src/Modules/UserAccess/Application/Emails/GetAllEmailsQuery.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Emails
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Emails
{
public class GetAllEmailsQuery : QueryBase>
{
diff --git a/src/Modules/UserAccess/Application/Emails/GetAllEmailsQueryHandler.cs b/src/Modules/UserAccess/Application/Emails/GetAllEmailsQueryHandler.cs
index fa26e171a..feca69435 100644
--- a/src/Modules/UserAccess/Application/Emails/GetAllEmailsQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/Emails/GetAllEmailsQueryHandler.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Emails
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Emails
{
internal class GetAllEmailsQueryHandler : IQueryHandler>
{
diff --git a/src/Modules/UserAccess/Application/IdentityServer/IdentityServerConfig.cs b/src/Modules/UserAccess/Application/IdentityServer/IdentityServerConfig.cs
index 2d2e9cccc..653781aa2 100644
--- a/src/Modules/UserAccess/Application/IdentityServer/IdentityServerConfig.cs
+++ b/src/Modules/UserAccess/Application/IdentityServer/IdentityServerConfig.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using IdentityServer4;
using IdentityServer4.Models;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.IdentityServer
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.IdentityServer
{
public class IdentityServerConfig
{
diff --git a/src/Modules/UserAccess/Application/IdentityServer/ProfileService.cs b/src/Modules/UserAccess/Application/IdentityServer/ProfileService.cs
index eae2f97c3..fbf15d0a4 100644
--- a/src/Modules/UserAccess/Application/IdentityServer/ProfileService.cs
+++ b/src/Modules/UserAccess/Application/IdentityServer/ProfileService.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using IdentityServer4.Models;
using IdentityServer4.Services;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.IdentityServer
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.IdentityServer
{
public class ProfileService : IProfileService
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommand.cs b/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommand.cs
index 2bc0fd088..cf877ab35 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommand.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommand.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.ConfirmUserRegistration
{
public class ConfirmUserRegistrationCommand : CommandBase
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommandHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommandHandler.cs
index 48598696c..7b2428a32 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommandHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommandHandler.cs
@@ -1,7 +1,7 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.ConfirmUserRegistration
{
internal class ConfirmUserRegistrationCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/UserRegistrationConfirmedHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/UserRegistrationConfirmedHandler.cs
index 2420aa163..6f2ce3a64 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/UserRegistrationConfirmedHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/UserRegistrationConfirmedHandler.cs
@@ -1,9 +1,9 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.ConfirmUserRegistration
{
public class UserRegistrationConfirmedHandler : INotificationHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQuery.cs b/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQuery.cs
index 21225e233..1bcbf6fc7 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQuery.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQuery.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.GetUserRegistration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.GetUserRegistration
{
public class GetUserRegistrationQuery : QueryBase
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQueryHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQueryHandler.cs
index 7d45eac6d..b5ca4a056 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQueryHandler.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.GetUserRegistration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.GetUserRegistration
{
internal class GetUserRegistrationQueryHandler : IQueryHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/UserRegistrationDto.cs b/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/UserRegistrationDto.cs
index 091015d5f..68bc871b6 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/UserRegistrationDto.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/UserRegistrationDto.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.GetUserRegistration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.GetUserRegistration
{
public class UserRegistrationDto
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredEnqueueEmailConfirmationHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredEnqueueEmailConfirmationHandler.cs
index b093b5d57..74f5d2e20 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredEnqueueEmailConfirmationHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredEnqueueEmailConfirmationHandler.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.SendUserRegistrationConfirmationEmail;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.SendUserRegistrationConfirmationEmail;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser
{
public class NewUserRegisteredEnqueueEmailConfirmationHandler : INotificationHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredNotification.cs b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredNotification.cs
index d5dfd9fee..8f4c5cab7 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredNotification.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredNotification.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Events;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events;
using Newtonsoft.Json;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser
{
public class NewUserRegisteredNotification : DomainNotificationBase
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredPublishEventHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredPublishEventHandler.cs
index 2c41aff0e..fbb8ce79b 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredPublishEventHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/NewUserRegisteredPublishEventHandler.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
-using CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents;
+using CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser
{
public class NewUserRegisteredPublishEventHandler : INotificationHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommand.cs b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommand.cs
index b8257b6b4..74725b909 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommand.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommand.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser
{
public class RegisterNewUserCommand : CommandBase
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommandHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommandHandler.cs
index cbcc313c7..464c7c5d1 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommandHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/RegisterNewUser/RegisterNewUserCommandHandler.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser
{
internal class RegisterNewUserCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommand.cs b/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommand.cs
index f1e55149e..899476d86 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommand.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommand.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
using Newtonsoft.Json;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.SendUserRegistrationConfirmationEmail
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.SendUserRegistrationConfirmationEmail
{
public class SendUserRegistrationConfirmationEmailCommand : InternalCommandBase
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommandHandler.cs b/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommandHandler.cs
index f1bd10b7d..7317ec18a 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommandHandler.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/SendUserRegistrationConfirmationEmail/SendUserRegistrationConfirmationEmailCommandHandler.cs
@@ -1,7 +1,7 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Emails;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.SendUserRegistrationConfirmationEmail
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.SendUserRegistrationConfirmationEmail
{
internal class SendUserRegistrationConfirmationEmailCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Application/UserRegistrations/UsersCounter.cs b/src/Modules/UserAccess/Application/UserRegistrations/UsersCounter.cs
index 16e66b080..579c84a6e 100644
--- a/src/Modules/UserAccess/Application/UserRegistrations/UsersCounter.cs
+++ b/src/Modules/UserAccess/Application/UserRegistrations/UsersCounter.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations
{
public class UsersCounter : IUsersCounter
{
diff --git a/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommand.cs b/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommand.cs
index 5786fd97d..a0b30bc70 100644
--- a/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommand.cs
+++ b/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommand.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.AddAdminUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.AddAdminUser
{
public class AddAdminUserCommand : CommandBase
{
diff --git a/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommandHandler.cs b/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommandHandler.cs
index 297b1d126..16627d418 100644
--- a/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommandHandler.cs
+++ b/src/Modules/UserAccess/Application/Users/AddAdminUser/AddAdminUserCommandHandler.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Authentication;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.AddAdminUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.AddAdminUser
{
internal class AddAdminUserCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQuery.cs b/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQuery.cs
index 05beeac2c..cb8092f7e 100644
--- a/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQuery.cs
+++ b/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQuery.cs
@@ -1,7 +1,7 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetAuthenticatedUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetAuthenticatedUser
{
public class GetAuthenticatedUserQuery : QueryBase
{
diff --git a/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQueryHandler.cs b/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQueryHandler.cs
index 9041e55d1..2507ba900 100644
--- a/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQueryHandler.cs
@@ -1,10 +1,10 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetAuthenticatedUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetAuthenticatedUser
{
internal class GetAuthenticatedUserQueryHandler : IQueryHandler
{
diff --git a/src/Modules/UserAccess/Application/Users/GetUser/GetUserQuery.cs b/src/Modules/UserAccess/Application/Users/GetUser/GetUserQuery.cs
index 2ab1f06f5..66f41bf31 100644
--- a/src/Modules/UserAccess/Application/Users/GetUser/GetUserQuery.cs
+++ b/src/Modules/UserAccess/Application/Users/GetUser/GetUserQuery.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser
{
public class GetUserQuery : QueryBase
{
diff --git a/src/Modules/UserAccess/Application/Users/GetUser/GetUserQueryHandler.cs b/src/Modules/UserAccess/Application/Users/GetUser/GetUserQueryHandler.cs
index 06b97f32a..cc47ecd8e 100644
--- a/src/Modules/UserAccess/Application/Users/GetUser/GetUserQueryHandler.cs
+++ b/src/Modules/UserAccess/Application/Users/GetUser/GetUserQueryHandler.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
using Dapper;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser
{
internal class GetUserQueryHandler : IQueryHandler
{
diff --git a/src/Modules/UserAccess/Application/Users/GetUser/UserDto.cs b/src/Modules/UserAccess/Application/Users/GetUser/UserDto.cs
index d664e4e07..67d158983 100644
--- a/src/Modules/UserAccess/Application/Users/GetUser/UserDto.cs
+++ b/src/Modules/UserAccess/Application/Users/GetUser/UserDto.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser
{
public class UserDto
{
diff --git a/src/Modules/UserAccess/Domain/CompanyName.MyMeetings.Modules.UserAccess.Domain.csproj b/src/Modules/UserAccess/Domain/CompanyName.MyMeetings.Modules.UserAccessIS.Domain.csproj
similarity index 100%
rename from src/Modules/UserAccess/Domain/CompanyName.MyMeetings.Modules.UserAccess.Domain.csproj
rename to src/Modules/UserAccess/Domain/CompanyName.MyMeetings.Modules.UserAccessIS.Domain.csproj
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Events/NewUserRegisteredDomainEvent.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Events/NewUserRegisteredDomainEvent.cs
index 0adce92ed..c5dfc556e 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Events/NewUserRegisteredDomainEvent.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Events/NewUserRegisteredDomainEvent.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events
{
public class NewUserRegisteredDomainEvent : DomainEventBase
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationConfirmedDomainEvent.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationConfirmedDomainEvent.cs
index deaa90744..3ec639e49 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationConfirmedDomainEvent.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationConfirmedDomainEvent.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events
{
public class UserRegistrationConfirmedDomainEvent : DomainEventBase
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationExpiredDomainEvent.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationExpiredDomainEvent.cs
index 9b47582aa..e8a558deb 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationExpiredDomainEvent.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationExpiredDomainEvent.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events
{
public class UserRegistrationExpiredDomainEvent : DomainEventBase
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/IUserRegistrationRepository.cs b/src/Modules/UserAccess/Domain/UserRegistrations/IUserRegistrationRepository.cs
index ac797d530..b134a3c22 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/IUserRegistrationRepository.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/IUserRegistrationRepository.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations
{
public interface IUserRegistrationRepository
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/IUsersCounter.cs b/src/Modules/UserAccess/Domain/UserRegistrations/IUsersCounter.cs
index e3451cfea..90039ebb8 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/IUsersCounter.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/IUsersCounter.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations
{
public interface IUsersCounter
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule.cs
index 8cca80925..28dbf6ed6 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules
{
public class UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule : IBusinessRule
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserLoginMustBeUniqueRule.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserLoginMustBeUniqueRule.cs
index 43513e366..b4a471df6 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserLoginMustBeUniqueRule.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserLoginMustBeUniqueRule.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules
{
public class UserLoginMustBeUniqueRule : IBusinessRule
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedAfterExpirationRule.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedAfterExpirationRule.cs
index 898214688..f2526be2f 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedAfterExpirationRule.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedAfterExpirationRule.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules
{
public class UserRegistrationCannotBeConfirmedAfterExpirationRule : IBusinessRule
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedMoreThanOnceRule.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedMoreThanOnceRule.cs
index ba59993b4..69f84e5db 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedMoreThanOnceRule.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeConfirmedMoreThanOnceRule.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules
{
public class UserRegistrationCannotBeConfirmedMoreThanOnceRule : IBusinessRule
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeExpiredMoreThanOnceRule.cs b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeExpiredMoreThanOnceRule.cs
index 478d6fc07..02cf68ec5 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeExpiredMoreThanOnceRule.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/Rules/UserRegistrationCannotBeExpiredMoreThanOnceRule.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules
{
public class UserRegistrationCannotBeExpiredMoreThanOnceRule : IBusinessRule
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistration.cs b/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistration.cs
index c7c261cb3..80ef58b00 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistration.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistration.cs
@@ -1,9 +1,9 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations
{
public class UserRegistration : Entity, IAggregateRoot
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationId.cs b/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationId.cs
index 3cb893ef6..49549f332 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationId.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationId.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations
{
public class UserRegistrationId : TypedIdValueBase
{
diff --git a/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationStatus.cs b/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationStatus.cs
index 7a29fc5b4..8c27a5abc 100644
--- a/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationStatus.cs
+++ b/src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationStatus.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations
{
public class UserRegistrationStatus : ValueObject
{
diff --git a/src/Modules/UserAccess/Domain/Users/Events/UserCreatedDomainEvent.cs b/src/Modules/UserAccess/Domain/Users/Events/UserCreatedDomainEvent.cs
index 5d1920323..a75623c5a 100644
--- a/src/Modules/UserAccess/Domain/Users/Events/UserCreatedDomainEvent.cs
+++ b/src/Modules/UserAccess/Domain/Users/Events/UserCreatedDomainEvent.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users.Events
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users.Events
{
public class UserCreatedDomainEvent : DomainEventBase
{
diff --git a/src/Modules/UserAccess/Domain/Users/IUserRepository.cs b/src/Modules/UserAccess/Domain/Users/IUserRepository.cs
index ebcae180e..7a8b95f66 100644
--- a/src/Modules/UserAccess/Domain/Users/IUserRepository.cs
+++ b/src/Modules/UserAccess/Domain/Users/IUserRepository.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users
{
public interface IUserRepository
{
diff --git a/src/Modules/UserAccess/Domain/Users/User.cs b/src/Modules/UserAccess/Domain/Users/User.cs
index 769483579..3941f2b66 100644
--- a/src/Modules/UserAccess/Domain/Users/User.cs
+++ b/src/Modules/UserAccess/Domain/Users/User.cs
@@ -1,8 +1,8 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users.Events;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users.Events;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users
{
public class User : Entity, IAggregateRoot
{
diff --git a/src/Modules/UserAccess/Domain/Users/UserId.cs b/src/Modules/UserAccess/Domain/Users/UserId.cs
index d8d2499b5..22f9c2764 100644
--- a/src/Modules/UserAccess/Domain/Users/UserId.cs
+++ b/src/Modules/UserAccess/Domain/Users/UserId.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users
{
public class UserId : TypedIdValueBase
{
diff --git a/src/Modules/UserAccess/Domain/Users/UserRole.cs b/src/Modules/UserAccess/Domain/Users/UserRole.cs
index 0690e44e2..b3e5202bd 100644
--- a/src/Modules/UserAccess/Domain/Users/UserRole.cs
+++ b/src/Modules/UserAccess/Domain/Users/UserRole.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users
{
public class UserRole : ValueObject
{
diff --git a/src/Modules/UserAccess/Infrastructure/CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.csproj b/src/Modules/UserAccess/Infrastructure/CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.csproj
similarity index 100%
rename from src/Modules/UserAccess/Infrastructure/CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.csproj
rename to src/Modules/UserAccess/Infrastructure/CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.csproj
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/AllConstructorFinder.cs b/src/Modules/UserAccess/Infrastructure/Configuration/AllConstructorFinder.cs
index 52bda4011..4ec2fe15a 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/AllConstructorFinder.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/AllConstructorFinder.cs
@@ -2,7 +2,7 @@
using System.Reflection;
using Autofac.Core.Activators.Reflection;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration
{
internal class AllConstructorFinder : IConstructorFinder
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Assemblies.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Assemblies.cs
index 775b01850..97d2a5f9b 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Assemblies.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Assemblies.cs
@@ -1,7 +1,7 @@
using System.Reflection;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration
{
internal static class Assemblies
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/DataAccess/DataAccessModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/DataAccess/DataAccessModule.cs
index 140d6959e..fdb8830f4 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/DataAccess/DataAccessModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/DataAccess/DataAccessModule.cs
@@ -5,7 +5,7 @@
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.Extensions.Logging;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.DataAccess
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.DataAccess
{
internal class DataAccessModule : Autofac.Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Domain/DomainModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Domain/DomainModule.cs
index a026da24d..4e6e214e0 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Domain/DomainModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Domain/DomainModule.cs
@@ -1,8 +1,8 @@
using Autofac;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Domain
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Domain
{
internal class DomainModule : Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Email/EmailModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Email/EmailModule.cs
index 476e12029..02620e8a0 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Email/EmailModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Email/EmailModule.cs
@@ -2,7 +2,7 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Emails;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.Emails;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Email
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Email
{
internal class EmailModule : Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusModule.cs
index ae2e8fd1c..019c7a2ec 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusModule.cs
@@ -1,7 +1,7 @@
using Autofac;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.EventsBus
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.EventsBus
{
internal class EventsBusModule : Autofac.Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs b/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
index 9c60bb06b..52868df05 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/EventsBusStartup.cs
@@ -3,7 +3,7 @@
using CompanyName.MyMeetings.Modules.Meetings.IntegrationEvents;
using Serilog;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.EventsBus
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.EventsBus
{
public static class EventsBusStartup
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/IntegrationEventGenericHandler.cs b/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/IntegrationEventGenericHandler.cs
index e004f4726..e6ec8ad73 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/IntegrationEventGenericHandler.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/EventsBus/IntegrationEventGenericHandler.cs
@@ -5,7 +5,7 @@
using Dapper;
using Newtonsoft.Json;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.EventsBus
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.EventsBus
{
internal class IntegrationEventGenericHandler : IIntegrationEventHandler
where T : IntegrationEvent
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Logging/LoggingModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Logging/LoggingModule.cs
index a42522f70..b44075bd6 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Logging/LoggingModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Logging/LoggingModule.cs
@@ -1,7 +1,7 @@
using Autofac;
using Serilog;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Logging
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Logging
{
internal class LoggingModule : Autofac.Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Mediation/MediatorModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Mediation/MediatorModule.cs
index 50148a614..5eed38448 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Mediation/MediatorModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Mediation/MediatorModule.cs
@@ -3,12 +3,12 @@
using Autofac.Core;
using Autofac.Features.Variance;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
using FluentValidation;
using MediatR;
using MediatR.Pipeline;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Mediation
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Mediation
{
public class MediatorModule : Autofac.Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/CommandsExecutor.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/CommandsExecutor.cs
index b5ca1a030..127d5c5ad 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/CommandsExecutor.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/CommandsExecutor.cs
@@ -1,8 +1,8 @@
using Autofac;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal static class CommandsExecutor
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/IRecurringCommand.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/IRecurringCommand.cs
index d6e0e1ff8..fc8b8f1a1 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/IRecurringCommand.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/IRecurringCommand.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
public interface IRecurringCommand
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs
index bbb10ccd6..9caca68b4 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Inbox
{
public class InboxMessageDto
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs
index cf3ae1bfc..f77f73d6a 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs
@@ -1,8 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Inbox
{
- public class ProcessInboxCommand : CommandBase, IRecurringCommand
+ public class ProcessInboxCommand : UserAccessIS.Application.Contracts.CommandBase, IRecurringCommand
{
}
}
\ No newline at end of file
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommandHandler.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommandHandler.cs
index 7a8a832c6..b88df3037 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommandHandler.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommandHandler.cs
@@ -1,10 +1,10 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
using Dapper;
using MediatR;
using Newtonsoft.Json;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Inbox
{
internal class ProcessInboxCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs
index 897046458..7361bcc88 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs
@@ -1,6 +1,6 @@
using Quartz;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Inbox
{
[DisallowConcurrentExecution]
public class ProcessInboxJob : IJob
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/CommandsScheduler.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/CommandsScheduler.cs
index ef92e18ff..ee02fd718 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/CommandsScheduler.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/CommandsScheduler.cs
@@ -1,11 +1,11 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.Serialization;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using Dapper;
using Newtonsoft.Json;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.InternalCommands
{
public class CommandsScheduler : ICommandsScheduler
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs
index e5a1d4ee5..99af1304a 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs
@@ -1,8 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.InternalCommands
{
- internal class ProcessInternalCommandsCommand : CommandBase, IRecurringCommand
+ internal class ProcessInternalCommandsCommand : UserAccessIS.Application.Contracts.CommandBase, IRecurringCommand
{
}
}
\ No newline at end of file
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommandHandler.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommandHandler.cs
index 0a08b8264..4a2ca6707 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommandHandler.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommandHandler.cs
@@ -1,10 +1,10 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
using Dapper;
using Newtonsoft.Json;
using Polly;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.InternalCommands
{
internal class ProcessInternalCommandsCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs
index 40e3f3287..faf07a982 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs
@@ -1,6 +1,6 @@
using Quartz;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.InternalCommands
{
[DisallowConcurrentExecution]
public class ProcessInternalCommandsJob : IJob
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerDecorator.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerDecorator.cs
index 6d0c02a99..71f8a0a1e 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerDecorator.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerDecorator.cs
@@ -1,15 +1,14 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
using Serilog;
using Serilog.Context;
using Serilog.Core;
using Serilog.Events;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class LoggingCommandHandlerDecorator : ICommandHandler
- where T : ICommand
+ where T : UserAccessIS.Application.Contracts.ICommand
{
private readonly ILogger _logger;
private readonly IExecutionContextAccessor _executionContextAccessor;
@@ -57,9 +56,9 @@ public async Task Handle(T command, CancellationToken cancellationToken)
private class CommandLogEnricher : ILogEventEnricher
{
- private readonly ICommand _command;
+ private readonly UserAccessIS.Application.Contracts.ICommand _command;
- public CommandLogEnricher(ICommand command)
+ public CommandLogEnricher(UserAccessIS.Application.Contracts.ICommand command)
{
_command = command;
}
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerWithResultDecorator.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerWithResultDecorator.cs
index abf3770a2..9d18dd437 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerWithResultDecorator.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/LoggingCommandHandlerWithResultDecorator.cs
@@ -1,12 +1,12 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using Serilog;
using Serilog.Context;
using Serilog.Core;
using Serilog.Events;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class LoggingCommandHandlerWithResultDecorator : ICommandHandler
where T : ICommand
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs
index dfcc95b0e..ec6d150c8 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox
{
public class OutboxMessageDto
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxModule.cs
index d2d67df78..f826c1d71 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxModule.cs
@@ -3,10 +3,10 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Outbox;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.DomainEventsDispatching;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Outbox;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Outbox;
using Module = Autofac.Module;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox
{
internal class OutboxModule : Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs
index c6f671614..fbf030835 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs
@@ -1,8 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox
{
- public class ProcessOutboxCommand : CommandBase, IRecurringCommand
+ public class ProcessOutboxCommand : UserAccessIS.Application.Contracts.CommandBase, IRecurringCommand
{
}
}
\ No newline at end of file
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommandHandler.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommandHandler.cs
index f63715d30..9498bb070 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommandHandler.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommandHandler.cs
@@ -1,7 +1,7 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
using CompanyName.MyMeetings.BuildingBlocks.Application.Events;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.DomainEventsDispatching;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
using Dapper;
using MediatR;
using Newtonsoft.Json;
@@ -9,7 +9,7 @@
using Serilog.Core;
using Serilog.Events;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox
{
internal class ProcessOutboxCommandHandler : ICommandHandler
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs
index af1824765..9cb0de950 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs
@@ -1,6 +1,6 @@
using Quartz;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox
{
[DisallowConcurrentExecution]
public class ProcessOutboxJob : IJob
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ProcessingModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ProcessingModule.cs
index 4316b4656..c443cc8c1 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ProcessingModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ProcessingModule.cs
@@ -2,11 +2,11 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Events;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.DomainEventsDispatching;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.InternalCommands;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class ProcessingModule : Autofac.Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerDecorator.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerDecorator.cs
index 7d71a2e47..93de5d0a8 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerDecorator.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerDecorator.cs
@@ -1,9 +1,9 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using Microsoft.EntityFrameworkCore;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class UnitOfWorkCommandHandlerDecorator : ICommandHandler
where T : ICommand
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerWithResultDecorator.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerWithResultDecorator.cs
index 01be1418e..7b6ebd14e 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerWithResultDecorator.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/UnitOfWorkCommandHandlerWithResultDecorator.cs
@@ -1,9 +1,9 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using Microsoft.EntityFrameworkCore;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class UnitOfWorkCommandHandlerWithResultDecorator : ICommandHandler
where T : ICommand
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerDecorator.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerDecorator.cs
index a59465704..64df85fde 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerDecorator.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerDecorator.cs
@@ -1,9 +1,9 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using FluentValidation;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class ValidationCommandHandlerDecorator : ICommandHandler
where T : ICommand
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs
index 5c7fc61e5..b8db82d09 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs
@@ -1,9 +1,9 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
using FluentValidation;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing
{
internal class ValidationCommandHandlerWithResultDecorator : ICommandHandler
where T : ICommand
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzModule.cs
index 94ca85c09..e77321d70 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzModule.cs
@@ -1,7 +1,7 @@
using Autofac;
using Quartz;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Quartz
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Quartz
{
public class QuartzModule : Autofac.Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzStartup.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzStartup.cs
index a34e7cdca..0f1bccf78 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzStartup.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzStartup.cs
@@ -1,13 +1,13 @@
using System.Collections.Specialized;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Inbox;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.InternalCommands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox;
using Quartz;
using Quartz.Impl;
using Quartz.Logging;
using Serilog;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Quartz
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Quartz
{
internal static class QuartzStartup
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/SerilogLogProvider.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/SerilogLogProvider.cs
index 7f4762e84..1003ff150 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/SerilogLogProvider.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Quartz/SerilogLogProvider.cs
@@ -1,7 +1,7 @@
using Quartz.Logging;
using Serilog;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Quartz
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Quartz
{
internal class SerilogLogProvider : ILogProvider
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Security/AesDataProtector.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Security/AesDataProtector.cs
index f5048343b..26421a41a 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Security/AesDataProtector.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Security/AesDataProtector.cs
@@ -1,7 +1,7 @@
using System.Security.Cryptography;
using System.Text;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Security
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Security
{
public class AesDataProtector : IDataProtector
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Security/IDataProtector.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Security/IDataProtector.cs
index e27cc0338..85a431d86 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Security/IDataProtector.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Security/IDataProtector.cs
@@ -1,4 +1,4 @@
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Security
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Security
{
public interface IDataProtector
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/Security/SecurityModule.cs b/src/Modules/UserAccess/Infrastructure/Configuration/Security/SecurityModule.cs
index b6ea58ad0..44b23752d 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/Security/SecurityModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/Security/SecurityModule.cs
@@ -1,6 +1,6 @@
using Autofac;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Security
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Security
{
internal class SecurityModule : Module
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessCompositionRoot.cs b/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessCompositionRoot.cs
index e322f8466..ecdf81d28 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessCompositionRoot.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessCompositionRoot.cs
@@ -1,6 +1,6 @@
using Autofac;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration
{
internal static class UserAccessCompositionRoot
{
diff --git a/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessStartup.cs b/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessStartup.cs
index ef5d3547b..1c6f00f72 100644
--- a/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessStartup.cs
+++ b/src/Modules/UserAccess/Infrastructure/Configuration/UserAccessStartup.cs
@@ -4,20 +4,20 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.Emails;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.DataAccess;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Domain;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Email;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.EventsBus;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Logging;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Mediation;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Quartz;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Security;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.DataAccess;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Domain;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Email;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.EventsBus;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Logging;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Mediation;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Quartz;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Security;
using Serilog;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration
{
public class UserAccessStartup
{
diff --git a/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationEntityTypeConfiguration.cs b/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationEntityTypeConfiguration.cs
index bfcfedda7..ac886267f 100644
--- a/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationEntityTypeConfiguration.cs
+++ b/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationEntityTypeConfiguration.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Domain.UserRegistrations
{
internal class UserRegistrationEntityTypeConfiguration : IEntityTypeConfiguration
{
diff --git a/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationRepository.cs b/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationRepository.cs
index 8a304f904..3e4a59a03 100644
--- a/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationRepository.cs
+++ b/src/Modules/UserAccess/Infrastructure/Domain/UserRegistrations/UserRegistrationRepository.cs
@@ -1,7 +1,7 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
using Microsoft.EntityFrameworkCore;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Domain.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Domain.UserRegistrations
{
public class UserRegistrationRepository : IUserRegistrationRepository
{
diff --git a/src/Modules/UserAccess/Infrastructure/Domain/Users/UserEntityTypeConfiguration.cs b/src/Modules/UserAccess/Infrastructure/Domain/Users/UserEntityTypeConfiguration.cs
index 7dc8d3aac..f38ab80c4 100644
--- a/src/Modules/UserAccess/Infrastructure/Domain/Users/UserEntityTypeConfiguration.cs
+++ b/src/Modules/UserAccess/Infrastructure/Domain/Users/UserEntityTypeConfiguration.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Domain.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Domain.Users
{
internal class UserEntityTypeConfiguration : IEntityTypeConfiguration
{
diff --git a/src/Modules/UserAccess/Infrastructure/Domain/Users/UserRepository.cs b/src/Modules/UserAccess/Infrastructure/Domain/Users/UserRepository.cs
index d6873cb80..ade0fb618 100644
--- a/src/Modules/UserAccess/Infrastructure/Domain/Users/UserRepository.cs
+++ b/src/Modules/UserAccess/Infrastructure/Domain/Users/UserRepository.cs
@@ -1,6 +1,6 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Domain.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Domain.Users
{
public class UserRepository : IUserRepository
{
diff --git a/src/Modules/UserAccess/Infrastructure/InternalCommands/InternalCommandEntityTypeConfiguration.cs b/src/Modules/UserAccess/Infrastructure/InternalCommands/InternalCommandEntityTypeConfiguration.cs
index 0116511df..939fdbf9f 100644
--- a/src/Modules/UserAccess/Infrastructure/InternalCommands/InternalCommandEntityTypeConfiguration.cs
+++ b/src/Modules/UserAccess/Infrastructure/InternalCommands/InternalCommandEntityTypeConfiguration.cs
@@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.InternalCommands
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.InternalCommands
{
internal class InternalCommandEntityTypeConfiguration : IEntityTypeConfiguration
{
diff --git a/src/Modules/UserAccess/Infrastructure/Outbox/OutboxAccessor.cs b/src/Modules/UserAccess/Infrastructure/Outbox/OutboxAccessor.cs
index 5502b0c01..ba9422a05 100644
--- a/src/Modules/UserAccess/Infrastructure/Outbox/OutboxAccessor.cs
+++ b/src/Modules/UserAccess/Infrastructure/Outbox/OutboxAccessor.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Outbox;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Outbox
{
public class OutboxAccessor : IOutbox
{
diff --git a/src/Modules/UserAccess/Infrastructure/Outbox/OutboxMessageEntityTypeConfiguration.cs b/src/Modules/UserAccess/Infrastructure/Outbox/OutboxMessageEntityTypeConfiguration.cs
index 84b299d6b..c2f5abd43 100644
--- a/src/Modules/UserAccess/Infrastructure/Outbox/OutboxMessageEntityTypeConfiguration.cs
+++ b/src/Modules/UserAccess/Infrastructure/Outbox/OutboxMessageEntityTypeConfiguration.cs
@@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Outbox
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Outbox
{
internal class OutboxMessageEntityTypeConfiguration : IEntityTypeConfiguration
{
diff --git a/src/Modules/UserAccess/Infrastructure/UserAccessContext.cs b/src/Modules/UserAccess/Infrastructure/UserAccessContext.cs
index 8b94db909..874e61678 100644
--- a/src/Modules/UserAccess/Infrastructure/UserAccessContext.cs
+++ b/src/Modules/UserAccess/Infrastructure/UserAccessContext.cs
@@ -1,15 +1,15 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Outbox;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.InternalCommands;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Domain.UserRegistrations;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Domain.Users;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.InternalCommands;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Outbox;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.InternalCommands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Outbox;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure
{
public class UserAccessContext : DbContext
{
diff --git a/src/Modules/UserAccess/Infrastructure/UserAccessModule.cs b/src/Modules/UserAccess/Infrastructure/UserAccessModule.cs
index 3b10cc5f9..e1f3da00f 100644
--- a/src/Modules/UserAccess/Infrastructure/UserAccessModule.cs
+++ b/src/Modules/UserAccess/Infrastructure/UserAccessModule.cs
@@ -1,10 +1,10 @@
using Autofac;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing;
using MediatR;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure
{
public class UserAccessModule : IUserAccessModule
{
diff --git a/src/Modules/UserAccess/IntegrationEvents/CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents.csproj b/src/Modules/UserAccess/IntegrationEvents/CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents.csproj
similarity index 100%
rename from src/Modules/UserAccess/IntegrationEvents/CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents.csproj
rename to src/Modules/UserAccess/IntegrationEvents/CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents.csproj
diff --git a/src/Modules/UserAccess/IntegrationEvents/NewUserRegisteredIntegrationEvent.cs b/src/Modules/UserAccess/IntegrationEvents/NewUserRegisteredIntegrationEvent.cs
index fcb88dac3..cc850bfec 100644
--- a/src/Modules/UserAccess/IntegrationEvents/NewUserRegisteredIntegrationEvent.cs
+++ b/src/Modules/UserAccess/IntegrationEvents/NewUserRegisteredIntegrationEvent.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus;
-namespace CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationEvents
{
public class NewUserRegisteredIntegrationEvent : IntegrationEvent
{
diff --git a/src/Modules/UserAccess/Tests/ArchTests/Application/ApplicationTests.cs b/src/Modules/UserAccess/Tests/ArchTests/Application/ApplicationTests.cs
index d0463569b..47d0790c4 100644
--- a/src/Modules/UserAccess/Tests/ArchTests/Application/ApplicationTests.cs
+++ b/src/Modules/UserAccess/Tests/ArchTests/Application/ApplicationTests.cs
@@ -1,15 +1,15 @@
using System.Reflection;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.ArchTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.SeedWork;
using FluentValidation;
using MediatR;
using NetArchTest.Rules;
using Newtonsoft.Json;
using NUnit.Framework;
-namespace CompanyName.MyMeetings.Modules.UserAccess.ArchTests.Application
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.Application
{
[TestFixture]
public class ApplicationTests : TestBase
diff --git a/src/Modules/UserAccess/Tests/ArchTests/CompanyName.MyMeetings.Modules.UserAccess.ArchTests.csproj b/src/Modules/UserAccess/Tests/ArchTests/CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.csproj
similarity index 100%
rename from src/Modules/UserAccess/Tests/ArchTests/CompanyName.MyMeetings.Modules.UserAccess.ArchTests.csproj
rename to src/Modules/UserAccess/Tests/ArchTests/CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.csproj
diff --git a/src/Modules/UserAccess/Tests/ArchTests/Domain/DomainTests.cs b/src/Modules/UserAccess/Tests/ArchTests/Domain/DomainTests.cs
index 161941196..6a3c38b8e 100644
--- a/src/Modules/UserAccess/Tests/ArchTests/Domain/DomainTests.cs
+++ b/src/Modules/UserAccess/Tests/ArchTests/Domain/DomainTests.cs
@@ -1,10 +1,10 @@
using System.Reflection;
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-using CompanyName.MyMeetings.Modules.UserAccess.ArchTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.SeedWork;
using NetArchTest.Rules;
using NUnit.Framework;
-namespace CompanyName.MyMeetings.Modules.UserAccess.ArchTests.Domain
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.Domain
{
public class DomainTests : TestBase
{
diff --git a/src/Modules/UserAccess/Tests/ArchTests/Module/LayersTests.cs b/src/Modules/UserAccess/Tests/ArchTests/Module/LayersTests.cs
index ec7b9e1a2..0e1798cbc 100644
--- a/src/Modules/UserAccess/Tests/ArchTests/Module/LayersTests.cs
+++ b/src/Modules/UserAccess/Tests/ArchTests/Module/LayersTests.cs
@@ -1,8 +1,8 @@
-using CompanyName.MyMeetings.Modules.UserAccess.ArchTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.SeedWork;
using NetArchTest.Rules;
using NUnit.Framework;
-namespace CompanyName.MyMeetings.Modules.UserAccess.ArchTests.Module
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.Module
{
[TestFixture]
public class LayersTests : TestBase
diff --git a/src/Modules/UserAccess/Tests/ArchTests/SeedWork/TestBase.cs b/src/Modules/UserAccess/Tests/ArchTests/SeedWork/TestBase.cs
index 58feb086f..1149e3842 100644
--- a/src/Modules/UserAccess/Tests/ArchTests/SeedWork/TestBase.cs
+++ b/src/Modules/UserAccess/Tests/ArchTests/SeedWork/TestBase.cs
@@ -1,11 +1,11 @@
using System.Reflection;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure;
using NetArchTest.Rules;
using NUnit.Framework;
-namespace CompanyName.MyMeetings.Modules.UserAccess.ArchTests.SeedWork
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.ArchTests.SeedWork
{
public abstract class TestBase
{
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/AssemblyInfo.cs b/src/Modules/UserAccess/Tests/IntegrationTests/AssemblyInfo.cs
index c3707f714..ffe779400 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/AssemblyInfo.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/AssemblyInfo.cs
@@ -3,7 +3,7 @@
[assembly: NonParallelizable]
[assembly: LevelOfParallelism(1)]
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests
{
public class AssemblyInfo
{
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.csproj b/src/Modules/UserAccess/Tests/IntegrationTests/CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.csproj
similarity index 100%
rename from src/Modules/UserAccess/Tests/IntegrationTests/CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.csproj
rename to src/Modules/UserAccess/Tests/IntegrationTests/CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.csproj
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs b/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
index 59628ef13..ec99f4bc8 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs
@@ -1,6 +1,6 @@
using CompanyName.MyMeetings.BuildingBlocks.Application;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork
{
public class ExecutionContextMock : IExecutionContextAccessor
{
@@ -15,6 +15,8 @@ public ExecutionContextMock(Guid userId)
public bool IsAvailable { get; }
+ public bool IsAuthenticated { get; }
+
public void SetUserId(Guid userId)
{
this.UserId = userId;
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/OutboxMessagesHelper.cs b/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/OutboxMessagesHelper.cs
index 9cfdec37d..8e2633996 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/OutboxMessagesHelper.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/OutboxMessagesHelper.cs
@@ -1,12 +1,12 @@
using System.Data;
using System.Reflection;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration.Processing.Outbox;
using Dapper;
using MediatR;
using Newtonsoft.Json;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork
{
public class OutboxMessagesHelper
{
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/TestBase.cs b/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/TestBase.cs
index 5135fa6cc..da5717c91 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/TestBase.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/SeedWork/TestBase.cs
@@ -3,16 +3,16 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Emails;
using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.Emails;
using CompanyName.MyMeetings.BuildingBlocks.IntegrationTests;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure;
-using CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Infrastructure.Configuration;
using Dapper;
using MediatR;
using NSubstitute;
using NUnit.Framework;
using Serilog;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork
{
public class TestBase
{
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/ConfirmUserRegistrationTests.cs b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/ConfirmUserRegistrationTests.cs
index 337493a46..22539e5c0 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/ConfirmUserRegistrationTests.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/ConfirmUserRegistrationTests.cs
@@ -1,11 +1,11 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.GetUserRegistration;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
-using CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.ConfirmUserRegistration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.GetUserRegistration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork;
using NUnit.Framework;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.UserRegistrations
{
[TestFixture]
public class ConfirmUserRegistrationTests : TestBase
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/SendUserRegistrationConfirmationEmailTests.cs b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/SendUserRegistrationConfirmationEmailTests.cs
index ed2163247..641848e11 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/SendUserRegistrationConfirmationEmailTests.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/SendUserRegistrationConfirmationEmailTests.cs
@@ -1,11 +1,11 @@
using CompanyName.MyMeetings.BuildingBlocks.Application.Emails;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.SendUserRegistrationConfirmationEmail;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
-using CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.SendUserRegistrationConfirmationEmail;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork;
using NSubstitute.ReceivedExtensions;
using NUnit.Framework;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.UserRegistrations
{
[TestFixture]
public class SendUserRegistrationConfirmationEmailTests : TestBase
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationSampleData.cs b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationSampleData.cs
index 0cbe855eb..89283d314 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationSampleData.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationSampleData.cs
@@ -1,4 +1,4 @@
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.UserRegistrations
{
public struct UserRegistrationSampleData
{
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationTests.cs b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationTests.cs
index e01449241..947495393 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationTests.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationTests.cs
@@ -1,10 +1,10 @@
using System.Data.SqlClient;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.GetUserRegistration;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser;
-using CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.GetUserRegistration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork;
using NUnit.Framework;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.UserRegistrations
{
[TestFixture]
public class UserRegistrationTests : TestBase
diff --git a/src/Modules/UserAccess/Tests/IntegrationTests/Users/CreateUserTests.cs b/src/Modules/UserAccess/Tests/IntegrationTests/Users/CreateUserTests.cs
index 347eaa72a..322227599 100644
--- a/src/Modules/UserAccess/Tests/IntegrationTests/Users/CreateUserTests.cs
+++ b/src/Modules/UserAccess/Tests/IntegrationTests/Users/CreateUserTests.cs
@@ -1,11 +1,11 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.RegisterNewUser;
-using CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser;
-using CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.SeedWork;
-using CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.ConfirmUserRegistration;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.UserRegistrations.RegisterNewUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Application.Users.GetUser;
+using CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.UserRegistrations;
using NUnit.Framework;
-namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.Users
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.IntegrationTests.Users
{
[TestFixture]
public class CreateUserTests : TestBase
diff --git a/src/Modules/UserAccess/Tests/UnitTests/CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.csproj b/src/Modules/UserAccess/Tests/UnitTests/CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.csproj
similarity index 100%
rename from src/Modules/UserAccess/Tests/UnitTests/CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.csproj
rename to src/Modules/UserAccess/Tests/UnitTests/CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.csproj
diff --git a/src/Modules/UserAccess/Tests/UnitTests/SeedWork/DomainEventsTestHelper.cs b/src/Modules/UserAccess/Tests/UnitTests/SeedWork/DomainEventsTestHelper.cs
index ee6b1c113..84c3b0e99 100644
--- a/src/Modules/UserAccess/Tests/UnitTests/SeedWork/DomainEventsTestHelper.cs
+++ b/src/Modules/UserAccess/Tests/UnitTests/SeedWork/DomainEventsTestHelper.cs
@@ -2,7 +2,7 @@
using System.Reflection;
using CompanyName.MyMeetings.BuildingBlocks.Domain;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.SeedWork
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.SeedWork
{
public class DomainEventsTestHelper
{
diff --git a/src/Modules/UserAccess/Tests/UnitTests/SeedWork/TestBase.cs b/src/Modules/UserAccess/Tests/UnitTests/SeedWork/TestBase.cs
index 616ac79a6..7ae720c88 100644
--- a/src/Modules/UserAccess/Tests/UnitTests/SeedWork/TestBase.cs
+++ b/src/Modules/UserAccess/Tests/UnitTests/SeedWork/TestBase.cs
@@ -1,7 +1,7 @@
using CompanyName.MyMeetings.BuildingBlocks.Domain;
using NUnit.Framework;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.SeedWork
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.SeedWork
{
public abstract class TestBase
{
diff --git a/src/Modules/UserAccess/Tests/UnitTests/UserRegistrations/UserRegistrationTests.cs b/src/Modules/UserAccess/Tests/UnitTests/UserRegistrations/UserRegistrationTests.cs
index c05229164..ed6af0e03 100644
--- a/src/Modules/UserAccess/Tests/UnitTests/UserRegistrations/UserRegistrationTests.cs
+++ b/src/Modules/UserAccess/Tests/UnitTests/UserRegistrations/UserRegistrationTests.cs
@@ -1,12 +1,12 @@
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.SeedWork;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Rules;
-using CompanyName.MyMeetings.Modules.UserAccess.Domain.Users.Events;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.SeedWork;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Events;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UserRegistrations.Rules;
+using CompanyName.MyMeetings.Modules.UserAccessIS.Domain.Users.Events;
using NSubstitute;
using NUnit.Framework;
-namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.UserRegistrations
+namespace CompanyName.MyMeetings.Modules.UserAccessIS.Domain.UnitTests.UserRegistrations
{
[TestFixture]
public class UserRegistrationTests : TestBase
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommand.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommand.cs
new file mode 100644
index 000000000..20225af53
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommand.cs
@@ -0,0 +1,16 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+public class AccountLoginCommand : CommandBase
+{
+ public AccountLoginCommand(string login, string password)
+ {
+ Login = login;
+ Password = password;
+ }
+
+ public string Login { get; }
+
+ public string Password { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandHandler.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandHandler.cs
new file mode 100644
index 000000000..0c14f35c9
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandHandler.cs
@@ -0,0 +1,162 @@
+using System.Security.Claims;
+using CompanyName.MyMeetings.BuildingBlocks.Application.Emails;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+internal class AccountLoginCommandHandler : ICommandHandler
+{
+ private readonly IEmailSender _emailSender;
+ private readonly UserManager _userManager;
+ private readonly IdentityOptions _identityOptions;
+ private readonly ITokenClaimsService _tokenClaimsService;
+ private readonly IUserClaimsPrincipalFactory _userClaimsPrincipalFactory;
+
+ public AccountLoginCommandHandler(
+ IEmailSender emailSender,
+ UserManager userManager,
+ ITokenClaimsService tokenClaimsService,
+ IUserClaimsPrincipalFactory userClaimsPrincipalFactory)
+ {
+ _emailSender = emailSender;
+ _userManager = userManager;
+ _identityOptions = _userManager.Options;
+ _tokenClaimsService = tokenClaimsService;
+ _userClaimsPrincipalFactory = userClaimsPrincipalFactory;
+ }
+
+ public async Task Handle(AccountLoginCommand request, CancellationToken cancellationToken)
+ {
+ var response = new AuthenticationResult();
+
+ var user = await _userManager.FindByNameAsync(request.Login);
+ if (user != null && !await _userManager.IsLockedOutAsync(user))
+ {
+ if (await _userManager.HasPasswordAsync(user))
+ {
+ var passwordCheckSucceeded = await _userManager.CheckPasswordAsync(user, request.Password);
+ if (passwordCheckSucceeded)
+ {
+ // Reset failed account login attempts
+ await _userManager.ResetAccessFailedCountAsync(user);
+
+ // Check if user is allowed to login
+ if (_identityOptions.SignIn.RequireConfirmedEmail && !await _userManager.IsEmailConfirmedAsync(user))
+ {
+ if (!string.IsNullOrEmpty(user.Email))
+ {
+ var emailMessage = new EmailMessage(
+ user.Email!,
+ "MyMeetings user account not validated!",
+ $@"You cannot log in with this user account because the e-mail address you have entered has not yet been validated.\n\nUser name: {user.UserName}\nEmail: {user.Email}");
+
+ await _emailSender.SendEmail(emailMessage);
+ }
+
+ response.AddError(Errors.UserAccess.EmailNotConfirmed);
+ }
+ else
+ {
+ if (await _userManager.GetTwoFactorEnabledAsync(user))
+ {
+ var validProviders = await _userManager.GetValidTwoFactorProvidersAsync(user);
+
+ if (validProviders.Contains(_userManager.Options.Tokens.AuthenticatorTokenProvider))
+ {
+ response.StoreTwoFactorAuthentication(Generate2FA(user.Id, _userManager.Options.Tokens.AuthenticatorTokenProvider));
+ }
+ else if (validProviders.Contains("Email"))
+ {
+ var token = await _userManager.GenerateTwoFactorTokenAsync(user, "Email");
+
+ var emailMessage = new EmailMessage(
+ user.Email,
+ "MyMeetings Token",
+ "Here is your token which you need for the registration.\n\nToken: {token}");
+
+ await _emailSender.SendEmail(emailMessage);
+
+ response.StoreTwoFactorAuthentication(Generate2FA(user.Id, "Email"));
+ }
+ }
+ else
+ {
+ var userDto = new UserDto()
+ {
+ Id = user.Id,
+ Name = $"{user.Name}".Trim(),
+ UserName = user.UserName,
+ Email = user.Email,
+ Claims = _tokenClaimsService.GetUserClaims(user)
+ };
+
+ var tokens = _tokenClaimsService.GenerateTokens(user);
+ var principal = await _userClaimsPrincipalFactory.CreateAsync(user);
+
+ response.SetAuthenticatedUser(userDto, tokens.AccessToken, tokens.RefreshToken, principal);
+ }
+ }
+ }
+ else
+ {
+ // Increase the failed account login count
+ await _userManager.AccessFailedAsync(user);
+ if (await _userManager.IsLockedOutAsync(user))
+ {
+ await SendNotificationEmailAsync(user);
+ }
+
+ response.AddError(Errors.UserAccess.InvalidUserNameOrPassword);
+ }
+ }
+ else
+ {
+ var emailMessage = new EmailMessage(
+ user.Email,
+ "MyMeetings user account not enabled!",
+ $"You cannot log in with this user account because no password has been defined for this account.\n\nUser name: {user.UserName}\nEmail: {user.Email}");
+
+ await _emailSender.SendEmail(emailMessage);
+
+ response.AddError(Errors.UserAccess.LoginNotAllowed);
+ }
+ }
+ else
+ {
+ // Instead of returning an "User not found." error message return an more generic one.
+ response.AddError(Errors.UserAccess.InvalidUserNameOrPassword);
+ }
+
+ return response;
+ }
+
+ private static ClaimsPrincipal Generate2FA(Guid userId, string provider)
+ {
+ var identity = new ClaimsIdentity(
+ new List
+ {
+ new Claim("sub", userId.ToString()),
+ new Claim("amr", provider) // Authentication method reference
+ },
+ IdentityConstants.TwoFactorUserIdScheme);
+
+ return new ClaimsPrincipal(identity);
+ }
+
+ private async Task SendNotificationEmailAsync(ApplicationUser user)
+ {
+ if (!string.IsNullOrEmpty(user.Email))
+ {
+ var emailMessage = new EmailMessage(
+ user.Email,
+ "MyMeetings user account locked!",
+ $"Your user account has been blocked for security reasons.\n\nUser name: {user.UserName}\n\nThe account has been locked for {_identityOptions.Lockout.DefaultLockoutTimeSpan.Minutes}minutes because the password was entered incorrectly {_identityOptions.Lockout.MaxFailedAccessAttempts} times in a row. After this time, the lock is automatically removed.\n\nIf you are not responsible for locking the user account, please contact the administrator.");
+
+ await _emailSender.SendEmail(emailMessage);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandValidator.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandValidator.cs
new file mode 100644
index 000000000..048ea2653
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountLoginCommandValidator.cs
@@ -0,0 +1,12 @@
+using FluentValidation;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+public class AccountLoginCommandValidator : AbstractValidator
+{
+ public AccountLoginCommandValidator()
+ {
+ RuleFor(x => x.Login).CustomNotEmpty();
+ RuleFor(x => x.Password).CustomNotEmpty();
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommand.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommand.cs
new file mode 100644
index 000000000..c09ec6142
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommand.cs
@@ -0,0 +1,19 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+public class AccountTwoFactorLoginCommand : CommandBase
+{
+ public AccountTwoFactorLoginCommand(Guid userId, string provider, string token)
+ {
+ UserId = userId;
+ Provider = provider;
+ Token = token;
+ }
+
+ public Guid UserId { get; }
+
+ public string Provider { get; }
+
+ public string Token { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommandHandler.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommandHandler.cs
new file mode 100644
index 000000000..b9fb761b9
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/AccountTwoFactorLoginCommandHandler.cs
@@ -0,0 +1,57 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+internal class AccountTwoFactorLoginCommandHandler : ICommandHandler
+{
+ private readonly ITokenClaimsService _tokenClaimsService;
+ private readonly UserManager _userManager;
+ private readonly IUserClaimsPrincipalFactory _userClaimsPrincipalFactory;
+
+ public AccountTwoFactorLoginCommandHandler(
+ UserManager userManager,
+ ITokenClaimsService tokenClaimsService,
+ IUserClaimsPrincipalFactory userClaimsPrincipalFactory)
+ {
+ _userManager = userManager;
+ _tokenClaimsService = tokenClaimsService;
+ _userClaimsPrincipalFactory = userClaimsPrincipalFactory;
+ }
+
+ public async Task Handle(AccountTwoFactorLoginCommand request, CancellationToken cancellationToken)
+ {
+ var response = new AuthenticationResult();
+
+ var user = await _userManager.FindByIdAsync(request.UserId.ToString());
+ if (user is null)
+ {
+ response.AddError(Errors.General.NotFound(request.UserId, "User"));
+ return response;
+ }
+
+ var isValid = await _userManager.VerifyTwoFactorTokenAsync(user, request.Provider, request.Token);
+
+ if (isValid)
+ {
+ var userDto = new UserDto()
+ {
+ Id = user.Id,
+ Name = $"{user.FirstName} {user.LastName}",
+ UserName = user.UserName,
+ Email = user.Email,
+ Claims = _tokenClaimsService.GetUserClaims(user)
+ };
+
+ var tokens = _tokenClaimsService.GenerateTokens(user);
+ var principal = await _userClaimsPrincipalFactory.CreateAsync(user);
+
+ response.SetAuthenticatedUser(userDto, tokens.AccessToken, tokens.RefreshToken, principal);
+ }
+
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/AuthenticationResult.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/AuthenticationResult.cs
new file mode 100644
index 000000000..0a677d93d
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/AuthenticationResult.cs
@@ -0,0 +1,62 @@
+using System.Security.Claims;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+public class AuthenticationResult : Result
+{
+ public AuthenticationResult()
+ {
+ RequiresTwoFactor = false;
+ }
+
+ public bool IsAuthenticated => ClaimsPrincipal is not null;
+
+ public string? AccessToken { get; private set; }
+
+ public string? RefreshToken { get; private set; }
+
+ public bool RequiresTwoFactor { get; private set; }
+
+ public UserDto? User { get; private set; }
+
+ public ClaimsPrincipal? ClaimsPrincipal { get; private set; }
+
+ public void SetAuthenticatedUser(UserDto user, string accessToken, string refreshToken)
+ {
+ ArgumentNullException.ThrowIfNull(user, nameof(user));
+
+ User = user;
+ AccessToken = accessToken;
+ RefreshToken = refreshToken;
+ }
+
+ public void SetAuthenticatedUser(UserDto user, ClaimsPrincipal claimsPrincipal)
+ {
+ ArgumentNullException.ThrowIfNull(user, nameof(user));
+ ArgumentNullException.ThrowIfNull(claimsPrincipal, nameof(claimsPrincipal));
+
+ User = user;
+ ClaimsPrincipal = claimsPrincipal;
+ }
+
+ public void SetAuthenticatedUser(UserDto user, string accessToken, string refreshToken, ClaimsPrincipal claimsPrincipal)
+ {
+ SetAuthenticatedUser(user, accessToken, refreshToken);
+
+ ArgumentNullException.ThrowIfNull(claimsPrincipal, nameof(claimsPrincipal));
+
+ ClaimsPrincipal = claimsPrincipal;
+ }
+
+ public void StoreTwoFactorAuthentication(ClaimsPrincipal claimsPrincipal)
+ {
+ if (claimsPrincipal == null)
+ {
+ throw new ArgumentNullException(nameof(claimsPrincipal), "Missing the claims principal.");
+ }
+
+ RequiresTwoFactor = true;
+ ClaimsPrincipal = claimsPrincipal;
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommand.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommand.cs
new file mode 100644
index 000000000..333929ace
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommand.cs
@@ -0,0 +1,22 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login.External;
+
+public class ExternalAccountLoginCommand : CommandBase
+{
+ public ExternalAccountLoginCommand(string provider, string externalUserId, string emailAddress, bool autoCreateUser)
+ {
+ Provider = provider;
+ ExternalUserId = externalUserId;
+ EmailAddress = emailAddress;
+ AutoCreateUser = autoCreateUser;
+ }
+
+ public string Provider { get; }
+
+ public string ExternalUserId { get; }
+
+ public string EmailAddress { get; }
+
+ public bool AutoCreateUser { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommandHandler.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommandHandler.cs
new file mode 100644
index 000000000..44385e935
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/External/ExternalAccountLoginCommandHandler.cs
@@ -0,0 +1,76 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login.External;
+
+internal class ExternalAccountLoginCommandHandler : ICommandHandler
+{
+ private readonly UserManager _userManager;
+ private readonly ITokenClaimsService _tokenClaimsService;
+ private readonly IUserClaimsPrincipalFactory _userClaimsPrincipalFactory;
+
+ public ExternalAccountLoginCommandHandler(
+ UserManager userManager,
+ ITokenClaimsService tokenClaimsService,
+ IUserClaimsPrincipalFactory userClaimsPrincipalFactory)
+ {
+ _userManager = userManager;
+ _tokenClaimsService = tokenClaimsService;
+ _userClaimsPrincipalFactory = userClaimsPrincipalFactory;
+ }
+
+ public async Task Handle(ExternalAccountLoginCommand request, CancellationToken cancellationToken)
+ {
+ var response = new AuthenticationResult();
+
+ // Try to find the user by the provider and external user unique identifier
+ // This will return the user we have that is link to this external account
+ var user = await _userManager.FindByLoginAsync(request.Provider, request.ExternalUserId);
+
+ // If the user is null, so we have never seen this external user before
+ if (user is null)
+ {
+ // ... We have a few options, but in the case we have the user's email address
+ var email = request.EmailAddress;
+ if (!string.IsNullOrEmpty(email))
+ {
+ // we check if we can find an user by that email address
+ user = await _userManager.FindByEmailAsync(email);
+
+ // If we still have no user we are going to auto create the user if enabled
+ if (user == null)
+ {
+ if (!request.AutoCreateUser)
+ {
+ response.AddError(Errors.UserAccess.InvalidUserNameOrPassword);
+ return response;
+ }
+
+ user = new ApplicationUser(email) { Email = email };
+
+ // Create the user without a password
+ await _userManager.CreateAsync(user);
+ }
+
+ // Finally we have to link the user with the external account
+ await _userManager.AddLoginAsync(user, new UserLoginInfo(request.Provider, request.ExternalUserId, request.Provider));
+ }
+ }
+
+ var userDto = new UserDto()
+ {
+ Id = user!.Id,
+ Name = $"{user.Name}".Trim(),
+ UserName = user.UserName,
+ Email = user.Email,
+ Claims = _tokenClaimsService.GetUserClaims(user)
+ };
+
+ var principal = await _userClaimsPrincipalFactory.CreateAsync(user);
+ response.SetAuthenticatedUser(userDto, principal);
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/Login/UserDto.cs b/src/Modules/UserAccessMI/Application/Authentication/Login/UserDto.cs
new file mode 100644
index 000000000..60c5715a4
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/Login/UserDto.cs
@@ -0,0 +1,16 @@
+using System.Security.Claims;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.Login;
+
+public class UserDto
+{
+ public Guid Id { get; init; }
+
+ public string? UserName { get; init; } = null!;
+
+ public string? Name { get; init; }
+
+ public string? Email { get; init; }
+
+ public List? Claims { get; set; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommand.cs b/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommand.cs
new file mode 100644
index 000000000..93c1ba9e6
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommand.cs
@@ -0,0 +1,17 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RefreshToken;
+
+public class RefreshTokenCommand : CommandBase>
+{
+ public RefreshTokenCommand(string accessToken, string refreshToken)
+ {
+ AccessToken = accessToken;
+ RefreshToken = refreshToken;
+ }
+
+ public string AccessToken { get; }
+
+ public string RefreshToken { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommandHandler.cs b/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommandHandler.cs
new file mode 100644
index 000000000..912677df5
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/RefreshTokenCommandHandler.cs
@@ -0,0 +1,22 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CSharpFunctionalExtensions;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RefreshToken;
+
+internal class RefreshTokenCommandHandler : ICommandHandler>
+{
+ private readonly ITokenClaimsService _tokenService;
+
+ public RefreshTokenCommandHandler(ITokenClaimsService tokenService)
+ {
+ _tokenService = tokenService;
+ }
+
+ public async Task> Handle(RefreshTokenCommand request, CancellationToken cancellationToken)
+ {
+ return await _tokenService.GenerateNewTokensAsync(request.AccessToken, request.RefreshToken, cancellationToken)
+ .Map(tokens => new TokenDto(tokens.AccessToken, tokens.RefreshToken));
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/TokenDto.cs b/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/TokenDto.cs
new file mode 100644
index 000000000..7b3b10cd0
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/RefreshToken/TokenDto.cs
@@ -0,0 +1,3 @@
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RefreshToken;
+
+public record TokenDto(string AccessToken, string RefreshToken);
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/ForgotPasswordLinkResult.cs b/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/ForgotPasswordLinkResult.cs
new file mode 100644
index 000000000..9f210d27e
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/ForgotPasswordLinkResult.cs
@@ -0,0 +1,17 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RequestForgotPasswordLink;
+
+public class ForgotPasswordLinkResult : Result
+{
+ public ForgotPasswordLinkResult()
+ {
+ }
+
+ public ForgotPasswordLinkResult(string token)
+ {
+ Token = token;
+ }
+
+ public string? Token { get; set; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommand.cs b/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommand.cs
new file mode 100644
index 000000000..db9c8d97e
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommand.cs
@@ -0,0 +1,13 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RequestForgotPasswordLink;
+
+public class RequestForgotPasswordLinkCommand : CommandBase
+{
+ public RequestForgotPasswordLinkCommand(string emailAddress)
+ {
+ EmailAddress = emailAddress;
+ }
+
+ public string EmailAddress { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommandHandler.cs b/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommandHandler.cs
new file mode 100644
index 000000000..fe122a522
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/RequestForgotPasswordLink/RequestForgotPasswordLinkCommandHandler.cs
@@ -0,0 +1,41 @@
+using CompanyName.MyMeetings.BuildingBlocks.Application.Emails;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.RequestForgotPasswordLink;
+
+internal class RequestForgotPasswordLinkCommandHandler : ICommandHandler
+{
+ private readonly UserManager _userManager;
+ private readonly IEmailSender _emailSender;
+
+ public RequestForgotPasswordLinkCommandHandler(UserManager userManager, IEmailSender emailSender)
+ {
+ _userManager = userManager;
+ _emailSender = emailSender;
+ }
+
+ public async Task Handle(RequestForgotPasswordLinkCommand request, CancellationToken cancellationToken)
+ {
+ var user = await _userManager.FindByEmailAsync(request.EmailAddress);
+ if (user != null)
+ {
+ var token = await _userManager.GeneratePasswordResetTokenAsync(user);
+ return new ForgotPasswordLinkResult(token);
+ }
+
+ // email user and inform them that they do not have an account with that email address
+ var message = new EmailMessage(
+ request.EmailAddress,
+ "MyMeetings - Forgot password",
+ $"We could not find your account with the given email addess '{request.EmailAddress}'.\n\nPlease check if you registered with an different email address.");
+
+ await _emailSender.SendEmail(message);
+
+ var response = new ForgotPasswordLinkResult();
+ response.AddError(Errors.General.NotFound(request.EmailAddress, "User"));
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommand.cs b/src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommand.cs
new file mode 100644
index 000000000..ff6839e9f
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommand.cs
@@ -0,0 +1,20 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.ResetPassword;
+
+public class ResetPasswordCommand : CommandBase
+{
+ public ResetPasswordCommand(string token, string emailAddress, string password)
+ {
+ Token = token;
+ EmailAddress = emailAddress;
+ Password = password;
+ }
+
+ public string Token { get; }
+
+ public string EmailAddress { get; }
+
+ public string Password { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommandHandler.cs b/src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommandHandler.cs
new file mode 100644
index 000000000..12d5e5d4b
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authentication/ResetPassword/ResetPasswordCommandHandler.cs
@@ -0,0 +1,40 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authentication.ResetPassword;
+
+internal class ResetPasswordCommandHandler : ICommandHandler
+{
+ private readonly UserManager _userManager;
+
+ public ResetPasswordCommandHandler(UserManager userManager)
+ {
+ _userManager = userManager;
+ }
+
+ public async Task Handle(ResetPasswordCommand request, CancellationToken cancellationToken)
+ {
+ var user = await _userManager.FindByEmailAsync(request.EmailAddress);
+ if (user is null)
+ {
+ return Errors.General.NotFound(request.EmailAddress, "User");
+ }
+
+ var result = await _userManager.ResetPasswordAsync(user, request.Token, request.Password);
+ if (!result.Succeeded)
+ {
+ return result.Errors.Map().Combine();
+ }
+
+ // Check if we have to unlock the user account
+ if (await _userManager.IsLockedOutAsync(user))
+ {
+ await _userManager.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow);
+ }
+
+ return Result.Ok();
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQuery.cs b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQuery.cs
new file mode 100644
index 000000000..a3bf1553c
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQuery.cs
@@ -0,0 +1,14 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions.ByUserId;
+
+public class GetPermissionsQuery : QueryBase>>
+{
+ public GetPermissionsQuery(Guid userId)
+ {
+ UserId = userId;
+ }
+
+ public Guid UserId { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQueryHandler.cs b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQueryHandler.cs
new file mode 100644
index 000000000..47335c530
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/ByUserId/GetPermissionsQueryHandler.cs
@@ -0,0 +1,84 @@
+using System.Security.Claims;
+using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Dapper;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions.ByUserId;
+
+internal class GetPermissionsQueryHandler : IQueryHandler>>
+{
+ private readonly UserManager _userManager;
+ private readonly ISqlConnectionFactory _connectionFactory;
+ private readonly RoleManager _roleManager;
+
+ public GetPermissionsQueryHandler(
+ UserManager userManager,
+ RoleManager roleManager,
+ ISqlConnectionFactory connectionFactory)
+ {
+ _userManager = userManager;
+ _roleManager = roleManager;
+ _connectionFactory = connectionFactory;
+ }
+
+ public async Task>> Handle(GetPermissionsQuery request, CancellationToken cancellationToken)
+ {
+ var user = await _userManager.FindByIdAsync(request.UserId.ToString());
+ if (user is null)
+ {
+ return Errors.General.NotFound(request.UserId, "User");
+ }
+
+ var roleNames = await _userManager.GetRolesAsync(user);
+ var roleClaims = await GetClaimsAsync(roleNames);
+ var userClaims = await _userManager.GetClaimsAsync(user);
+ var claims = roleClaims.Union(userClaims)
+ .Where(x => x.Type == CustomClaimTypes.Permission)
+ .Select(x => x.Value)
+ .ToList();
+
+ // Short circuit
+ if (!claims.Any())
+ {
+ return Result.Ok(Enumerable.Empty());
+ }
+
+ using (var connection = _connectionFactory.CreateNewConnection())
+ {
+ string query = $@"
+ SELECT [P].[Code] AS {nameof(PermissionDto.Code)},
+ [P].[Name] AS {nameof(PermissionDto.Name)},
+ [P].[Description] AS {nameof(PermissionDto.Description)}
+ FROM [usersmi].[Permissions] AS [P]
+ WHERE [P].[Code] IN @Claims";
+
+ var permissions = await connection.QueryAsync(
+ new CommandDefinition(query, new { Claims = claims }, cancellationToken: cancellationToken));
+
+ return Result.Ok(permissions);
+ }
+ }
+
+ private async Task> GetClaimsAsync(IEnumerable roleNames)
+ {
+ var claims = new List();
+ foreach (var roleName in roleNames)
+ {
+ var role = await _roleManager.FindByNameAsync(roleName);
+ if (role is null)
+ {
+ continue;
+ }
+
+ var roleClaims = await _roleManager.GetClaimsAsync(role);
+ claims.AddRange(roleClaims ?? Enumerable.Empty());
+ }
+
+ return claims;
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQuery.cs b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQuery.cs
new file mode 100644
index 000000000..7bcaca018
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQuery.cs
@@ -0,0 +1,8 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions.Directory;
+
+public class GetPermissionsQuery : QueryBase>>
+{
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQueryHandler.cs b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQueryHandler.cs
new file mode 100644
index 000000000..e7a245010
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/Directory/GetPermissionsQueryHandler.cs
@@ -0,0 +1,31 @@
+using CompanyName.MyMeetings.BuildingBlocks.Application.Data;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using Dapper;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions.Directory;
+
+internal class GetPermissionsQueryHandler : IQueryHandler>>
+{
+ private readonly ISqlConnectionFactory _connectionFactory;
+
+ public GetPermissionsQueryHandler(ISqlConnectionFactory connectionFactory)
+ {
+ _connectionFactory = connectionFactory;
+ }
+
+ public async Task>> Handle(GetPermissionsQuery request, CancellationToken cancellationToken)
+ {
+ using (var connection = _connectionFactory.CreateNewConnection())
+ {
+ string query = $@"
+ SELECT [P].[Code] AS {nameof(PermissionDto.Code)},
+ [P].[Name] AS {nameof(PermissionDto.Name)},
+ [P].[Description] AS {nameof(PermissionDto.Description)}
+ FROM [usersmi].[Permissions] AS [P]";
+
+ var permissions = await connection.QueryAsync(query, cancellationToken);
+ return Result.Ok(permissions);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/PermissionDto.cs b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/PermissionDto.cs
new file mode 100644
index 000000000..6b08782f2
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetPermissions/PermissionDto.cs
@@ -0,0 +1,10 @@
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetPermissions;
+
+public class PermissionDto
+{
+ public string Code { get; set; } = null!;
+
+ public string Name { get; set; } = null!;
+
+ public string? Description { get; set; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQuery.cs b/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQuery.cs
new file mode 100644
index 000000000..c1de798c6
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQuery.cs
@@ -0,0 +1,14 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetUserRoles;
+
+public class GetUserRolesQuery : QueryBase>>
+{
+ public GetUserRolesQuery(Guid userId)
+ {
+ UserId = userId;
+ }
+
+ public Guid UserId { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQueryHandler.cs b/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQueryHandler.cs
new file mode 100644
index 000000000..d6b1e7106
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/GetUserRolesQueryHandler.cs
@@ -0,0 +1,44 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Queries;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.Users;
+using Microsoft.AspNetCore.Identity;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetUserRoles;
+
+internal class GetUserRolesQueryHandler : IQueryHandler>>
+{
+ private readonly UserManager _userManager;
+ private readonly RoleManager _roleManager;
+
+ public GetUserRolesQueryHandler(UserManager userManager, RoleManager roleManager)
+ {
+ _userManager = userManager;
+ _roleManager = roleManager;
+ }
+
+ public async Task>> Handle(GetUserRolesQuery request, CancellationToken cancellationToken)
+ {
+ var user = await _userManager.FindByIdAsync(request.UserId.ToString());
+ if (user is null)
+ {
+ return Errors.General.NotFound(request.UserId, "User");
+ }
+
+ var roleNames = await _userManager.GetRolesAsync(user);
+ if (!roleNames.Any())
+ {
+ return Result.Ok(Enumerable.Empty());
+ }
+
+ var roles = (from role in _roleManager.Roles
+ where roleNames.Contains(role.Name ?? string.Empty)
+ select new RoleDto()
+ {
+ Id = role.Id,
+ Name = role.Name
+ }).ToList();
+
+ return Result.Ok(roles.AsEnumerable());
+ }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/RoleDto.cs b/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/RoleDto.cs
new file mode 100644
index 000000000..8d38d3fb0
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Authorization/GetUserRoles/RoleDto.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Authorization.GetUserRoles;
+
+public class RoleDto
+{
+ public string Id { get; set; } = null!;
+
+ public string? Name { get; set; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/CompanyName.MyMeetings.Modules.UserAccessMI.Application.csproj b/src/Modules/UserAccessMI/Application/CompanyName.MyMeetings.Modules.UserAccessMI.Application.csproj
new file mode 100644
index 000000000..4bb97b9ec
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/CompanyName.MyMeetings.Modules.UserAccessMI.Application.csproj
@@ -0,0 +1,11 @@
+
+
+ enable
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandHandler.cs b/src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandHandler.cs
new file mode 100644
index 000000000..ca412fec0
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandHandler.cs
@@ -0,0 +1,15 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using MediatR;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+
+public interface ICommandHandler : IRequestHandler
+ where TCommand : ICommand
+{
+}
+
+public interface ICommandHandler :
+ IRequestHandler
+ where TCommand : ICommand
+{
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandsScheduler.cs b/src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandsScheduler.cs
new file mode 100644
index 000000000..21b2aed75
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Configuration/Commands/ICommandsScheduler.cs
@@ -0,0 +1,10 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+
+public interface ICommandsScheduler
+{
+ Task EnqueueAsync(ICommand command);
+
+ Task EnqueueAsync(ICommand command);
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Configuration/Commands/InternalCommandBase.cs b/src/Modules/UserAccessMI/Application/Configuration/Commands/InternalCommandBase.cs
new file mode 100644
index 000000000..7680c5da8
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Configuration/Commands/InternalCommandBase.cs
@@ -0,0 +1,28 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Commands;
+
+public abstract class InternalCommandBase : ICommand
+{
+ protected InternalCommandBase(Guid id)
+ {
+ Id = id;
+ }
+
+ public Guid Id { get; }
+}
+
+public abstract class InternalCommandBase : ICommand
+{
+ protected InternalCommandBase()
+ {
+ Id = Guid.NewGuid();
+ }
+
+ protected InternalCommandBase(Guid id)
+ {
+ Id = id;
+ }
+
+ public Guid Id { get; }
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Configuration/Queries/IQueryHandler.cs b/src/Modules/UserAccessMI/Application/Configuration/Queries/IQueryHandler.cs
new file mode 100644
index 000000000..7bc5cea98
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Configuration/Queries/IQueryHandler.cs
@@ -0,0 +1,10 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Application.Contracts;
+using MediatR;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Queries;
+
+public interface IQueryHandler :
+ IRequestHandler
+ where TQuery : IQuery
+{
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Configuration/Results/IResult.cs b/src/Modules/UserAccessMI/Application/Configuration/Results/IResult.cs
new file mode 100644
index 000000000..bf34baa8d
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Configuration/Results/IResult.cs
@@ -0,0 +1,26 @@
+using CompanyName.MyMeetings.Modules.UserAccessMI.Domain.ErrorHandling;
+
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+
+public interface IResult
+{
+ ResultStatus Status { get; }
+
+ IReadOnlyList Errors { get; }
+
+ bool HasError { get; }
+
+ IResult AddError(Error error);
+
+ IResult Forbidden();
+
+ IResult Forbidden(string? message);
+
+ IResult Forbidden(Error error);
+
+ IResult NotFound();
+
+ IResult NotFound(string message);
+
+ IResult NotFound(Error error);
+}
\ No newline at end of file
diff --git a/src/Modules/UserAccessMI/Application/Configuration/Results/IResultOfT.cs b/src/Modules/UserAccessMI/Application/Configuration/Results/IResultOfT.cs
new file mode 100644
index 000000000..1776d2a46
--- /dev/null
+++ b/src/Modules/UserAccessMI/Application/Configuration/Results/IResultOfT.cs
@@ -0,0 +1,8 @@
+namespace CompanyName.MyMeetings.Modules.UserAccessMI.Application.Configuration.Results;
+
+#pragma warning disable SA1649 // File name should match first type name
+public interface IResult