diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/IntegrationEventHandlers/UserCreatedIntegrationEventHandler.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/IntegrationEventHandlers/UserCreatedIntegrationEventHandler.cs new file mode 100644 index 00000000..e1cbae5e --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/IntegrationEventHandlers/UserCreatedIntegrationEventHandler.cs @@ -0,0 +1,13 @@ +using Modules.TenantIdentity.IntegrationEvents; +using Shared.Features.CQRS.IntegrationEvent; + +namespace Modules.Subscriptions.Features.Agregates.StripeCustomerAggregate.Aplication.IntegrationEventHandlers +{ + public class UserCreatedIntegrationEventHandler : IIntegrationEventHandler + { + public async Task HandleAsync(UserCreatedIntegrationEvent userCreatedIntegrationEvent, CancellationToken cancellation) + { + + } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/IntegrationEventHandlers/UserUpdatedIntegrationEventHandler.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/IntegrationEventHandlers/UserUpdatedIntegrationEventHandler.cs new file mode 100644 index 00000000..80b23a19 --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/IntegrationEventHandlers/UserUpdatedIntegrationEventHandler.cs @@ -0,0 +1,13 @@ +using Modules.TenantIdentity.IntegrationEvents; +using Shared.Features.CQRS.IntegrationEvent; + +namespace Modules.Subscriptions.Features.Agregates.StripeCustomerAggregate.Aplication.IntegrationEventHandlers +{ + public class UserUpdatedIntegrationEventHandler : IIntegrationEventHandler + { + public async Task HandleAsync(UserEmailUpdatedIntegrationEvent userEmailUpdatedIntegrationEvent, CancellationToken cancellationToken) + { + + } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/Queries/GetStripeCustomer.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/Queries/GetStripeCustomer.cs new file mode 100644 index 00000000..932e6042 --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/Aplication/Queries/GetStripeCustomer.cs @@ -0,0 +1,10 @@ +using Modules.Subscriptions.Features.Agregates.StripeCustomerAggregate; +using Shared.Features.CQRS.Query; + +namespace Modules.Subscriptions.Features.Agregates.StripeCustomerAggregate.Aplication.Queries +{ + public class GetStripeCustomer : IQuery + { + public string StripeCustomerId { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/StripeCustomer.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/StripeCustomer.cs new file mode 100644 index 00000000..4e6b67bd --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeCustomerAggregate/StripeCustomer.cs @@ -0,0 +1,10 @@ +using Shared.Features.DomainKernel; + +namespace Modules.Subscriptions.Features.Agregates.StripeCustomerAggregate +{ + public class StripeCustomer : AggregateRoot + { + public Guid UserId { get; set; } + public string StripeCustomerId { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/CreateSubscriptionForTenant.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/CreateSubscriptionForTenant.cs new file mode 100644 index 00000000..a4552d9d --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/CreateSubscriptionForTenant.cs @@ -0,0 +1,10 @@ +using Shared.Features.CQRS.Command; + +namespace Modules.Subscriptions.Features.Agregates.StripeSubscriptionAggregate.Application.Commands +{ + public class CreateSubscriptionForTenant : ICommand + { + public Guid TenantId { get; set; } + public Stripe.Subscription Subscription { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/DeleteSubscription.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/DeleteSubscription.cs new file mode 100644 index 00000000..60044631 --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/DeleteSubscription.cs @@ -0,0 +1,9 @@ +using Shared.Features.CQRS.Command; + +namespace Modules.Subscriptions.Features.Agregates.StripeSubscriptionAggregate.Application.Commands +{ + public class DeleteSubscription : ICommand + { + public Stripe.Subscription Subscription { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/UpdateSubscription.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/UpdateSubscription.cs new file mode 100644 index 00000000..3540c6d0 --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Commands/UpdateSubscription.cs @@ -0,0 +1,9 @@ +using Shared.Features.CQRS.Command; + +namespace Modules.Subscriptions.Features.Agregates.StripeSubscriptionAggregate.Application.Commands +{ + public class UpdateSubscription : ICommand + { + public Stripe.Subscription Subscription { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Queries/GetStripeCheckoutSession.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Queries/GetStripeCheckoutSession.cs new file mode 100644 index 00000000..faf78e66 --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/Application/Queries/GetStripeCheckoutSession.cs @@ -0,0 +1,9 @@ +using Shared.Features.CQRS.Query; + +namespace Modules.Subscriptions.Features.Agregates.StripeSubscriptionAggregate.Application.Queries +{ + public class GetStripeCheckoutSession : IQuery + { + public string SessionId { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/StripeSubscription.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/StripeSubscription.cs new file mode 100644 index 00000000..e59b779d --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/StripeSubscription.cs @@ -0,0 +1,14 @@ +using Modules.Subscriptions.Features.Agregates.StripeCustomerAggregate; +using Shared.Features.DomainKernel; +using Shared.Kernel.BuildingBlocks.Authorization; + +namespace Modules.Subscriptions.Features.Agregates.StripeSubscriptionAggregate +{ + public class StripeSubscription : AggregateRoot + { + public StripeCustomer StripeCustomer { get; set; } + public DateTime ExpirationDate { get; set; } + public SubscriptionPlanType PlanType { get; set; } + public SubscriptionStatus Status { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/StripeSubscriptionPlan.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/StripeSubscriptionPlan.cs new file mode 100644 index 00000000..a7d1d8fc --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/StripeSubscriptionPlan.cs @@ -0,0 +1,10 @@ +using Shared.Kernel.BuildingBlocks.Authorization; + +namespace Modules.Subscriptions.Features.Agregates.SubscriptionAggregate +{ + public class StripeSubscriptionPlan + { + public string StripePriceId { get; set; } + public SubscriptionPlanType Type { get; set; } + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/SubscriptionStatus.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/SubscriptionStatus.cs new file mode 100644 index 00000000..e6ff36cf --- /dev/null +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Agregates/StripeSubscriptionAggregate/SubscriptionStatus.cs @@ -0,0 +1,10 @@ +namespace Modules.Subscriptions.Features.Agregates.StripeSubscriptionAggregate +{ + public enum SubscriptionStatus + { + Active, + Canceled, + Trialing, + Unpaid + } +} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/CreateSubscriptionCommand.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/CreateSubscriptionCommand.cs deleted file mode 100644 index 60dc5e39..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/CreateSubscriptionCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Shared.Features.CQRS.Command; - -namespace Modules.Subscriptions.Features.Commands -{ - public class CreateSubscriptionCommand : ICommand - { - public Subscription Subscription { get; set; } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/DeleteSubscriptionCommand.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/DeleteSubscriptionCommand.cs deleted file mode 100644 index 143c1192..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/DeleteSubscriptionCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Shared.Features.CQRS.Command; - -namespace Modules.Subscriptions.Features.Commands -{ - public class DeleteSubscriptionCommand : ICommand - { - public Subscription Subscription { get; set; } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/SubscriptionTrialEndedCommand.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/SubscriptionTrialEndedCommand.cs deleted file mode 100644 index 7deb033f..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/SubscriptionTrialEndedCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Shared.Features.CQRS.Command; - -namespace Modules.Subscriptions.Features.Commands -{ - public class SubscriptionTrialEndedCommand : ICommand - { - public Subscription Subscription { get; set; } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/UpdateSubscriptionCommand.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/UpdateSubscriptionCommand.cs deleted file mode 100644 index 48192033..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Commands/UpdateSubscriptionCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Shared.Features.CQRS.Command; - -namespace Modules.Subscriptions.Features.Commands -{ - public class UpdateSubscriptionCommand : ICommand - { - public Subscription Subscription { get; set; } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeCustomerService.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeCustomerService.cs deleted file mode 100644 index d20d1d8b..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeCustomerService.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Modules.Subscriptions.Features.Services.Interfaces -{ - public interface IStripeCustomerService - { - Task CreateStripeCustomerAsync(string userName, string emailAddress); - Task DeleteStripeCustomerAsync(string stripeCustomerId); - Task UpdateStripeCustomerAsync(string stripeCustomerId); - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeSessionService.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeSessionService.cs deleted file mode 100644 index 1919b553..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeSessionService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Modules.Subscriptions.Features.Configuration; - -namespace Modules.Subscriptions.Features.Services.Interfaces -{ - public interface IStripeSessionService - { - Task GetStripeCheckoutSessionAsync(string id); - Task CreateBillingPortalSessionAsync(string redirectBaseUrl, string stripeCustomerId); - Task CreateCheckoutSessionAsync(string redirectBaseUrl, string stripeCustomerId, Guid tenantId, StripeSubscriptionType stripeSubscription); - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeSubscriptionService.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeSubscriptionService.cs deleted file mode 100644 index 9de4fb25..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/Interfaces/IStripeSubscriptionService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Modules.Subscriptions.Features.Configuration; - -namespace Modules.Subscriptions.Features.Services.Interfaces -{ - public interface IStripeSubscriptionService - { - StripeSubscriptionType GetSubscriptionType(SubscriptionPlanType subscriptionPlanType); - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeCustomerService.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeCustomerService.cs deleted file mode 100644 index 62a1009a..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeCustomerService.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Modules.Subscriptions.Features.Services.Interfaces; - -namespace Modules.Subscriptions.Features.Services -{ - public class StripeCustomerService : IStripeCustomerService - { - public Task CreateStripeCustomerAsync(string userName, string emailAddress) - { - return new CustomerService().CreateAsync(new CustomerCreateOptions { Name = userName, Email = emailAddress }); - } - - public Task DeleteStripeCustomerAsync(string stripeCustomerId) - { - return new CustomerService().DeleteAsync(stripeCustomerId); - } - - public Task UpdateStripeCustomerAsync(string stripeCustomerId) - { - return new CustomerService().UpdateAsync(stripeCustomerId, new CustomerUpdateOptions { Name = stripeCustomerId }); - } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeSessionService.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeSessionService.cs deleted file mode 100644 index 1083b911..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeSessionService.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Modules.Subscriptions.Features.Services.Interfaces; -using Modules.Subscriptions.Features.Configuration; - -namespace Modules.Subscriptions.Features.Services -{ - public class StripeSessionService : IStripeSessionService - { - public async Task CreateBillingPortalSessionAsync(string redirectBaseUrl, string stripeCustomerId) - { - var options = new Stripe.BillingPortal.SessionCreateOptions - { - Customer = stripeCustomerId, - ReturnUrl = redirectBaseUrl - }; - var service = new Stripe.BillingPortal.SessionService(); - Stripe.BillingPortal.Session session = await service.CreateAsync(options); - return session; - } - - public async Task CreateCheckoutSessionAsync(string redirectBaseUrl, string user, Guid tenantId, StripeSubscriptionType stripeSubscription) - { - var options = new SessionCreateOptions - { - PaymentMethodTypes = new List - { - "card", - }, - Customer = user.StripeCustomerId, - //CustomerEmail = user.Email, - //ClientReferenceId = user.Id.ToString(), - LineItems = new List - { - new SessionLineItemOptions - { - Price = stripeSubscription.StripePriceId, - Quantity = 1 - } - }, - Mode = "subscription", - SuccessUrl = redirectBaseUrl + "/ManageTeam", - CancelUrl = redirectBaseUrl + "/ManageTeam", - SubscriptionData = new SessionSubscriptionDataOptions - { - Metadata = new Dictionary - { - ["TenantId"] = tenantId.ToString(), - }, - TrialPeriodDays = stripeSubscription.TrialPeriodDays - } - }; - var service = new SessionService(); - Session session = await service.CreateAsync(options); - return session; - } - - public async Task GetStripeCheckoutSessionAsync(string id) - { - var session = await new SessionService().GetAsync(id); - return session; - } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeSubscriptionTypeService.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeSubscriptionTypeService.cs deleted file mode 100644 index 00cda6ce..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/Services/StripeSubscriptionTypeService.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Modules.Subscriptions.Features.Services.Interfaces; -using Modules.Subscriptions.Features.Configuration; -using Shared.Kernel.BuildingBlocks.Auth.DomainKernel; - -namespace Modules.Subscriptions.Features.Services -{ - public class StripeSubscriptionTypeService : IStripeSubscriptionService - { - private List subscriptions; - public StripeSubscriptionTypeService() - { - subscriptions = new List() - { - new StripeSubscriptionType - { - Type = SubscriptionPlanType.Professional, - TrialPeriodDays = 7, - StripePriceId = "price_1KYcx5EhLcfJYVVFmQGwWRdb" - }, - new StripeSubscriptionType - { - Type = SubscriptionPlanType.Enterprise, - TrialPeriodDays = 7, - StripePriceId = "price_1KYd0eEhLcfJYVVF7YWjH5Cf" - } - }; - } - public StripeSubscriptionType GetSubscriptionType(SubscriptionPlanType subscriptionPlanType) - { - return subscriptions.Single(s => s.Type == subscriptionPlanType); - } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/StripeIntegrationException.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/StripeIntegrationException.cs deleted file mode 100644 index 08e236f9..00000000 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Features/StripeIntegrationException.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Shared.Modules.Layers.Features.StripeIntegration -{ - public class StripeIntegrationException : Exception - { - public StripeIntegrationException(string message) : base(message) - { - - } - } -} diff --git a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Infrastructure/Configuration/StripeSubscriptionType.cs b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Infrastructure/Configuration/StripeSubscriptionType.cs index 9abf5768..2eb83812 100644 --- a/Source/Modules/Subscription/Features/Modules.Subscription.Features/Infrastructure/Configuration/StripeSubscriptionType.cs +++ b/Source/Modules/Subscription/Features/Modules.Subscription.Features/Infrastructure/Configuration/StripeSubscriptionType.cs @@ -1,4 +1,6 @@ -namespace Modules.Subscriptions.Features.Configuration +using Shared.Kernel.BuildingBlocks.Auth.DomainKernel; + +namespace Modules.Subscriptions.Features.Configuration { public class StripeSubscriptionType { diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Application/Queries/GetTenantMembershipQuery.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Application/Queries/GetTenantMembershipQuery.cs index 9ce802a8..11216e6e 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Application/Queries/GetTenantMembershipQuery.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Application/Queries/GetTenantMembershipQuery.cs @@ -1,5 +1,5 @@ using Modules.TenantIdentity.Features.Aggregates.TenantAggregate; -using Modules.TenantIdentity.Features.EFCore; +using Modules.TenantIdentity.Features.Infrastructure.EFCore; using Shared.Features.CQRS.Query; using System; using System.Linq; diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Tenant.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Tenant.cs index 35fdae13..dc99fc84 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Tenant.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/Tenant.cs @@ -7,8 +7,7 @@ namespace Modules.TenantIdentity.Features.Aggregates.TenantAggregate { - [AggregateRoot] - public class Tenant : Entity + public class Tenant : AggregateRoot { private Tenant() { } public Tenant(string name) @@ -20,7 +19,6 @@ public Tenant(IServiceProvider serviceProvider) } - public override Guid TenantId { get => base.TenantId; } public string Name { get; set; } public TenantStyling Styling { get; set; } public TenantSettings Settings { get; set; } @@ -46,7 +44,7 @@ public void AddUser(Guid userId, TenantRole role) memberships.Add(new TenantMembership(userId, role)); } } - public void ChangeRoleOfMember(Guid userId, Role newRole) + public void ChangeRoleOfMember(Guid userId, TenantRole newRole) { TenantAuthorizationService.ThrowIfUserIsNotInRole(TenantRole.Admin); @@ -67,7 +65,7 @@ public void RemoveUser(Guid userId) memberships.Remove(memberships.Single(m => m.UserId == userId)); } - public void InviteUserToRole(Guid userId, Role role) + public void InviteUserToRole(Guid userId, TenantRole role) { TenantAuthorizationService.ThrowIfUserIsNotInRole(TenantRole.Admin); diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/TenantSubscription.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/TenantSubscription.cs index 27cf7755..6b8d2749 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/TenantSubscription.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/TenantAggregate/TenantSubscription.cs @@ -1,4 +1,5 @@ using Shared.Features.DomainKernel; +using Shared.Kernel.BuildingBlocks.Auth.DomainKernel; using System; namespace Modules.TenantIdentity.Features.Aggregates.TenantAggregate @@ -9,6 +10,5 @@ public class TenantSubscription : Entity public DateTime PeriodStart { get; set; } public DateTime PeriodEnd { get; set; } public SubscriptionPlanType SubscriptionPlanType { get; set; } - public SubscriptionStatus Status { get; set; } } } diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/CreateNewUser.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/CreateNewUser.cs new file mode 100644 index 00000000..c57933c3 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/CreateNewUser.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Identity; +using Shared.Features.CQRS.Command; +using System.Threading; + +namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Commands +{ + public class CreateNewUser : ICommand + { + public ApplicationUser User { get; set; } + public ExternalLoginInfo LoginInfo { get; set; } + } + public class CreateNewUserCommandHandler : ICommandHandler + { + private readonly UserManager userManager; + public CreateNewUserCommandHandler(UserManager userManager) + { + this.userManager = userManager; + } + + public async Task HandleAsync(CreateNewUser command, CancellationToken cancellationToken) + { + await userManager.CreateAsync(command.User); + } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/CreateUserCommand.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/CreateUserCommand.cs deleted file mode 100644 index 2220311c..00000000 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/CreateUserCommand.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Modules.TenantIdentity.Features.Aggregates.UserAggregate; -using Shared.Features.CQRS.Command; -using System.Threading; -using System.Threading.Tasks; - -namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Commands -{ - public class CreateUserCommand : ICommand - { - public ApplicationUser User { get; set; } - public ExternalLoginInfo LoginInfo { get; set; } - } - - public class CreateUserCommandHandler : ICommandHandler - { - private readonly SignInManager signInManager; - private readonly ApplicationUserManager userManager; - private readonly ICommandDispatcher commandDispatcher; - - public CreateUserCommandHandler(SignInManager signInManager, ApplicationUserManager userManager, ICommandDispatcher commandDispatcher, IStripeCustomerService stripeCustomerService) - { - this.signInManager = signInManager; - this.userManager = userManager; - this.commandDispatcher = commandDispatcher; - } - public async Task HandleAsync(CreateUserCommand command, CancellationToken cancellationToken) - { - var result = await userManager.CreateAsync(command.User); - - if (result.Succeeded) - { - await userManager.AddLoginAsync(command.User, command.LoginInfo); - await signInManager.SignInAsync(command.User, isPersistent: false, command.LoginInfo.LoginProvider); - - //var stripeCustomer = await stripeCustomerService.CreateStripeCustomerAsync(command.User.UserName, command.User.Email); - //command.User.StripeCustomerId = stripeCustomer.Id; - - //await userManager.UpdateAsync(command.User); - } - } - } -} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/SetSelectedTenantForUser.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/SetSelectedTenantForUser.cs new file mode 100644 index 00000000..1a88809a --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/SetSelectedTenantForUser.cs @@ -0,0 +1,34 @@ +using Modules.TenantIdentity.Features.Infrastructure.EFCore; +using Shared.Features.CQRS.Command; +using System.Threading; + +namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Commands +{ + public class SetSelectedTenantForUser : ICommand + { + public Guid SelectedTenantId { get; set; } + public Guid UserId { get; set; } + } + public class SetSelectedTenantForUserHandler : ICommandHandler + { + private readonly TenantIdentityDbContext tenantIdentityDbContext; + public SetSelectedTenantForUserHandler(TenantIdentityDbContext tenantIdentityDbContext) + { + this.tenantIdentityDbContext = tenantIdentityDbContext; + } + + public async Task HandleAsync(SetSelectedTenantForUser command, CancellationToken cancellationToken) + { + var user = await tenantIdentityDbContext.GetUserByIdAsync(command.UserId); + + if (user.SelectedTenantId == command.SelectedTenantId) + { + return; + } + + user.SelectedTenantId = command.SelectedTenantId; + + await tenantIdentityDbContext.SaveChangesAsync(cancellationToken); + } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/UpdateUser.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/UpdateUser.cs new file mode 100644 index 00000000..70dd0a69 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/UpdateUser.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Http; +using Shared.Features.CQRS.Command; + +namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Commands +{ + public class UpdateUser : ICommand + { + public string UserName { get; set; } + public IFormFile ProfilePicture { get; set; } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/UpdateUserCommand.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/UpdateUserCommand.cs deleted file mode 100644 index 0766a057..00000000 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Commands/UpdateUserCommand.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Commands -{ - public class UpdateUserCommand : ICommand - { - } -} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetClaimsForUser.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetClaimsForUser.cs index 9634cf2d..bdc382f5 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetClaimsForUser.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetClaimsForUser.cs @@ -1,48 +1,50 @@ -using Modules.TenantIdentity.Features.Aggregates.UserAggregate; +using Modules.TenantIdentity.Features.Infrastructure.EFCore; using Shared.Features.CQRS.Query; using Shared.SharedKernel.Constants; +using System; using System.Collections.Generic; +using System.Linq; using System.Security.Claims; -using System.Threading.Tasks; using System.Threading; -using Modules.TenantIdentity.Features.Aggregates.TenantAggregate.Application.Queries; -using Modules.TenantIdentity.Features.Aggregates.TenantAggregate; +using System.Threading.Tasks; namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Queries { public class GetClaimsForUser : IQuery> { - public ApplicationUser User { get; set; } + public Guid UserId { get; set; } } - public class GetClaimsForUserQueryHandler : IQueryHandler> + public class ClaimsForUserQueryHandler : IQueryHandler> { private readonly IQueryDispatcher queryDispatcher; - public GetClaimsForUserQueryHandler(IQueryDispatcher queryDispatcher) + private readonly TenantIdentityDbContext tenantIdentityDbContext; + + public ClaimsForUserQueryHandler(IQueryDispatcher queryDispatcher, TenantIdentityDbContext tenantIdentityDbContext) { this.queryDispatcher = queryDispatcher; + this.tenantIdentityDbContext = tenantIdentityDbContext; } public async Task> HandleAsync(GetClaimsForUser query, CancellationToken cancellation) { + var user = await tenantIdentityDbContext.GetUserByIdAsync(query.UserId); + List claims = new List { - new Claim(ClaimConstants.UserNameClaimType, query.User.UserName), - new Claim(ClaimConstants.UserIdClaimType, query.User.Id.ToString()), - new Claim(ClaimConstants.EmailClaimType, query.User.Email), - new Claim(ClaimConstants.PictureClaimType, query.User.PictureUri) + new Claim(ClaimConstants.UserNameClaimType, user.UserName), + new Claim(ClaimConstants.UserIdClaimType, user.Id.ToString()), + new Claim(ClaimConstants.EmailClaimType, user.Email), + new Claim(ClaimConstants.PictureClaimType, user.PictureUri) }; - var tenantByIdQuery = new GetTenantById() { TenantId = query.User.SelectedTenantId }; - Tenant currentTenant = await queryDispatcher.DispatchAsync(tenantByIdQuery); - - var tenantMembershipQuery = new GetTenantMembershipQuery { TenantId = query.User.SelectedTenantId, UserId = query.User.Id }; - TenantMembership tenantMembership = await queryDispatcher.DispatchAsync(tenantMembershipQuery); + var tenant = await tenantIdentityDbContext.GetTenantExtendedByIdAsync(user.SelectedTenantId); + var tenantMembership = tenant.Memberships.Single(m => m.UserId == user.Id); claims.AddRange(new List { - new Claim(ClaimConstants.TenantPlanClaimType, currentTenant.CurrentSubscriptionPlanType.ToString()), - new Claim(ClaimConstants.TenantNameClaimType, currentTenant.Name), - new Claim(ClaimConstants.TenantIdClaimType, currentTenant.TenantId.ToString()), + new Claim(ClaimConstants.TenantPlanClaimType, tenant.CurrentSubscriptionPlanType.ToString()), + new Claim(ClaimConstants.TenantNameClaimType, tenant.Name), + new Claim(ClaimConstants.TenantIdClaimType, tenant.Id.ToString()), new Claim(ClaimConstants.UserRoleInTenantClaimType, tenantMembership.Role.ToString()), }); diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetUserById.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetUserById.cs new file mode 100644 index 00000000..a23830b5 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/GetUserById.cs @@ -0,0 +1,24 @@ +using Modules.TenantIdentity.Features.Infrastructure.EFCore; +using Shared.Features.CQRS.Query; +using System.Threading; + +namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Queries +{ + public class GetUserById : IQuery + { + public Guid UserId { get; set; } + } + public class GetUserByIdHandler : IQueryHandler + { + private readonly TenantIdentityDbContext tenantIdentityDbContext; + public GetUserByIdHandler(TenantIdentityDbContext tenantIdentityDbContext) + { + this.tenantIdentityDbContext = tenantIdentityDbContext; + } + + public async Task HandleAsync(GetUserById query, CancellationToken cancellation) + { + return await tenantIdentityDbContext.GetUserByIdAsync(query.UserId); + } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/UserByStripeCustomerIdQuery.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/UserByStripeCustomerIdQuery.cs deleted file mode 100644 index 5d5bf72f..00000000 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Aggregates/UserAggregate/Application/Queries/UserByStripeCustomerIdQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Modules.TenantIdentity.Features.Aggregates.UserAggregate; - -namespace Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Queries -{ - public class UserByStripeCustomerIdQuery : IQuery - { - public string StripeCustomerId { get; set; } - } -} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/Registrator.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/Registrator.cs new file mode 100644 index 00000000..18e7cbe5 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/Registrator.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace Modules.TenantIdentity.Features.Infrastructure.Configuration +{ + public static class Registrator + { + public static IServiceCollection RegisterConfiguration(this IServiceCollection services, IConfiguration configuration) + { + services.Configure(configuration.GetSection(nameof(TenantIdentityConfiguration))); + services.AddScoped(sp => + { + TenantIdentityConfiguration tc = new TenantIdentityConfiguration(); + sp.GetRequiredService().GetSection("TenantIdentityConfiguration").Bind(tc); + return tc; + }); + services.AddSingleton, TenantIdentityConfigurationValidator>(); + + return services; + } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/TenantIdentityConfiguration.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/TenantIdentityConfiguration.cs new file mode 100644 index 00000000..14d1ba70 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/TenantIdentityConfiguration.cs @@ -0,0 +1,12 @@ +namespace Modules.TenantIdentity.Features.Infrastructure.Configuration +{ + public class TenantIdentityConfiguration + { + public string GoogleClientId { get; set; } + public string GoogleClientSecret { get; set; } + public string MicrosoftClientId { get; set; } + public string MicrosoftClientSecret { get; set; } + public string LinkedinClientId { get; set; } + public string LinkedinClientSecret { get; set; } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/TenantIdentityConfigurationValidator.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/TenantIdentityConfigurationValidator.cs new file mode 100644 index 00000000..58cacc11 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/Configuration/TenantIdentityConfigurationValidator.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.Options; + +namespace Modules.TenantIdentity.Features.Infrastructure.Configuration +{ + public class TenantIdentityConfigurationValidator : IValidateOptions + { + public ValidateOptionsResult Validate(string name, TenantIdentityConfiguration tenantIdentityConfiguration) + { + if (string.IsNullOrEmpty(tenantIdentityConfiguration.GoogleClientId)) + { + return ValidateOptionsResult.Fail(""); + } + + if (string.IsNullOrEmpty(tenantIdentityConfiguration.MicrosoftClientId)) + { + return ValidateOptionsResult.Fail(""); + } + + if (string.IsNullOrEmpty(tenantIdentityConfiguration.GoogleClientSecret)) + { + return ValidateOptionsResult.Fail(""); + } + + return ValidateOptionsResult.Success; + } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantConfiguration.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantAggregate/TenantConfiguration.cs similarity index 55% rename from Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantConfiguration.cs rename to Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantAggregate/TenantConfiguration.cs index 9069f5e4..db9ffff3 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantConfiguration.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantAggregate/TenantConfiguration.cs @@ -1,6 +1,8 @@ -using Modules.TenantIdentity.Features.Aggregates.TenantAggregate; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Modules.TenantIdentity.Features.Aggregates.TenantAggregate.Domain; -namespace Modules.TenantIdentity.Features.EFCore.Configuration +namespace Modules.TenantIdentity.Features.Infrastructure.EFCore.Configuration.TenantAggregate { public class TenantConfiguration : IEntityTypeConfiguration { diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantAggregate/TenantSubscriptionConfiguration.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantAggregate/TenantSubscriptionConfiguration.cs new file mode 100644 index 00000000..ed4a3a38 --- /dev/null +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantAggregate/TenantSubscriptionConfiguration.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Modules.TenantIdentity.Features.Aggregates.TenantAggregate.Domain; + +namespace Modules.TenantIdentity.Features.Infrastructure.EFCore.Configuration.TenantAggregate +{ + internal class SubscriptionConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + + } + } +} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantSubscriptionConfiguration.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantSubscriptionConfiguration.cs deleted file mode 100644 index b8850dcf..00000000 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/TenantSubscriptionConfiguration.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Modules.TenantIdentity.Features.Aggregates.TenantAggregate; - -namespace Modules.TenantIdentity.Features.EFCore.Configuration -{ - internal class SubscriptionConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - - } - } -} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/ApplicationUserConfiguration.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/UserAggregate/UserConfiguration.cs similarity index 61% rename from Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/ApplicationUserConfiguration.cs rename to Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/UserAggregate/UserConfiguration.cs index cad91f28..110cfa23 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/ApplicationUserConfiguration.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/Configuration/UserAggregate/UserConfiguration.cs @@ -2,13 +2,13 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Modules.TenantIdentity.Features.Aggregates.UserAggregate; -namespace Modules.TenantIdentity.Features.EFCore +namespace Modules.TenantIdentity.Features.Infrastructure.EFCore.Configuration.UserAggregate { - public class ApplicationUserConfiguration : IEntityTypeConfiguration + public class UserConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - + } } } diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/IdentityDbContext.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/IdentityDbContext.cs deleted file mode 100644 index 53745e2d..00000000 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/IdentityDbContext.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Modules.TenantIdentity.Features.Aggregates.UserAggregate; -using System; - -namespace Modules.TenantIdentity.Features.EFCore -{ - public class IdentityDbContext : IdentityDbContext, Guid> - { - private readonly IConfiguration configuration; - public IdentityDbContext(IConfiguration configuration, DbContextOptions options) : base(options) - { - this.configuration = configuration; - } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - if(optionsBuilder.IsConfigured is false) - { - //optionsBuilder.UseSqlServer(configuration.GetConnectionString("IdentityDbLocalConnectionString"), sqlServerOptions => - //{ - // //sqlServerOptions.MigrationsAssembly(typeof(IAssemblyMarker).GetTypeInfo().Assembly.GetName().Name); - // sqlServerOptions.EnableRetryOnFailure(5); - //}); - } - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.ApplyConfiguration(new ApplicationUserConfiguration()); - base.OnModelCreating(modelBuilder); - } - } -} diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/TenantIdentityDbContext.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/TenantIdentityDbContext.cs index ab366b4e..f3c5d69e 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/TenantIdentityDbContext.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/EFCore/TenantIdentityDbContext.cs @@ -1,20 +1,115 @@ -using Modules.TenantIdentity.Features.Aggregates.TenantAggregate; +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity; +using Modules.TenantIdentity.Features.Infrastructure.EFCore.Configuration.UserAggregate; +using Shared.Features.DomainKernel.Exceptions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Shared.Features.EFCore.Configuration; using Modules.TenantIdentity.Features.Aggregates.UserAggregate; +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using Modules.TenantIdentity.Features.Aggregates.TenantAggregate; +using System.Linq; +using SendGrid.Helpers.Errors.Model; -namespace Modules.TenantIdentity.Features.EFCore +namespace Modules.TenantIdentity.Features.Infrastructure.EFCore { public class TenantIdentityDbContext : IdentityDbContext, Guid> { - private readonly IConfiguration configuration; - public TenantIdentityDbContext(IConfiguration configuration, DbContextOptions options) : base(options) + private readonly IServiceProvider serviceProvider; + private readonly EFCoreConfiguration configuration; + + public TenantIdentityDbContext() { - this.configuration = configuration; + + } + public TenantIdentityDbContext(IServiceProvider serviceProvider, DbContextOptions dbContextOptions) : base(dbContextOptions) + { + this.serviceProvider = serviceProvider; + configuration = serviceProvider.GetService(); } - //public TenantIdentityDbContext(DbContextOptions dbContextOptions, IServiceProvider serviceProvider, IConfiguration configuration) : base(dbContextOptions, serviceProvider, configuration) - //{ - - //} + public override DbSet Users { get; set; } public DbSet Tenants { get; set; } + public DbSet TenantInvitations { get; set; } + public DbSet TenantMeberships { get; set; } + public DbSet TenantSettings { get; set; } + public DbSet TenantStylings { get; set; } + public DbSet TenantSubscriptions { get; set; } + + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + var hostEnvironment = serviceProvider.GetRequiredService(); + + if (hostEnvironment.IsDevelopment()) + { + optionsBuilder.UseSqlServer(configuration.SQLServerConnectionString, sqlServerOptions => + { + sqlServerOptions.EnableRetryOnFailure(5); + }); + } + if (hostEnvironment.IsProduction()) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Chinook"); + } + } + + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfiguration(new UserConfiguration()); + modelBuilder.HasDefaultSchema("Identity"); + base.OnModelCreating(modelBuilder); + } + + public async Task> GetAllTenantsForUser(Guid userId) + { + return await Users.Where(u => u.Id == userId) + .Include(t => t.TenantMemberships) + .ThenInclude(tm => tm.Tenant) + .SelectMany(u => u.TenantMemberships.Select(tm => tm.Tenant)) + .ToListAsync(); + } + + public async Task GetUserByIdAsync(Guid userId) + { + var user = await Users.FirstOrDefaultAsync(t => t.Id == userId); + if (user == null) + { + throw new NotFoundException(); + } + return user; + } + + public async Task GetTenantByIdAsync(Guid tenantId) + { + var tenant = await Tenants.FirstOrDefaultAsync(t => t.TenantId == tenantId); + if (tenant == null) + { + throw new NotFoundException(); + } + return tenant; + } + + public async Task GetTenantExtendedByIdAsync(Guid tenantId) + { + var tenant = await Tenants + .Include(t => t.Memberships) + .Include(t => t.Invitations) + .Include(t => t.TenantSubscriptions) + .FirstOrDefaultAsync(t => t.TenantId == tenantId); + if (tenant == null) + { + throw new NotFoundException(); + } + return tenant; + } } } diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/ApplicationUserClaimsPrincipalFactory.cs b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/UserClaimsPrincipalFactory.cs similarity index 61% rename from Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/ApplicationUserClaimsPrincipalFactory.cs rename to Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/UserClaimsPrincipalFactory.cs index 69f556b7..33e16483 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/ApplicationUserClaimsPrincipalFactory.cs +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Infrastructure/UserClaimsPrincipalFactory.cs @@ -1,34 +1,27 @@ -using System.Collections.Generic; +using Microsoft.AspNetCore.Identity; using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Identity; -using Modules.TenantIdentity.Features.Aggregates.UserAggregate; -using Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Queries; using Shared.Features.CQRS.Query; +using Modules.TenantIdentity.Features.Aggregates.UserAggregate.Application.Queries; +using Modules.TenantIdentity.Features.Aggregates.UserAggregate; +using System.Threading.Tasks; +using System.Collections.Generic; using Shared.SharedKernel.Constants; -namespace Modules.TenantIdentity.Layers.Features +namespace Modules.TenantIdentity.Features.Infrastructure { - public class ApplicationUserClaimsPrincipalFactory : IUserClaimsPrincipalFactory where User : ApplicationUser + public class UserClaimsPrincipalFactory : IUserClaimsPrincipalFactory where TUser : ApplicationUser { private readonly IQueryDispatcher queryDispatcher; - - public ApplicationUserClaimsPrincipalFactory(IQueryDispatcher queryDispatcher) + public UserClaimsPrincipalFactory(IQueryDispatcher queryDispatcher) { this.queryDispatcher = queryDispatcher; } - public async Task CreateAsync(User user) + public async Task CreateAsync(TUser user) { - var getUserById = new GetUserById - { - - }; - - ApplicationUser applicationUser = await applicationUserManager.FindByIdAsync(user.Id); - - var claimsForUserQuery = new GetClaimsForUser { User = applicationUser }; + var claimsForUserQuery = new GetClaimsForUser { UserId = user.Id }; var claimsForUser = await queryDispatcher.DispatchAsync>(claimsForUserQuery); + ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimsForUser, IdentityConstants.ApplicationScheme, nameType: ClaimConstants.UserNameClaimType, ClaimConstants.UserRoleInTenantClaimType); ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity); diff --git a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Modules.TenantIdentity.Features.csproj b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Modules.TenantIdentity.Features.csproj index 53b4e5d5..7800b0a8 100644 --- a/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Modules.TenantIdentity.Features.csproj +++ b/Source/Modules/TenantIdentity/Features/Modules.TenantIdentity.Features/Modules.TenantIdentity.Features.csproj @@ -6,6 +6,7 @@ + diff --git a/Source/Shared/Features/DomainKernel/Attributes/AggregateRootAttribute.cs b/Source/Shared/Features/DomainKernel/Attributes/AggregateRootAttribute.cs deleted file mode 100644 index 377cd75c..00000000 --- a/Source/Shared/Features/DomainKernel/Attributes/AggregateRootAttribute.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Shared.Features.DomainKernel.Attributes -{ - public class AggregateRootAttribute : Attribute - { - } -} diff --git a/Source/Shared/Features/DomainKernel/Entity.cs b/Source/Shared/Features/DomainKernel/Entity.cs index 685a3682..5379e5d1 100644 --- a/Source/Shared/Features/DomainKernel/Entity.cs +++ b/Source/Shared/Features/DomainKernel/Entity.cs @@ -21,14 +21,12 @@ protected void AddDomainEvent(IDomainEvent eventItem) { _domainEvents.Add(eventItem); } - protected void RemoveEvent(IDomainEvent eventItem) - { - _domainEvents?.Remove(eventItem); - } - public void ClearEvents() + + public void ClearDomainEvents() { _domainEvents?.Clear(); } + public void SoftDelete() { if (IsSoftDeleted is true) diff --git a/Source/Shared/Features/EFCore/BaseDbContext.cs b/Source/Shared/Features/EFCore/BaseDbContext.cs index cc494162..42539479 100644 --- a/Source/Shared/Features/EFCore/BaseDbContext.cs +++ b/Source/Shared/Features/EFCore/BaseDbContext.cs @@ -8,6 +8,7 @@ using Shared.Features.EFCore.MultiTenancy; using Shared.Features.EFCore.MultiTenancy.Exceptions; using Shared.Kernel.BuildingBlocks; +using Shared.SharedKernel.Interfaces; using SharedKernel.Interfaces; namespace Shared.Features.EFCore diff --git a/Source/Shared/Features/Shared.Features.csproj b/Source/Shared/Features/Shared.Features.csproj index 45840b2c..a8628696 100644 --- a/Source/Shared/Features/Shared.Features.csproj +++ b/Source/Shared/Features/Shared.Features.csproj @@ -10,6 +10,7 @@ +