mirror of
https://github.com/bitwarden/server.git
synced 2025-07-05 01:52:49 -05:00
[AC-1880] Public API - Deprecated properties (#3706)
* feat: remove required for AccessAll and add xmldoc for usage restrictions, refs AC-1880 * feat: add validation for create group workflow wrt manage property, refs AC-1880 * feat: add validation for update group workflow wrt manage property, refs AC-1880 * feat: add validation for create and update member workflow wrt manage property, refs AC-1880 * feat: add validation for update collection workflow wrt manage property, refs AC-1880 * fix: flaky Public/GroupsControllerTests + more test coverage, refs AC-1880
This commit is contained in:
@ -36,10 +36,10 @@ public class CreateGroupCommand : ICreateGroupCommand
|
||||
}
|
||||
|
||||
public async Task CreateGroupAsync(Group group, Organization organization,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> users = null)
|
||||
{
|
||||
Validate(organization, group);
|
||||
Validate(organization, group, collections);
|
||||
await GroupRepositoryCreateGroupAsync(group, organization, collections);
|
||||
|
||||
if (users != null)
|
||||
@ -51,10 +51,10 @@ public class CreateGroupCommand : ICreateGroupCommand
|
||||
}
|
||||
|
||||
public async Task CreateGroupAsync(Group group, Organization organization, EventSystemUser systemUser,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> users = null)
|
||||
{
|
||||
Validate(organization, group);
|
||||
Validate(organization, group, collections);
|
||||
await GroupRepositoryCreateGroupAsync(group, organization, collections);
|
||||
|
||||
if (users != null)
|
||||
@ -103,7 +103,7 @@ public class CreateGroupCommand : ICreateGroupCommand
|
||||
}
|
||||
}
|
||||
|
||||
private static void Validate(Organization organization, Group group)
|
||||
private static void Validate(Organization organization, Group group, IEnumerable<CollectionAccessSelection> collections)
|
||||
{
|
||||
if (organization == null)
|
||||
{
|
||||
@ -115,9 +115,18 @@ public class CreateGroupCommand : ICreateGroupCommand
|
||||
throw new BadRequestException("This organization cannot use groups.");
|
||||
}
|
||||
|
||||
if (organization.FlexibleCollections && group.AccessAll)
|
||||
if (organization.FlexibleCollections)
|
||||
{
|
||||
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the group to collections instead.");
|
||||
if (group.AccessAll)
|
||||
{
|
||||
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the group to collections instead.");
|
||||
}
|
||||
|
||||
var invalidAssociations = collections?.Where(cas => cas.Manage && (cas.ReadOnly || cas.HidePasswords));
|
||||
if (invalidAssociations?.Any() ?? false)
|
||||
{
|
||||
throw new BadRequestException("The Manage property is mutually exclusive and cannot be true while the ReadOnly or HidePasswords properties are also true.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
|
||||
public interface ICreateGroupCommand
|
||||
{
|
||||
Task CreateGroupAsync(Group group, Organization organization,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> users = null);
|
||||
|
||||
Task CreateGroupAsync(Group group, Organization organization, EventSystemUser systemUser,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> users = null);
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
|
||||
public interface IUpdateGroupCommand
|
||||
{
|
||||
Task UpdateGroupAsync(Group group, Organization organization,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> users = null);
|
||||
|
||||
Task UpdateGroupAsync(Group group, Organization organization, EventSystemUser systemUser,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> users = null);
|
||||
}
|
||||
|
@ -26,10 +26,10 @@ public class UpdateGroupCommand : IUpdateGroupCommand
|
||||
}
|
||||
|
||||
public async Task UpdateGroupAsync(Group group, Organization organization,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> userIds = null)
|
||||
{
|
||||
Validate(organization, group);
|
||||
Validate(organization, group, collections);
|
||||
await GroupRepositoryUpdateGroupAsync(group, collections);
|
||||
|
||||
if (userIds != null)
|
||||
@ -41,10 +41,10 @@ public class UpdateGroupCommand : IUpdateGroupCommand
|
||||
}
|
||||
|
||||
public async Task UpdateGroupAsync(Group group, Organization organization, EventSystemUser systemUser,
|
||||
IEnumerable<CollectionAccessSelection> collections = null,
|
||||
ICollection<CollectionAccessSelection> collections = null,
|
||||
IEnumerable<Guid> userIds = null)
|
||||
{
|
||||
Validate(organization, group);
|
||||
Validate(organization, group, collections);
|
||||
await GroupRepositoryUpdateGroupAsync(group, collections);
|
||||
|
||||
if (userIds != null)
|
||||
@ -97,7 +97,7 @@ public class UpdateGroupCommand : IUpdateGroupCommand
|
||||
}
|
||||
}
|
||||
|
||||
private static void Validate(Organization organization, Group group)
|
||||
private static void Validate(Organization organization, Group group, IEnumerable<CollectionAccessSelection> collections)
|
||||
{
|
||||
if (organization == null)
|
||||
{
|
||||
@ -109,9 +109,18 @@ public class UpdateGroupCommand : IUpdateGroupCommand
|
||||
throw new BadRequestException("This organization cannot use groups.");
|
||||
}
|
||||
|
||||
if (organization.FlexibleCollections && group.AccessAll)
|
||||
if (organization.FlexibleCollections)
|
||||
{
|
||||
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the group to collections instead.");
|
||||
if (group.AccessAll)
|
||||
{
|
||||
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the group to collections instead.");
|
||||
}
|
||||
|
||||
var invalidAssociations = collections?.Where(cas => cas.Manage && (cas.ReadOnly || cas.HidePasswords));
|
||||
if (invalidAssociations?.Any() ?? false)
|
||||
{
|
||||
throw new BadRequestException("The Manage property is mutually exclusive and cannot be true while the ReadOnly or HidePasswords properties are also true.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public interface IOrganizationService
|
||||
Task<List<OrganizationUser>> InviteUsersAsync(Guid organizationId, EventSystemUser systemUser,
|
||||
IEnumerable<(OrganizationUserInvite invite, string externalId)> invites);
|
||||
Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid? invitingUserId, string email,
|
||||
OrganizationUserType type, bool accessAll, string externalId, IEnumerable<CollectionAccessSelection> collections, IEnumerable<Guid> groups);
|
||||
OrganizationUserType type, bool accessAll, string externalId, ICollection<CollectionAccessSelection> collections, IEnumerable<Guid> groups);
|
||||
Task<OrganizationUser> InviteUserAsync(Guid organizationId, EventSystemUser systemUser, string email,
|
||||
OrganizationUserType type, bool accessAll, string externalId, IEnumerable<CollectionAccessSelection> collections, IEnumerable<Guid> groups);
|
||||
Task<IEnumerable<Tuple<OrganizationUser, string>>> ResendInvitesAsync(Guid organizationId, Guid? invitingUserId, IEnumerable<Guid> organizationUsersId);
|
||||
@ -45,7 +45,7 @@ public interface IOrganizationService
|
||||
Guid confirmingUserId, IUserService userService);
|
||||
Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync(Guid organizationId, Dictionary<Guid, string> keys,
|
||||
Guid confirmingUserId, IUserService userService);
|
||||
Task SaveUserAsync(OrganizationUser user, Guid? savingUserId, IEnumerable<CollectionAccessSelection> collections, IEnumerable<Guid> groups);
|
||||
Task SaveUserAsync(OrganizationUser user, Guid? savingUserId, ICollection<CollectionAccessSelection> collections, IEnumerable<Guid> groups);
|
||||
[Obsolete("IDeleteOrganizationUserCommand should be used instead. To be removed by EC-607.")]
|
||||
Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid? deletingUserId);
|
||||
[Obsolete("IDeleteOrganizationUserCommand should be used instead. To be removed by EC-607.")]
|
||||
|
@ -1370,7 +1370,7 @@ public class OrganizationService : IOrganizationService
|
||||
}
|
||||
|
||||
public async Task SaveUserAsync(OrganizationUser user, Guid? savingUserId,
|
||||
IEnumerable<CollectionAccessSelection> collections,
|
||||
ICollection<CollectionAccessSelection> collections,
|
||||
IEnumerable<Guid> groups)
|
||||
{
|
||||
if (user.Id.Equals(default(Guid)))
|
||||
@ -1408,6 +1408,15 @@ public class OrganizationService : IOrganizationService
|
||||
{
|
||||
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the user to collections instead.");
|
||||
}
|
||||
|
||||
if (organizationAbility?.FlexibleCollections == true && collections?.Any() == true)
|
||||
{
|
||||
var invalidAssociations = collections.Where(cas => cas.Manage && (cas.ReadOnly || cas.HidePasswords));
|
||||
if (invalidAssociations.Any())
|
||||
{
|
||||
throw new BadRequestException("The Manage property is mutually exclusive and cannot be true while the ReadOnly or HidePasswords properties are also true.");
|
||||
}
|
||||
}
|
||||
// End Flexible Collections
|
||||
|
||||
// Only autoscale (if required) after all validation has passed so that we know it's a valid request before
|
||||
@ -1625,9 +1634,20 @@ public class OrganizationService : IOrganizationService
|
||||
}
|
||||
|
||||
public async Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid? invitingUserId, string email,
|
||||
OrganizationUserType type, bool accessAll, string externalId, IEnumerable<CollectionAccessSelection> collections,
|
||||
OrganizationUserType type, bool accessAll, string externalId, ICollection<CollectionAccessSelection> collections,
|
||||
IEnumerable<Guid> groups)
|
||||
{
|
||||
// Validate Collection associations if org is using latest collection enhancements
|
||||
var organizationAbility = await _applicationCacheService.GetOrganizationAbilityAsync(organizationId);
|
||||
if (organizationAbility?.FlexibleCollections ?? false)
|
||||
{
|
||||
var invalidAssociations = collections?.Where(cas => cas.Manage && (cas.ReadOnly || cas.HidePasswords));
|
||||
if (invalidAssociations?.Any() ?? false)
|
||||
{
|
||||
throw new BadRequestException("The Manage property is mutually exclusive and cannot be true while the ReadOnly or HidePasswords properties are also true.");
|
||||
}
|
||||
}
|
||||
|
||||
return await SaveUserSendInviteAsync(organizationId, invitingUserId, systemUser: null, email, type, accessAll, externalId, collections, groups);
|
||||
}
|
||||
|
||||
@ -1635,6 +1655,7 @@ public class OrganizationService : IOrganizationService
|
||||
OrganizationUserType type, bool accessAll, string externalId, IEnumerable<CollectionAccessSelection> collections,
|
||||
IEnumerable<Guid> groups)
|
||||
{
|
||||
// Collection associations validation not required as they are always an empty list - created via system user (scim)
|
||||
return await SaveUserSendInviteAsync(organizationId, invitingUserId: null, systemUser, email, type, accessAll, externalId, collections, groups);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user