1
0
mirror of https://github.com/bitwarden/server synced 2026-01-04 09:33:40 +00:00

Merge branch 'feature/flexible-collections' into flexible-collections/add-feature-flags

This commit is contained in:
Thomas Rittson
2023-10-09 10:56:58 +10:00
18 changed files with 165 additions and 88 deletions

View File

@@ -20,7 +20,7 @@ public static class Constants
/// </summary>
public const int OrganizationSelfHostSubscriptionGracePeriodDays = 60;
public const string CipherKeyEncryptionMinimumVersion = "2023.9.1";
public const string CipherKeyEncryptionMinimumVersion = "2023.9.2";
}
public static class TokenPurposes

View File

@@ -5,10 +5,25 @@ namespace Bit.Core.Models.Business;
public class SubscriptionInfo
{
public BillingCustomerDiscount Discount { get; set; }
public BillingSubscription Subscription { get; set; }
public BillingUpcomingInvoice UpcomingInvoice { get; set; }
public bool UsingInAppPurchase { get; set; }
public class BillingCustomerDiscount
{
public BillingCustomerDiscount() { }
public BillingCustomerDiscount(Discount discount)
{
Id = discount.Id;
Active = discount.Start != null && discount.End == null;
}
public string Id { get; }
public bool Active { get; }
}
public class BillingSubscription
{
public BillingSubscription(Subscription sub)

View File

@@ -5,7 +5,7 @@ namespace Bit.Core.Services;
public interface ICollectionService
{
Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection> groups = null, IEnumerable<CollectionAccessSelection> users = null, Guid? assignUserId = null);
Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection> groups = null, IEnumerable<CollectionAccessSelection> users = null);
Task DeleteUserAsync(Collection collection, Guid organizationUserId);
Task<IEnumerable<Collection>> GetOrganizationCollectionsAsync(Guid organizationId);
}

View File

@@ -41,7 +41,7 @@ public class CollectionService : ICollectionService
}
public async Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection> groups = null,
IEnumerable<CollectionAccessSelection> users = null, Guid? assignUserId = null)
IEnumerable<CollectionAccessSelection> users = null)
{
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
if (org == null)
@@ -49,6 +49,16 @@ public class CollectionService : ICollectionService
throw new BadRequestException("Organization not found");
}
var groupsList = groups?.ToList();
var usersList = users?.ToList();
var groupHasManageAccess = groupsList?.Any(g => g.Manage) ?? false;
var userHasManageAccess = usersList?.Any(u => u.Manage) ?? false;
if (!groupHasManageAccess && !userHasManageAccess)
{
throw new BadRequestException(
"At least one member or group must have can manage permission.");
}
if (collection.Id == default(Guid))
{
if (org.MaxCollections.HasValue)
@@ -61,26 +71,13 @@ public class CollectionService : ICollectionService
}
}
await _collectionRepository.CreateAsync(collection, org.UseGroups ? groups : null, users);
// Assign a user to the newly created collection.
if (assignUserId.HasValue)
{
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, assignUserId.Value);
if (orgUser != null && orgUser.Status == Enums.OrganizationUserStatusType.Confirmed)
{
await _collectionRepository.UpdateUsersAsync(collection.Id,
new List<CollectionAccessSelection> {
new CollectionAccessSelection { Id = orgUser.Id, Manage = true} });
}
}
await _collectionRepository.CreateAsync(collection, org.UseGroups ? groupsList : null, usersList);
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Created);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.CollectionCreated, org, _currentContext));
}
else
{
await _collectionRepository.ReplaceAsync(collection, org.UseGroups ? groups : null, users);
await _collectionRepository.ReplaceAsync(collection, org.UseGroups ? groupsList : null, usersList);
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Updated);
}
}

View File

@@ -1557,10 +1557,19 @@ public class StripePaymentService : IPaymentService
{
var subscriptionInfo = new SubscriptionInfo();
if (subscriber.IsUser() && !string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
if (!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
{
var customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId);
subscriptionInfo.UsingInAppPurchase = customer.Metadata.ContainsKey("appleReceipt");
if (customer.Discount != null)
{
subscriptionInfo.Discount = new SubscriptionInfo.BillingCustomerDiscount(customer.Discount);
}
if (subscriber.IsUser())
{
subscriptionInfo.UsingInAppPurchase = customer.Metadata.ContainsKey("appleReceipt");
}
}
if (!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))