1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-25 12:45:18 +01:00

[AC-1331] Remove Manager role - final (#4493)

* Remove OrganizationUserType.Manager

* Add EnumDataType validation to prevent invalid enum values
This commit is contained in:
Thomas Rittson 2024-07-12 06:13:10 +10:00 committed by GitHub
parent d2567dd42d
commit 7fe4fe16cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 6 additions and 108 deletions

View File

@ -14,6 +14,7 @@ public class OrganizationUserInviteRequestModel
[StrictEmailAddressList] [StrictEmailAddressList]
public IEnumerable<string> Emails { get; set; } public IEnumerable<string> Emails { get; set; }
[Required] [Required]
[EnumDataType(typeof(OrganizationUserType))]
public OrganizationUserType? Type { get; set; } public OrganizationUserType? Type { get; set; }
public bool AccessSecretsManager { get; set; } public bool AccessSecretsManager { get; set; }
public Permissions Permissions { get; set; } public Permissions Permissions { get; set; }
@ -83,6 +84,7 @@ public class OrganizationUserBulkConfirmRequestModel
public class OrganizationUserUpdateRequestModel public class OrganizationUserUpdateRequestModel
{ {
[Required] [Required]
[EnumDataType(typeof(OrganizationUserType))]
public OrganizationUserType? Type { get; set; } public OrganizationUserType? Type { get; set; }
public bool AccessSecretsManager { get; set; } public bool AccessSecretsManager { get; set; }
public Permissions Permissions { get; set; } public Permissions Permissions { get; set; }

View File

@ -45,10 +45,10 @@ public abstract class MemberBaseModel
} }
/// <summary> /// <summary>
/// The member's type (or role) within the organization. If your organization has is using the latest collection enhancements, /// The member's type (or role) within the organization.
/// you will not be allowed to assign the Manager role (OrganizationUserType = 3).
/// </summary> /// </summary>
[Required] [Required]
[EnumDataType(typeof(OrganizationUserType))]
public OrganizationUserType? Type { get; set; } public OrganizationUserType? Type { get; set; }
/// <summary> /// <summary>
/// External identifier for reference or linking this member to another system, such as a user directory. /// External identifier for reference or linking this member to another system, such as a user directory.

View File

@ -5,6 +5,6 @@ public enum OrganizationUserType : byte
Owner = 0, Owner = 0,
Admin = 1, Admin = 1,
User = 2, User = 2,
Manager = 3, // Manager = 3 has been intentionally permanently deleted
Custom = 4, Custom = 4,
} }

View File

@ -61,11 +61,6 @@ public class UpdateOrganizationUserCommand : IUpdateOrganizationUserCommand
// If the organization is using Flexible Collections, prevent use of any deprecated permissions // If the organization is using Flexible Collections, prevent use of any deprecated permissions
var organization = await _organizationRepository.GetByIdAsync(user.OrganizationId); var organization = await _organizationRepository.GetByIdAsync(user.OrganizationId);
if (organization.FlexibleCollections && user.Type == OrganizationUserType.Manager)
{
throw new BadRequestException("The Manager role has been deprecated by collection enhancements. Use the collection Can Manage permission instead.");
}
if (organization.FlexibleCollections && user.AccessAll) if (organization.FlexibleCollections && user.AccessAll)
{ {
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the user to collections instead."); throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the user to collections instead.");

View File

@ -1039,11 +1039,6 @@ public class OrganizationService : IOrganizationService
} }
// If the organization is using Flexible Collections, prevent use of any deprecated permissions // If the organization is using Flexible Collections, prevent use of any deprecated permissions
if (organization.FlexibleCollections && invites.Any(i => i.invite.Type is OrganizationUserType.Manager))
{
throw new BadRequestException("The Manager role has been deprecated by collection enhancements. Use the collection Can Manage permission instead.");
}
if (organization.FlexibleCollections && invites.Any(i => i.invite.AccessAll)) if (organization.FlexibleCollections && invites.Any(i => i.invite.AccessAll))
{ {
throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the user to collections instead."); throw new BadRequestException("The AccessAll property has been deprecated by collection enhancements. Assign the user to collections instead.");

View File

@ -217,17 +217,6 @@ public class CurrentContext : ICurrentContext
})); }));
} }
if (claimsDict.ContainsKey(Claims.OrganizationManager))
{
organizations.AddRange(claimsDict[Claims.OrganizationManager].Select(c =>
new CurrentContextOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Manager,
AccessSecretsManager = accessSecretsManager.ContainsKey(c.Value),
}));
}
if (claimsDict.ContainsKey(Claims.OrganizationCustom)) if (claimsDict.ContainsKey(Claims.OrganizationCustom))
{ {
organizations.AddRange(claimsDict[Claims.OrganizationCustom].Select(c => organizations.AddRange(claimsDict[Claims.OrganizationCustom].Select(c =>
@ -274,12 +263,6 @@ public class CurrentContext : ICurrentContext
return (Organizations?.Any(o => o.Id == orgId) ?? false) || await OrganizationOwner(orgId); return (Organizations?.Any(o => o.Id == orgId) ?? false) || await OrganizationOwner(orgId);
} }
public async Task<bool> OrganizationManager(Guid orgId)
{
return await OrganizationAdmin(orgId) ||
(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Manager) ?? false);
}
public async Task<bool> OrganizationAdmin(Guid orgId) public async Task<bool> OrganizationAdmin(Guid orgId)
{ {
return await OrganizationOwner(orgId) || return await OrganizationOwner(orgId) ||

View File

@ -36,8 +36,6 @@ public interface ICurrentContext
Task<bool> OrganizationUser(Guid orgId); Task<bool> OrganizationUser(Guid orgId);
[Obsolete("Manager role is deprecated after Flexible Collections.")]
Task<bool> OrganizationManager(Guid orgId);
Task<bool> OrganizationAdmin(Guid orgId); Task<bool> OrganizationAdmin(Guid orgId);
Task<bool> OrganizationOwner(Guid orgId); Task<bool> OrganizationOwner(Guid orgId);
Task<bool> OrganizationCustom(Guid orgId); Task<bool> OrganizationCustom(Guid orgId);

View File

@ -9,7 +9,6 @@ public static class Claims
public const string OrganizationOwner = "orgowner"; public const string OrganizationOwner = "orgowner";
public const string OrganizationAdmin = "orgadmin"; public const string OrganizationAdmin = "orgadmin";
public const string OrganizationManager = "orgmanager";
public const string OrganizationUser = "orguser"; public const string OrganizationUser = "orguser";
public const string OrganizationCustom = "orgcustom"; public const string OrganizationCustom = "orgcustom";
public const string ProviderAdmin = "providerprovideradmin"; public const string ProviderAdmin = "providerprovideradmin";

View File

@ -700,12 +700,6 @@ public static class CoreHelpers
claims.Add(new KeyValuePair<string, string>(Claims.OrganizationAdmin, org.Id.ToString())); claims.Add(new KeyValuePair<string, string>(Claims.OrganizationAdmin, org.Id.ToString()));
} }
break; break;
case Enums.OrganizationUserType.Manager:
foreach (var org in group)
{
claims.Add(new KeyValuePair<string, string>(Claims.OrganizationManager, org.Id.ToString()));
}
break;
case Enums.OrganizationUserType.User: case Enums.OrganizationUserType.User:
foreach (var org in group) foreach (var org in group)
{ {

View File

@ -20,7 +20,6 @@ public class ApiResources
Claims.Device, Claims.Device,
Claims.OrganizationOwner, Claims.OrganizationOwner,
Claims.OrganizationAdmin, Claims.OrganizationAdmin,
Claims.OrganizationManager,
Claims.OrganizationUser, Claims.OrganizationUser,
Claims.OrganizationCustom, Claims.OrganizationCustom,
Claims.ProviderAdmin, Claims.ProviderAdmin,

View File

@ -77,44 +77,6 @@ public class UpdateOrganizationUserCommandTests
Arg.Is<IEnumerable<Guid>>(i => i.Contains(newUserData.Id))); Arg.Is<IEnumerable<Guid>>(i => i.Contains(newUserData.Id)));
} }
[Theory, BitAutoData]
public async Task UpdateUserAsync_WithFlexibleCollections_WhenUpgradingToManager_Throws(
Organization organization,
[OrganizationUser(type: OrganizationUserType.User)] OrganizationUser oldUserData,
[OrganizationUser(type: OrganizationUserType.Manager)] OrganizationUser newUserData,
[OrganizationUser(type: OrganizationUserType.Owner, status: OrganizationUserStatusType.Confirmed)] OrganizationUser savingUser,
ICollection<CollectionAccessSelection> collections,
IEnumerable<Guid> groups,
SutProvider<UpdateOrganizationUserCommand> sutProvider)
{
organization.FlexibleCollections = true;
newUserData.Id = oldUserData.Id;
newUserData.UserId = oldUserData.UserId;
newUserData.OrganizationId = oldUserData.OrganizationId = savingUser.OrganizationId = organization.Id;
newUserData.Permissions = CoreHelpers.ClassToJsonData(new Permissions());
sutProvider.GetDependency<IOrganizationRepository>()
.GetByIdAsync(organization.Id)
.Returns(organization);
sutProvider.GetDependency<IOrganizationService>()
.HasConfirmedOwnersExceptAsync(newUserData.OrganizationId, Arg.Is<IEnumerable<Guid>>(i => i.Contains(newUserData.Id)))
.Returns(true);
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetByIdAsync(oldUserData.Id)
.Returns(oldUserData);
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyByOrganizationAsync(organization.Id, OrganizationUserType.Owner)
.Returns(new List<OrganizationUser> { savingUser });
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateUserAsync(newUserData, oldUserData.UserId, collections, groups));
Assert.Contains("manager role has been deprecated", exception.Message.ToLowerInvariant());
}
[Theory, BitAutoData] [Theory, BitAutoData]
public async Task UpdateUserAsync_WithFlexibleCollections_WithAccessAll_Throws( public async Task UpdateUserAsync_WithFlexibleCollections_WithAccessAll_Throws(
Organization organization, Organization organization,

View File

@ -732,7 +732,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
[Theory] [Theory]
[OrganizationCustomize(FlexibleCollections = false)] [OrganizationCustomize(FlexibleCollections = false)]
[BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Admin)]
[BitAutoData(OrganizationUserType.Manager)]
[BitAutoData(OrganizationUserType.Owner)] [BitAutoData(OrganizationUserType.Owner)]
[BitAutoData(OrganizationUserType.User)] [BitAutoData(OrganizationUserType.User)]
public async Task InviteUsers_WithNonCustomType_WhenUseCustomPermissionsIsFalse_Passes(OrganizationUserType inviteUserType, Organization organization, OrganizationUserInvite invite, public async Task InviteUsers_WithNonCustomType_WhenUseCustomPermissionsIsFalse_Passes(OrganizationUserType inviteUserType, Organization organization, OrganizationUserInvite invite,
@ -762,7 +761,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
[Theory] [Theory]
[OrganizationInviteCustomize( [OrganizationInviteCustomize(
InviteeUserType = OrganizationUserType.Manager, InviteeUserType = OrganizationUserType.User,
InvitorUserType = OrganizationUserType.Custom InvitorUserType = OrganizationUserType.Custom
), OrganizationCustomize(FlexibleCollections = false), BitAutoData] ), OrganizationCustomize(FlexibleCollections = false), BitAutoData]
public async Task InviteUsers_CustomUserWithoutManageUsersConfiguringUser_Throws(Organization organization, OrganizationUserInvite invite, public async Task InviteUsers_CustomUserWithoutManageUsersConfiguringUser_Throws(Organization organization, OrganizationUserInvite invite,
@ -1183,28 +1182,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
}); });
} }
[Theory, OrganizationCustomize(FlexibleCollections = true), BitAutoData]
public async Task InviteUsers_WithFlexibleCollections_WhenInvitingManager_Throws(Organization organization,
OrganizationUserInvite invite, OrganizationUser invitor, SutProvider<OrganizationService> sutProvider)
{
invite.Type = OrganizationUserType.Manager;
organization.FlexibleCollections = true;
sutProvider.GetDependency<IOrganizationRepository>()
.GetByIdAsync(organization.Id)
.Returns(organization);
sutProvider.GetDependency<ICurrentContext>()
.ManageUsers(organization.Id)
.Returns(true);
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.InviteUsersAsync(organization.Id, invitor.UserId, systemUser: null,
new (OrganizationUserInvite, string)[] { (invite, null) }));
Assert.Contains("manager role has been deprecated", exception.Message.ToLowerInvariant());
}
[Theory, OrganizationCustomize(FlexibleCollections = true), BitAutoData] [Theory, OrganizationCustomize(FlexibleCollections = true), BitAutoData]
public async Task InviteUsers_WithFlexibleCollections_WithAccessAll_Throws(Organization organization, public async Task InviteUsers_WithFlexibleCollections_WithAccessAll_Throws(Organization organization,
OrganizationUserInvite invite, OrganizationUser invitor, SutProvider<OrganizationService> sutProvider) OrganizationUserInvite invite, OrganizationUser invitor, SutProvider<OrganizationService> sutProvider)
@ -2297,7 +2274,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
[BitAutoData(OrganizationUserType.Owner)] [BitAutoData(OrganizationUserType.Owner)]
[BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Admin)]
[BitAutoData(OrganizationUserType.User)] [BitAutoData(OrganizationUserType.User)]
[BitAutoData(OrganizationUserType.Manager)]
public async Task ValidateOrganizationCustomPermissionsEnabledAsync_WithNotCustomType_IsValid( public async Task ValidateOrganizationCustomPermissionsEnabledAsync_WithNotCustomType_IsValid(
OrganizationUserType newType, OrganizationUserType newType,
Guid organizationId, Guid organizationId,

View File

@ -145,7 +145,6 @@ public class IdentityServerTests : IClassFixture<IdentityApplicationFactory>
[BitAutoData(OrganizationUserType.Owner)] [BitAutoData(OrganizationUserType.Owner)]
[BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Admin)]
[BitAutoData(OrganizationUserType.User)] [BitAutoData(OrganizationUserType.User)]
[BitAutoData(OrganizationUserType.Manager)]
[BitAutoData(OrganizationUserType.Custom)] [BitAutoData(OrganizationUserType.Custom)]
public async Task TokenEndpoint_GrantTypePassword_WithAllUserTypes_WithSsoPolicyDisabled_WithEnforceSsoPolicyForAllUsersTrue_Success(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername) public async Task TokenEndpoint_GrantTypePassword_WithAllUserTypes_WithSsoPolicyDisabled_WithEnforceSsoPolicyForAllUsersTrue_Success(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername)
{ {
@ -173,7 +172,6 @@ public class IdentityServerTests : IClassFixture<IdentityApplicationFactory>
[BitAutoData(OrganizationUserType.Owner)] [BitAutoData(OrganizationUserType.Owner)]
[BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Admin)]
[BitAutoData(OrganizationUserType.User)] [BitAutoData(OrganizationUserType.User)]
[BitAutoData(OrganizationUserType.Manager)]
[BitAutoData(OrganizationUserType.Custom)] [BitAutoData(OrganizationUserType.Custom)]
public async Task TokenEndpoint_GrantTypePassword_WithAllUserTypes_WithSsoPolicyDisabled_WithEnforceSsoPolicyForAllUsersFalse_Success(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername) public async Task TokenEndpoint_GrantTypePassword_WithAllUserTypes_WithSsoPolicyDisabled_WithEnforceSsoPolicyForAllUsersFalse_Success(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername)
{ {
@ -201,7 +199,6 @@ public class IdentityServerTests : IClassFixture<IdentityApplicationFactory>
[BitAutoData(OrganizationUserType.Owner)] [BitAutoData(OrganizationUserType.Owner)]
[BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Admin)]
[BitAutoData(OrganizationUserType.User)] [BitAutoData(OrganizationUserType.User)]
[BitAutoData(OrganizationUserType.Manager)]
[BitAutoData(OrganizationUserType.Custom)] [BitAutoData(OrganizationUserType.Custom)]
public async Task TokenEndpoint_GrantTypePassword_WithAllUserTypes_WithSsoPolicyEnabled_WithEnforceSsoPolicyForAllUsersTrue_Throw(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername) public async Task TokenEndpoint_GrantTypePassword_WithAllUserTypes_WithSsoPolicyEnabled_WithEnforceSsoPolicyForAllUsersTrue_Throw(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername)
{ {
@ -253,7 +250,6 @@ public class IdentityServerTests : IClassFixture<IdentityApplicationFactory>
[Theory] [Theory]
[BitAutoData(OrganizationUserType.User)] [BitAutoData(OrganizationUserType.User)]
[BitAutoData(OrganizationUserType.Manager)]
[BitAutoData(OrganizationUserType.Custom)] [BitAutoData(OrganizationUserType.Custom)]
public async Task TokenEndpoint_GrantTypePassword_WithNonOwnerOrAdmin_WithSsoPolicyEnabled_WithEnforceSsoPolicyForAllUsersFalse_Throws(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername) public async Task TokenEndpoint_GrantTypePassword_WithNonOwnerOrAdmin_WithSsoPolicyEnabled_WithEnforceSsoPolicyForAllUsersFalse_Throws(OrganizationUserType organizationUserType, Guid organizationId, string deviceId, int generatedUsername)
{ {

View File

@ -26,7 +26,6 @@
"device", "device",
"orgowner", "orgowner",
"orgadmin", "orgadmin",
"orgmanager",
"orguser", "orguser",
"orgcustom", "orgcustom",
"providerprovideradmin", "providerprovideradmin",