mirror of
https://github.com/bitwarden/server.git
synced 2024-11-21 12:05:42 +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:
parent
d2567dd42d
commit
7fe4fe16cb
@ -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; }
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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.");
|
||||||
|
@ -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.");
|
||||||
|
@ -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) ||
|
||||||
|
@ -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);
|
||||||
|
@ -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";
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
"device",
|
"device",
|
||||||
"orgowner",
|
"orgowner",
|
||||||
"orgadmin",
|
"orgadmin",
|
||||||
"orgmanager",
|
|
||||||
"orguser",
|
"orguser",
|
||||||
"orgcustom",
|
"orgcustom",
|
||||||
"providerprovideradmin",
|
"providerprovideradmin",
|
||||||
|
Loading…
Reference in New Issue
Block a user