public bool IsValid(OrganizationSponsorship sponsorship, string currentUserEmail) =>
 sponsorship != null &&
 sponsorship.PlanSponsorshipType.HasValue &&
 SponsorshipType == sponsorship.PlanSponsorshipType.Value &&
 Id == sponsorship.Id &&
 !string.IsNullOrWhiteSpace(sponsorship.OfferedToEmail) &&
 Email.Equals(currentUserEmail, StringComparison.InvariantCultureIgnoreCase) &&
 Email.Equals(sponsorship.OfferedToEmail, StringComparison.InvariantCultureIgnoreCase);
        public async Task RevokeSponsorship_SponsorshipRedeemed_MarksForDelete(OrganizationSponsorship sponsorship,
                                                                               SutProvider <CloudRevokeSponsorshipCommand> sutProvider)
        {
            await sutProvider.Sut.RevokeSponsorshipAsync(sponsorship);

            Assert.True(sponsorship.ToDelete);
            await AssertUpdatedSponsorshipAsync(sponsorship, sutProvider);
            await AssertDidNotDeleteSponsorshipAsync(sutProvider);
        }
Ejemplo n.º 3
0
        public async Task RemoveSponsorshipAsync(OrganizationSponsorship sponsorship)
        {
            if (sponsorship == null || sponsorship.SponsoredOrganizationId == null)
            {
                throw new BadRequestException("The requested organization is not currently being sponsored.");
            }

            await MarkToDeleteSponsorshipAsync(sponsorship);
        }
        public async Task SendSponsorshipOfferAsync(OrganizationSponsorship sponsorship, string sponsoringOrgName)
        {
            var user = await _userRepository.GetByEmailAsync(sponsorship.OfferedToEmail);

            var isExistingAccount = user != null;

            await _mailService.SendFamiliesForEnterpriseOfferEmailAsync(sponsoringOrgName, sponsorship.OfferedToEmail,
                                                                        isExistingAccount, _tokenFactory.Protect(new OrganizationSponsorshipOfferTokenable(sponsorship)));
        }
Ejemplo n.º 5
0
        public async Task RevokeSponsorship_SponsorshipNotSynced_DeletesSponsorship(OrganizationSponsorship sponsorship,
                                                                                    SutProvider <SelfHostedRevokeSponsorshipCommand> sutProvider)
        {
            sponsorship.LastSyncDate = null;

            await sutProvider.Sut.RevokeSponsorshipAsync(sponsorship);

            await AssertDeletedSponsorshipAsync(sponsorship, sutProvider);
        }
Ejemplo n.º 6
0
        protected virtual async Task DeleteSponsorshipAsync(OrganizationSponsorship sponsorship = null)
        {
            if (sponsorship == null)
            {
                return;
            }

            await _organizationSponsorshipRepository.DeleteAsync(sponsorship);
        }
Ejemplo n.º 7
0
        protected async Task MarkToDeleteSponsorshipAsync(OrganizationSponsorship sponsorship)
        {
            if (sponsorship == null)
            {
                throw new BadRequestException("The sponsorship you are trying to cancel does not exist");
            }

            sponsorship.ToDelete = true;
            await _organizationSponsorshipRepository.UpsertAsync(sponsorship);
        }
 public OrganizationSponsorshipRequestModel(OrganizationSponsorship sponsorship)
 {
     SponsoringOrganizationUserId = sponsorship.SponsoringOrganizationUserId;
     FriendlyName        = sponsorship.FriendlyName;
     OfferedToEmail      = sponsorship.OfferedToEmail;
     PlanSponsorshipType = sponsorship.PlanSponsorshipType.GetValueOrDefault();
     LastSyncDate        = sponsorship.LastSyncDate;
     ValidUntil          = sponsorship.ValidUntil;
     ToDelete            = sponsorship.ToDelete;
 }
        public async Task UpdateExpirationDate_UpdatesValidUntil(OrganizationSponsorship sponsorship, DateTime expireDate,
                                                                 SutProvider <OrganizationSponsorshipRenewCommand> sutProvider)
        {
            sutProvider.GetDependency <IOrganizationSponsorshipRepository>().GetBySponsoredOrganizationIdAsync(sponsorship.SponsoredOrganizationId.Value).Returns(sponsorship);

            await sutProvider.Sut.UpdateExpirationDateAsync(sponsorship.SponsoredOrganizationId.Value, expireDate);

            await sutProvider.GetDependency <IOrganizationSponsorshipRepository>().Received(1)
            .UpsertAsync(sponsorship);
        }
Ejemplo n.º 10
0
        public async Task RevokeSponsorship_SponsorshipSynced_MarksForDeletion(OrganizationSponsorship sponsorship,
                                                                               SutProvider <SelfHostedRevokeSponsorshipCommand> sutProvider)
        {
            sponsorship.LastSyncDate = DateTime.UtcNow;

            await sutProvider.Sut.RevokeSponsorshipAsync(sponsorship);

            Assert.True(sponsorship.ToDelete);
            await AssertUpdatedSponsorshipAsync(sponsorship, sutProvider);
            await AssertDidNotDeleteSponsorshipAsync(sutProvider);
        }
        public async Task ResendSponsorshipOffer_SponsoringOrgNotFound_ThrowsBadRequest(
            OrganizationUser orgUser, OrganizationSponsorship sponsorship,
            SutProvider <SendSponsorshipOfferCommand> sutProvider)
        {
            var exception = await Assert.ThrowsAsync <BadRequestException>(() =>
                                                                           sutProvider.Sut.SendSponsorshipOfferAsync(null, orgUser, sponsorship));

            Assert.Contains("Cannot find the requested sponsoring organization.", exception.Message);
            await sutProvider.GetDependency <IMailService>()
            .DidNotReceiveWithAnyArgs()
            .SendFamiliesForEnterpriseOfferEmailAsync(default, default, default, default);
Ejemplo n.º 12
0
 private bool SponsorshipValidator(OrganizationSponsorship sponsorship, OrganizationSponsorship expectedSponsorship)
 {
     try
     {
         AssertHelper.AssertPropertyEqual(sponsorship, expectedSponsorship, nameof(OrganizationSponsorship.Id));
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Ejemplo n.º 13
0
        public async Task SetUpSponsorship_OrgAlreadySponsored_ThrowsBadRequest(Organization org,
                                                                                OrganizationSponsorship sponsorship, OrganizationSponsorship existingSponsorship,
                                                                                SutProvider <SetUpSponsorshipCommand> sutProvider)
        {
            sutProvider.GetDependency <IOrganizationSponsorshipRepository>()
            .GetBySponsoredOrganizationIdAsync(org.Id).Returns(existingSponsorship);

            var exception = await Assert.ThrowsAsync <BadRequestException>(() =>
                                                                           sutProvider.Sut.SetUpSponsorshipAsync(sponsorship, org));

            Assert.Contains("Cannot redeem a sponsorship offer for an organization that is already sponsored. Revoke existing sponsorship first.", exception.Message);
            await AssertDidNotSetUpAsync(sutProvider);
        }
Ejemplo n.º 14
0
        public async Task SetUpSponsorship_OrgNotFamiles_ThrowsBadRequest(PlanType planType,
                                                                          OrganizationSponsorship sponsorship, Organization org,
                                                                          SutProvider <SetUpSponsorshipCommand> sutProvider)
        {
            org.PlanType             = planType;
            sponsorship.LastSyncDate = DateTime.UtcNow;

            var exception = await Assert.ThrowsAsync <BadRequestException>(() =>
                                                                           sutProvider.Sut.SetUpSponsorshipAsync(sponsorship, org));

            Assert.Contains("Can only redeem sponsorship offer on families organizations.", exception.Message);
            await AssertDidNotSetUpAsync(sutProvider);
        }
Ejemplo n.º 15
0
        public async Task RemoveSponsorship_SponsoredOrgNull_ThrowsBadRequest(OrganizationSponsorship sponsorship,
                                                                              SutProvider <RemoveSponsorshipCommand> sutProvider)
        {
            sponsorship.SponsoredOrganizationId = null;

            var exception = await Assert.ThrowsAsync <BadRequestException>(() =>
                                                                           sutProvider.Sut.RemoveSponsorshipAsync(sponsorship));

            Assert.Contains("The requested organization is not currently being sponsored.", exception.Message);
            Assert.False(sponsorship.ToDelete);
            await AssertDidNotDeleteSponsorshipAsync(sutProvider);
            await AssertDidNotUpdateSponsorshipAsync(sutProvider);
        }
        public async void ReplaceAsync_Works_DataMatches(OrganizationSponsorship postOrganizationSponsorship,
                                                         OrganizationSponsorship replaceOrganizationSponsorship, Organization sponsoringOrg,
                                                         List <EfRepo.OrganizationRepository> efOrgRepos,
                                                         SqlRepo.OrganizationRepository sqlOrganizationRepo,
                                                         SqlRepo.OrganizationSponsorshipRepository sqlOrganizationSponsorshipRepo,
                                                         OrganizationSponsorshipCompare equalityComparer, List <EfRepo.OrganizationSponsorshipRepository> suts)
        {
            postOrganizationSponsorship.InstallationId             = null;
            postOrganizationSponsorship.SponsoredOrganizationId    = null;
            replaceOrganizationSponsorship.InstallationId          = null;
            replaceOrganizationSponsorship.SponsoredOrganizationId = null;

            var savedOrganizationSponsorships = new List <OrganizationSponsorship>();

            foreach (var(sut, orgRepo) in suts.Zip(efOrgRepos))
            {
                var efSponsoringOrg = await orgRepo.CreateAsync(sponsoringOrg);

                sut.ClearChangeTracking();
                postOrganizationSponsorship.SponsoringOrganizationId    = efSponsoringOrg.Id;
                replaceOrganizationSponsorship.SponsoringOrganizationId = efSponsoringOrg.Id;

                var postEfOrganizationSponsorship = await sut.CreateAsync(postOrganizationSponsorship);

                sut.ClearChangeTracking();

                replaceOrganizationSponsorship.Id = postEfOrganizationSponsorship.Id;
                await sut.ReplaceAsync(replaceOrganizationSponsorship);

                sut.ClearChangeTracking();

                var replacedOrganizationSponsorship = await sut.GetByIdAsync(replaceOrganizationSponsorship.Id);

                savedOrganizationSponsorships.Add(replacedOrganizationSponsorship);
            }

            var sqlSponsoringOrg = await sqlOrganizationRepo.CreateAsync(sponsoringOrg);

            postOrganizationSponsorship.SponsoringOrganizationId = sqlSponsoringOrg.Id;

            var postSqlOrganization = await sqlOrganizationSponsorshipRepo.CreateAsync(postOrganizationSponsorship);

            replaceOrganizationSponsorship.Id = postSqlOrganization.Id;
            await sqlOrganizationSponsorshipRepo.ReplaceAsync(replaceOrganizationSponsorship);

            savedOrganizationSponsorships.Add(await sqlOrganizationSponsorshipRepo.GetByIdAsync(replaceOrganizationSponsorship.Id));

            var distinctItems = savedOrganizationSponsorships.Distinct(equalityComparer);

            Assert.True(!distinctItems.Skip(1).Any());
        }
        public async void DeleteAsync_Works_DataMatches(OrganizationSponsorship organizationSponsorship,
                                                        Organization sponsoringOrg,
                                                        List <EfRepo.OrganizationRepository> efOrgRepos,
                                                        SqlRepo.OrganizationRepository sqlOrganizationRepo,
                                                        SqlRepo.OrganizationSponsorshipRepository sqlOrganizationSponsorshipRepo,
                                                        List <EfRepo.OrganizationSponsorshipRepository> suts)
        {
            organizationSponsorship.InstallationId          = null;
            organizationSponsorship.SponsoredOrganizationId = null;

            foreach (var(sut, orgRepo) in suts.Zip(efOrgRepos))
            {
                var efSponsoringOrg = await orgRepo.CreateAsync(sponsoringOrg);

                sut.ClearChangeTracking();
                organizationSponsorship.SponsoringOrganizationId = efSponsoringOrg.Id;

                var postEfOrganizationSponsorship = await sut.CreateAsync(organizationSponsorship);

                sut.ClearChangeTracking();

                var savedEfOrganizationSponsorship = await sut.GetByIdAsync(postEfOrganizationSponsorship.Id);

                sut.ClearChangeTracking();
                Assert.True(savedEfOrganizationSponsorship != null);

                await sut.DeleteAsync(savedEfOrganizationSponsorship);

                sut.ClearChangeTracking();

                savedEfOrganizationSponsorship = await sut.GetByIdAsync(savedEfOrganizationSponsorship.Id);

                Assert.True(savedEfOrganizationSponsorship == null);
            }

            var sqlSponsoringOrg = await sqlOrganizationRepo.CreateAsync(sponsoringOrg);

            organizationSponsorship.SponsoringOrganizationId = sqlSponsoringOrg.Id;

            var postSqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.CreateAsync(organizationSponsorship);

            var savedSqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.GetByIdAsync(postSqlOrganizationSponsorship.Id);

            Assert.True(savedSqlOrganizationSponsorship != null);

            await sqlOrganizationSponsorshipRepo.DeleteAsync(postSqlOrganizationSponsorship);

            savedSqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.GetByIdAsync(postSqlOrganizationSponsorship.Id);

            Assert.True(savedSqlOrganizationSponsorship == null);
        }
        protected async Task AssertRemovedSponsoredPaymentAsync <T>(Organization sponsoredOrg,
                                                                    OrganizationSponsorship sponsorship, SutProvider <T> sutProvider)
        {
            await sutProvider.GetDependency <IPaymentService>().Received(1)
            .RemoveOrganizationSponsorshipAsync(sponsoredOrg, sponsorship);

            await sutProvider.GetDependency <IOrganizationRepository>().Received(1).UpsertAsync(sponsoredOrg);

            if (sponsorship != null)
            {
                await sutProvider.GetDependency <IMailService>().Received(1)
                .SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(sponsoredOrg.BillingEmailAddress(), sponsorship.ValidUntil.GetValueOrDefault());
            }
        }
        public async Task RevokeSponsorshipAsync(OrganizationSponsorship sponsorship)
        {
            if (sponsorship == null)
            {
                throw new BadRequestException("You are not currently sponsoring an organization.");
            }

            if (sponsorship.LastSyncDate == null)
            {
                await base.DeleteSponsorshipAsync(sponsorship);
            }
            else
            {
                await MarkToDeleteSponsorshipAsync(sponsorship);
            }
        }
Ejemplo n.º 20
0
        public async Task SetUpSponsorshipAsync(OrganizationSponsorship sponsorship,
                                                Organization sponsoredOrganization)
        {
            if (sponsorship == null)
            {
                throw new BadRequestException("No unredeemed sponsorship offer exists for you.");
            }

            var existingOrgSponsorship = await _organizationSponsorshipRepository
                                         .GetBySponsoredOrganizationIdAsync(sponsoredOrganization.Id);

            if (existingOrgSponsorship != null)
            {
                throw new BadRequestException("Cannot redeem a sponsorship offer for an organization that is already sponsored. Revoke existing sponsorship first.");
            }

            if (sponsorship.PlanSponsorshipType == null)
            {
                throw new BadRequestException("Cannot set up sponsorship without a known sponsorship type.");
            }

            // Do not allow self-hosted sponsorships that haven't been synced for > 0.5 year
            if (sponsorship.LastSyncDate != null && DateTime.UtcNow.Subtract(sponsorship.LastSyncDate.Value).TotalDays > 182.5)
            {
                await _organizationSponsorshipRepository.DeleteAsync(sponsorship);

                throw new BadRequestException("This sponsorship offer is more than 6 months old and has expired.");
            }

            // Check org to sponsor's product type
            var requiredSponsoredProductType = StaticStore.GetSponsoredPlan(sponsorship.PlanSponsorshipType.Value)?.SponsoredProductType;

            if (requiredSponsoredProductType == null ||
                sponsoredOrganization == null ||
                StaticStore.GetPlan(sponsoredOrganization.PlanType).Product != requiredSponsoredProductType.Value)
            {
                throw new BadRequestException("Can only redeem sponsorship offer on families organizations.");
            }

            await _paymentService.SponsorOrganizationAsync(sponsoredOrganization, sponsorship);

            await _organizationRepository.UpsertAsync(sponsoredOrganization);

            sponsorship.SponsoredOrganizationId = sponsoredOrganization.Id;
            sponsorship.OfferedToEmail          = null;
            await _organizationSponsorshipRepository.UpsertAsync(sponsorship);
        }
Ejemplo n.º 21
0
        public async Task SetUpSponsorship_TooLongSinceLastSync_ThrowsBadRequest(PlanType planType, Organization org,
                                                                                 OrganizationSponsorship sponsorship,
                                                                                 SutProvider <SetUpSponsorshipCommand> sutProvider)
        {
            org.PlanType             = planType;
            sponsorship.LastSyncDate = DateTime.UtcNow.AddDays(-365);

            var exception = await Assert.ThrowsAsync <BadRequestException>(() =>
                                                                           sutProvider.Sut.SetUpSponsorshipAsync(sponsorship, org));

            Assert.Contains("This sponsorship offer is more than 6 months old and has expired.", exception.Message);
            await sutProvider.GetDependency <IOrganizationSponsorshipRepository>()
            .Received(1)
            .DeleteAsync(sponsorship);

            await AssertDidNotSetUpAsync(sutProvider);
        }
        public OrganizationSponsorshipOfferTokenable(OrganizationSponsorship sponsorship)
        {
            if (string.IsNullOrWhiteSpace(sponsorship.OfferedToEmail))
            {
                throw new ArgumentException("Invalid OrganizationSponsorship to create a token, OfferedToEmail is required", nameof(sponsorship));
            }
            Email = sponsorship.OfferedToEmail;

            if (!sponsorship.PlanSponsorshipType.HasValue)
            {
                throw new ArgumentException("Invalid OrganizationSponsorship to create a token, PlanSponsorshipType is required", nameof(sponsorship));
            }
            SponsorshipType = sponsorship.PlanSponsorshipType.Value;

            if (sponsorship.Id == default)
            {
                throw new ArgumentException("Invalid OrganizationSponsorship to create a token, Id is required", nameof(sponsorship));
            }
            Id = sponsorship.Id;
        }
Ejemplo n.º 23
0
        public async Task SendSponsorshipOfferAsync(Organization sponsoringOrg, OrganizationUser sponsoringOrgUser,
                                                    OrganizationSponsorship sponsorship)
        {
            if (sponsoringOrg == null)
            {
                throw new BadRequestException("Cannot find the requested sponsoring organization.");
            }

            if (sponsoringOrgUser == null || sponsoringOrgUser.Status != OrganizationUserStatusType.Confirmed)
            {
                throw new BadRequestException("Only confirmed users can sponsor other organizations.");
            }

            if (sponsorship == null || sponsorship.OfferedToEmail == null)
            {
                throw new BadRequestException("Cannot find an outstanding sponsorship offer for this organization.");
            }

            await SendSponsorshipOfferAsync(sponsorship, sponsoringOrg.Name);
        }
        public async Task ValidateSponsorshipAsync_Valid(PlanType planType,
                                                         Organization sponsoredOrg, OrganizationSponsorship existingSponsorship, Organization sponsoringOrg,
                                                         SutProvider <ValidateSponsorshipCommand> sutProvider)
        {
            sponsoringOrg.PlanType = planType;
            sponsoringOrg.Enabled  = true;
            existingSponsorship.SponsoringOrganizationId = sponsoringOrg.Id;

            sutProvider.GetDependency <IOrganizationSponsorshipRepository>()
            .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship);
            sutProvider.GetDependency <IOrganizationRepository>().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg);
            sutProvider.GetDependency <IOrganizationRepository>().GetByIdAsync(sponsoringOrg.Id).Returns(sponsoringOrg);

            var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id);

            Assert.True(result);

            await AssertDidNotRemoveSponsoredPaymentAsync(sutProvider);
            await AssertDidNotDeleteSponsorshipAsync(sutProvider);
        }
Ejemplo n.º 25
0
        public async Task SyncOrganization(Guid organizationId, Guid cloudOrganizationId, OrganizationConnection billingSyncConnection)
        {
            if (!_globalSettings.EnableCloudCommunication)
            {
                throw new BadRequestException("Failed to sync instance with cloud - Cloud communication is disabled in global settings");
            }
            if (!billingSyncConnection.Enabled)
            {
                throw new BadRequestException($"Billing Sync Key disabled for organization {organizationId}");
            }
            if (string.IsNullOrWhiteSpace(billingSyncConnection.Config))
            {
                throw new BadRequestException($"No Billing Sync Key known for organization {organizationId}");
            }
            var billingSyncConfig = billingSyncConnection.GetConfig <BillingSyncConfig>();

            if (billingSyncConfig == null || string.IsNullOrWhiteSpace(billingSyncConfig.BillingSyncKey))
            {
                throw new BadRequestException($"Failed to get Billing Sync Key for organization {organizationId}");
            }

            var organizationSponsorshipsDict = (await _organizationSponsorshipRepository.GetManyBySponsoringOrganizationAsync(organizationId))
                                               .ToDictionary(i => i.SponsoringOrganizationUserId);

            if (!organizationSponsorshipsDict.Any())
            {
                _logger.LogInformation($"No existing sponsorships to sync for organization {organizationId}");
                return;
            }
            var syncedSponsorships = new List <OrganizationSponsorshipData>();

            foreach (var orgSponsorshipsBatch in CoreHelpers.Batch(organizationSponsorshipsDict.Values, 1000))
            {
                var response = await SendAsync <OrganizationSponsorshipSyncRequestModel, OrganizationSponsorshipSyncResponseModel>(HttpMethod.Post, "organization/sponsorship/sync", new OrganizationSponsorshipSyncRequestModel
                {
                    BillingSyncKey = billingSyncConfig.BillingSyncKey,
                    SponsoringOrganizationCloudId = cloudOrganizationId,
                    SponsorshipsBatch             = orgSponsorshipsBatch.Select(s => new OrganizationSponsorshipRequestModel(s))
                });

                if (response == null)
                {
                    _logger.LogDebug("Organization sync failed for '{OrgId}'", organizationId);
                    throw new BadRequestException("Organization sync failed");
                }

                syncedSponsorships.AddRange(response.ToOrganizationSponsorshipSync().SponsorshipsBatch);
            }

            var sponsorshipsToDelete = syncedSponsorships.Where(s => s.CloudSponsorshipRemoved).Select(i => organizationSponsorshipsDict[i.SponsoringOrganizationUserId].Id);
            var sponsorshipsToUpsert = syncedSponsorships.Where(s => !s.CloudSponsorshipRemoved).Select(i =>
            {
                var existingSponsorship = organizationSponsorshipsDict[i.SponsoringOrganizationUserId];
                if (existingSponsorship != null)
                {
                    existingSponsorship.LastSyncDate = i.LastSyncDate;
                    existingSponsorship.ValidUntil   = i.ValidUntil;
                    existingSponsorship.ToDelete     = i.ToDelete;
                }
                else
                {
                    // shouldn't occur, added in case self hosted loses a sponsorship
                    existingSponsorship = new OrganizationSponsorship
                    {
                        SponsoringOrganizationId     = organizationId,
                        SponsoringOrganizationUserId = i.SponsoringOrganizationUserId,
                        FriendlyName        = i.FriendlyName,
                        OfferedToEmail      = i.OfferedToEmail,
                        PlanSponsorshipType = i.PlanSponsorshipType,
                        LastSyncDate        = i.LastSyncDate,
                        ValidUntil          = i.ValidUntil,
                        ToDelete            = i.ToDelete
                    };
                }
                return(existingSponsorship);
            });

            if (sponsorshipsToDelete.Any())
            {
                await _organizationSponsorshipRepository.DeleteManyAsync(sponsorshipsToDelete);
            }
            if (sponsorshipsToUpsert.Any())
            {
                await _organizationSponsorshipRepository.UpsertManyAsync(sponsorshipsToUpsert);
            }
        }
Ejemplo n.º 26
0
        private async Task <(IEnumerable <OrganizationSponsorshipData> data, IEnumerable <OrganizationSponsorship> toOffer)> DoSyncAsync(Organization sponsoringOrg, IEnumerable <OrganizationSponsorshipData> sponsorshipsData)
        {
            var existingSponsorshipsDict = (await _organizationSponsorshipRepository.GetManyBySponsoringOrganizationAsync(sponsoringOrg.Id))
                                           .ToDictionary(i => i.SponsoringOrganizationUserId);

            var sponsorshipsToUpsert   = new List <OrganizationSponsorship>();
            var sponsorshipIdsToDelete = new List <Guid>();
            var sponsorshipsToReturn   = new List <OrganizationSponsorshipData>();

            foreach (var selfHostedSponsorship in sponsorshipsData)
            {
                var requiredSponsoringProductType = StaticStore.GetSponsoredPlan(selfHostedSponsorship.PlanSponsorshipType)?.SponsoringProductType;
                if (requiredSponsoringProductType == null ||
                    StaticStore.GetPlan(sponsoringOrg.PlanType).Product != requiredSponsoringProductType.Value)
                {
                    continue; // prevent unsupported sponsorships
                }

                if (!existingSponsorshipsDict.TryGetValue(selfHostedSponsorship.SponsoringOrganizationUserId, out var cloudSponsorship))
                {
                    if (selfHostedSponsorship.ToDelete && selfHostedSponsorship.LastSyncDate == null)
                    {
                        continue; // prevent invalid sponsorships in cloud. These should have been deleted by self hosted
                    }
                    if (OrgDisabledForMoreThanGracePeriod(sponsoringOrg))
                    {
                        continue; // prevent new sponsorships from disabled orgs
                    }
                    cloudSponsorship = new OrganizationSponsorship
                    {
                        SponsoringOrganizationId     = sponsoringOrg.Id,
                        SponsoringOrganizationUserId = selfHostedSponsorship.SponsoringOrganizationUserId,
                        FriendlyName        = selfHostedSponsorship.FriendlyName,
                        OfferedToEmail      = selfHostedSponsorship.OfferedToEmail,
                        PlanSponsorshipType = selfHostedSponsorship.PlanSponsorshipType,
                        LastSyncDate        = DateTime.UtcNow,
                    };
                }
                else
                {
                    cloudSponsorship.LastSyncDate = DateTime.UtcNow;
                }

                if (selfHostedSponsorship.ToDelete)
                {
                    if (cloudSponsorship.SponsoredOrganizationId == null)
                    {
                        sponsorshipIdsToDelete.Add(cloudSponsorship.Id);
                        selfHostedSponsorship.CloudSponsorshipRemoved = true;
                    }
                    else
                    {
                        cloudSponsorship.ToDelete = true;
                    }
                }
                sponsorshipsToUpsert.Add(cloudSponsorship);

                selfHostedSponsorship.ValidUntil   = cloudSponsorship.ValidUntil;
                selfHostedSponsorship.LastSyncDate = DateTime.UtcNow;
                sponsorshipsToReturn.Add(selfHostedSponsorship);
            }
            var sponsorshipsToEmailOffer = sponsorshipsToUpsert.Where(s => s.Id == default).ToArray();

            if (sponsorshipsToUpsert.Any())
            {
                await _organizationSponsorshipRepository.UpsertManyAsync(sponsorshipsToUpsert);
            }
            if (sponsorshipIdsToDelete.Any())
            {
                await _organizationSponsorshipRepository.DeleteManyAsync(sponsorshipIdsToDelete);
            }

            return(sponsorshipsToReturn, sponsorshipsToEmailOffer);
        }
 protected async Task AssertDeletedSponsorshipAsync <T>(OrganizationSponsorship sponsorship,
                                                        SutProvider <T> sutProvider)
 {
     await sutProvider.GetDependency <IOrganizationSponsorshipRepository>().Received(1)
     .DeleteAsync(sponsorship);
 }
Ejemplo n.º 28
0
        public async Task <OrganizationSponsorship> CreateSponsorshipAsync(Organization sponsoringOrg, OrganizationUser sponsoringOrgUser,
                                                                           PlanSponsorshipType sponsorshipType, string sponsoredEmail, string friendlyName)
        {
            var sponsoringUser = await _userService.GetUserByIdAsync(sponsoringOrgUser.UserId.Value);

            if (sponsoringUser == null || string.Equals(sponsoringUser.Email, sponsoredEmail, System.StringComparison.InvariantCultureIgnoreCase))
            {
                throw new BadRequestException("Cannot offer a Families Organization Sponsorship to yourself. Choose a different email.");
            }

            var requiredSponsoringProductType = StaticStore.GetSponsoredPlan(sponsorshipType)?.SponsoringProductType;

            if (requiredSponsoringProductType == null ||
                sponsoringOrg == null ||
                StaticStore.GetPlan(sponsoringOrg.PlanType).Product != requiredSponsoringProductType.Value)
            {
                throw new BadRequestException("Specified Organization cannot sponsor other organizations.");
            }

            if (sponsoringOrgUser == null || sponsoringOrgUser.Status != OrganizationUserStatusType.Confirmed)
            {
                throw new BadRequestException("Only confirmed users can sponsor other organizations.");
            }

            var existingOrgSponsorship = await _organizationSponsorshipRepository
                                         .GetBySponsoringOrganizationUserIdAsync(sponsoringOrgUser.Id);

            if (existingOrgSponsorship?.SponsoredOrganizationId != null)
            {
                throw new BadRequestException("Can only sponsor one organization per Organization User.");
            }

            var sponsorship = new OrganizationSponsorship
            {
                SponsoringOrganizationId     = sponsoringOrg.Id,
                SponsoringOrganizationUserId = sponsoringOrgUser.Id,
                FriendlyName        = friendlyName,
                OfferedToEmail      = sponsoredEmail,
                PlanSponsorshipType = sponsorshipType,
            };

            if (existingOrgSponsorship != null)
            {
                // Replace existing invalid offer with our new sponsorship offer
                sponsorship.Id = existingOrgSponsorship.Id;
            }

            try
            {
                await _organizationSponsorshipRepository.UpsertAsync(sponsorship);

                return(sponsorship);
            }
            catch
            {
                if (sponsorship.Id != default)
                {
                    await _organizationSponsorshipRepository.DeleteAsync(sponsorship);
                }
                throw;
            }
        }
Ejemplo n.º 29
0
        protected async Task CancelSponsorshipAsync(Organization sponsoredOrganization, OrganizationSponsorship sponsorship = null)
        {
            if (sponsoredOrganization != null)
            {
                await _paymentService.RemoveOrganizationSponsorshipAsync(sponsoredOrganization, sponsorship);

                await _organizationRepository.UpsertAsync(sponsoredOrganization);

                try
                {
                    if (sponsorship != null)
                    {
                        await _mailService.SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(
                            sponsoredOrganization.BillingEmailAddress(),
                            sponsorship.ValidUntil ?? DateTime.UtcNow.AddDays(15));
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError("Error sending Family sponsorship removed email.", e);
                }
            }
            await base.DeleteSponsorshipAsync(sponsorship);
        }
        public async Task RevokeSponsorship_SponsorshipNotRedeemed_DeletesSponsorship(OrganizationSponsorship sponsorship,
                                                                                      SutProvider <CloudRevokeSponsorshipCommand> sutProvider)
        {
            sponsorship.SponsoredOrganizationId = null;

            await sutProvider.Sut.RevokeSponsorshipAsync(sponsorship);

            await AssertDeletedSponsorshipAsync(sponsorship, sutProvider);
        }