Beispiel #1
0
        public async Task <ApiKeyResponseModel> ApiKey(string id, [FromBody] OrganizationApiKeyRequestModel model)
        {
            var orgIdGuid = new Guid(id);

            if (!await HasApiKeyAccessAsync(orgIdGuid, model.Type))
            {
                throw new NotFoundException();
            }

            var organization = await _organizationRepository.GetByIdAsync(orgIdGuid);

            if (organization == null)
            {
                throw new NotFoundException();
            }

            if (model.Type == OrganizationApiKeyType.BillingSync || model.Type == OrganizationApiKeyType.Scim)
            {
                // Non-enterprise orgs should not be able to create or view an apikey of billing sync/scim key types
                var plan = StaticStore.GetPlan(organization.PlanType);
                if (plan.Product != ProductType.Enterprise)
                {
                    throw new NotFoundException();
                }
            }

            var organizationApiKey = await _getOrganizationApiKeyCommand
                                     .GetOrganizationApiKeyAsync(organization.Id, model.Type);

            var user = await _userService.GetUserByPrincipalAsync(User);

            if (user == null)
            {
                throw new UnauthorizedAccessException();
            }

            if (model.Type != OrganizationApiKeyType.Scim &&
                !await _userService.VerifySecretAsync(user, model.Secret))
            {
                await Task.Delay(2000);

                throw new BadRequestException("MasterPasswordHash", "Invalid password.");
            }
            else
            {
                var response = new ApiKeyResponseModel(organizationApiKey);
                return(response);
            }
        }
Beispiel #2
0
        public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails organization) : this("profileOrganization")
        {
            Id                            = organization.OrganizationId.ToString();
            Name                          = organization.Name;
            UsePolicies                   = organization.UsePolicies;
            UseSso                        = organization.UseSso;
            UseKeyConnector               = organization.UseKeyConnector;
            UseScim                       = organization.UseScim;
            UseGroups                     = organization.UseGroups;
            UseDirectory                  = organization.UseDirectory;
            UseEvents                     = organization.UseEvents;
            UseTotp                       = organization.UseTotp;
            Use2fa                        = organization.Use2fa;
            UseApi                        = organization.UseApi;
            UseResetPassword              = organization.UseResetPassword;
            UsersGetPremium               = organization.UsersGetPremium;
            SelfHost                      = organization.SelfHost;
            Seats                         = organization.Seats;
            MaxCollections                = organization.MaxCollections;
            MaxStorageGb                  = organization.MaxStorageGb;
            Key                           = organization.Key;
            HasPublicAndPrivateKeys       = organization.PublicKey != null && organization.PrivateKey != null;
            Status                        = organization.Status;
            Type                          = organization.Type;
            Enabled                       = organization.Enabled;
            SsoBound                      = !string.IsNullOrWhiteSpace(organization.SsoExternalId);
            Identifier                    = organization.Identifier;
            Permissions                   = CoreHelpers.LoadClassFromJsonData <Permissions>(organization.Permissions);
            ResetPasswordEnrolled         = organization.ResetPasswordKey != null;
            UserId                        = organization.UserId?.ToString();
            ProviderId                    = organization.ProviderId?.ToString();
            ProviderName                  = organization.ProviderName;
            FamilySponsorshipFriendlyName = organization.FamilySponsorshipFriendlyName;
            FamilySponsorshipAvailable    = FamilySponsorshipFriendlyName == null &&
                                            StaticStore.GetSponsoredPlan(PlanSponsorshipType.FamiliesForEnterprise)
                                            .UsersCanSponsor(organization);
            PlanProductType = StaticStore.GetPlan(organization.PlanType).Product;
            FamilySponsorshipLastSyncDate = organization.FamilySponsorshipLastSyncDate;
            FamilySponsorshipToDelete     = organization.FamilySponsorshipToDelete;
            FamilySponsorshipValidUntil   = organization.FamilySponsorshipValidUntil;

            if (organization.SsoConfig != null)
            {
                var ssoConfigData = SsoConfigurationData.Deserialize(organization.SsoConfig);
                KeyConnectorEnabled = ssoConfigData.KeyConnectorEnabled && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl);
                KeyConnectorUrl     = ssoConfigData.KeyConnectorUrl;
            }
        }
        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);
        }
        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;
            }
        }
Beispiel #5
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);
        }