mirror of
https://github.com/bitwarden/server
synced 2026-01-27 06:43:19 +00:00
Handle revoked the new way
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
using Bit.Core.AdminConsole.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Services;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Models;
|
||||
|
||||
@@ -57,13 +57,24 @@ public class AcceptedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// </summary>
|
||||
public bool AccessSecretsManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the user's access has been revoked, false otherwise.
|
||||
/// </summary>
|
||||
public bool Revoked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Transitions this accepted user to a confirmed state when an organization admin confirms them.
|
||||
/// </summary>
|
||||
/// <param name="key">The Organization symmetric key encrypted with the User's public key.</param>
|
||||
/// <returns>A new <see cref="ConfirmedOrganizationUser"/> instance.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the user is revoked.</exception>
|
||||
public ConfirmedOrganizationUser ToConfirmed(string key)
|
||||
{
|
||||
if (Revoked)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot transition a revoked user to confirmed status");
|
||||
}
|
||||
|
||||
return new ConfirmedOrganizationUser
|
||||
{
|
||||
Id = Id,
|
||||
@@ -76,14 +87,15 @@ public class AcceptedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
CreationDate = CreationDate,
|
||||
RevisionDate = DateTime.UtcNow,
|
||||
Permissions = Permissions,
|
||||
AccessSecretsManager = AccessSecretsManager
|
||||
AccessSecretsManager = AccessSecretsManager,
|
||||
Revoked = false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this model to an <see cref="OrganizationUser"/> entity.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="OrganizationUser"/> entity with Status set to Accepted.</returns>
|
||||
/// <returns>An <see cref="OrganizationUser"/> entity with Status set to Accepted or Revoked based on the Revoked flag.</returns>
|
||||
public OrganizationUser ToEntity()
|
||||
{
|
||||
return new OrganizationUser
|
||||
@@ -94,7 +106,7 @@ public class AcceptedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
Email = null,
|
||||
Key = null,
|
||||
ResetPasswordKey = null,
|
||||
Status = OrganizationUserStatusType.Accepted,
|
||||
Status = Revoked ? OrganizationUserStatusType.Revoked : OrganizationUserStatusType.Accepted,
|
||||
Type = Type,
|
||||
ExternalId = ExternalId,
|
||||
CreationDate = CreationDate,
|
||||
@@ -107,16 +119,28 @@ public class AcceptedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// <summary>
|
||||
/// Creates an <see cref="AcceptedOrganizationUser"/> from an <see cref="OrganizationUser"/> entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to convert from. Must have Status = Accepted and UserId must not be null.</param>
|
||||
/// <param name="entity">The entity to convert from. Must have Status = Accepted or Revoked (with pre-revoked status of Accepted), and UserId must not be null.</param>
|
||||
/// <returns>A new <see cref="AcceptedOrganizationUser"/> instance.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the entity is not in Accepted status or UserId is null.</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the entity status is invalid or UserId is null.</exception>
|
||||
public static AcceptedOrganizationUser FromEntity(OrganizationUser entity)
|
||||
{
|
||||
if (entity.Status != OrganizationUserStatusType.Accepted)
|
||||
var isRevoked = entity.Status == OrganizationUserStatusType.Revoked;
|
||||
|
||||
if (!isRevoked && entity.Status != OrganizationUserStatusType.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create AcceptedOrganizationUser from entity with status {entity.Status}");
|
||||
}
|
||||
|
||||
if (isRevoked)
|
||||
{
|
||||
// Validate that the revoked user's pre-revoked status is Accepted
|
||||
var preRevokedStatus = OrganizationService.GetPriorActiveOrganizationUserStatusType(entity);
|
||||
if (preRevokedStatus != OrganizationUserStatusType.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create AcceptedOrganizationUser from revoked entity with pre-revoked status {preRevokedStatus}");
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity.UserId.HasValue)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create AcceptedOrganizationUser from entity with null UserId");
|
||||
@@ -132,7 +156,8 @@ public class AcceptedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
CreationDate = entity.CreationDate,
|
||||
RevisionDate = entity.RevisionDate,
|
||||
Permissions = entity.Permissions,
|
||||
AccessSecretsManager = entity.AccessSecretsManager
|
||||
AccessSecretsManager = entity.AccessSecretsManager,
|
||||
Revoked = isRevoked
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.Core.AdminConsole.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Services;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Models;
|
||||
|
||||
@@ -69,10 +69,15 @@ public class ConfirmedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// </summary>
|
||||
public bool AccessSecretsManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the user's access has been revoked, false otherwise.
|
||||
/// </summary>
|
||||
public bool Revoked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts this model to an <see cref="OrganizationUser"/> entity.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="OrganizationUser"/> entity with Status set to Confirmed.</returns>
|
||||
/// <returns>An <see cref="OrganizationUser"/> entity with Status set to Confirmed or Revoked based on the Revoked flag.</returns>
|
||||
public OrganizationUser ToEntity()
|
||||
{
|
||||
return new OrganizationUser
|
||||
@@ -83,7 +88,7 @@ public class ConfirmedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
Email = null,
|
||||
Key = Key,
|
||||
ResetPasswordKey = ResetPasswordKey,
|
||||
Status = OrganizationUserStatusType.Confirmed,
|
||||
Status = Revoked ? OrganizationUserStatusType.Revoked : OrganizationUserStatusType.Confirmed,
|
||||
Type = Type,
|
||||
ExternalId = ExternalId,
|
||||
CreationDate = CreationDate,
|
||||
@@ -96,16 +101,28 @@ public class ConfirmedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// <summary>
|
||||
/// Creates a <see cref="ConfirmedOrganizationUser"/> from an <see cref="OrganizationUser"/> entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to convert from. Must have Status = Confirmed, UserId and Key must not be null.</param>
|
||||
/// <param name="entity">The entity to convert from. Must have Status = Confirmed or Revoked (with pre-revoked status of Confirmed), UserId and Key must not be null.</param>
|
||||
/// <returns>A new <see cref="ConfirmedOrganizationUser"/> instance.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the entity is not in Confirmed status, or UserId or Key is null.</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the entity status is invalid, or UserId or Key is null.</exception>
|
||||
public static ConfirmedOrganizationUser FromEntity(OrganizationUser entity)
|
||||
{
|
||||
if (entity.Status != OrganizationUserStatusType.Confirmed)
|
||||
var isRevoked = entity.Status == OrganizationUserStatusType.Revoked;
|
||||
|
||||
if (!isRevoked && entity.Status != OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create ConfirmedOrganizationUser from entity with status {entity.Status}");
|
||||
}
|
||||
|
||||
if (isRevoked)
|
||||
{
|
||||
// Validate that the revoked user's pre-revoked status is Confirmed
|
||||
var preRevokedStatus = OrganizationService.GetPriorActiveOrganizationUserStatusType(entity);
|
||||
if (preRevokedStatus != OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create ConfirmedOrganizationUser from revoked entity with pre-revoked status {preRevokedStatus}");
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity.UserId.HasValue)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create ConfirmedOrganizationUser from entity with null UserId");
|
||||
@@ -128,7 +145,8 @@ public class ConfirmedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
CreationDate = entity.CreationDate,
|
||||
RevisionDate = entity.RevisionDate,
|
||||
Permissions = entity.Permissions,
|
||||
AccessSecretsManager = entity.AccessSecretsManager
|
||||
AccessSecretsManager = entity.AccessSecretsManager,
|
||||
Revoked = isRevoked
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Models;
|
||||
@@ -57,6 +58,11 @@ public class InvitedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// </summary>
|
||||
public bool AccessSecretsManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the user's access has been revoked, false otherwise.
|
||||
/// </summary>
|
||||
public bool Revoked { get; set; }
|
||||
|
||||
public void SetNewId()
|
||||
{
|
||||
Id = CoreHelpers.GenerateComb();
|
||||
@@ -67,8 +73,14 @@ public class InvitedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// </summary>
|
||||
/// <param name="userId">The ID of the User who accepted the invitation.</param>
|
||||
/// <returns>A new <see cref="AcceptedOrganizationUser"/> instance.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the user is revoked.</exception>
|
||||
public AcceptedOrganizationUser ToAccepted(Guid userId)
|
||||
{
|
||||
if (Revoked)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot transition a revoked user to accepted status");
|
||||
}
|
||||
|
||||
return new AcceptedOrganizationUser
|
||||
{
|
||||
Id = Id,
|
||||
@@ -79,14 +91,15 @@ public class InvitedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
CreationDate = CreationDate,
|
||||
RevisionDate = DateTime.UtcNow,
|
||||
Permissions = Permissions,
|
||||
AccessSecretsManager = AccessSecretsManager
|
||||
AccessSecretsManager = AccessSecretsManager,
|
||||
Revoked = false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this model to an <see cref="OrganizationUser"/> entity.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="OrganizationUser"/> entity with Status set to Invited.</returns>
|
||||
/// <returns>An <see cref="OrganizationUser"/> entity with Status set to Invited or Revoked based on the Revoked flag.</returns>
|
||||
public OrganizationUser ToEntity()
|
||||
{
|
||||
return new OrganizationUser
|
||||
@@ -97,7 +110,7 @@ public class InvitedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
Email = Email,
|
||||
Key = null,
|
||||
ResetPasswordKey = null,
|
||||
Status = OrganizationUserStatusType.Invited,
|
||||
Status = Revoked ? OrganizationUserStatusType.Revoked : OrganizationUserStatusType.Invited,
|
||||
Type = Type,
|
||||
ExternalId = ExternalId,
|
||||
CreationDate = CreationDate,
|
||||
@@ -110,16 +123,28 @@ public class InvitedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
/// <summary>
|
||||
/// Creates an <see cref="InvitedOrganizationUser"/> from an <see cref="OrganizationUser"/> entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to convert from. Must have Status = Invited and Email must not be null.</param>
|
||||
/// <param name="entity">The entity to convert from. Must have Status = Invited or Revoked (with pre-revoked status of Invited), and Email must not be null.</param>
|
||||
/// <returns>A new <see cref="InvitedOrganizationUser"/> instance.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the entity is not in Invited status or Email is null.</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the entity status is invalid or Email is null.</exception>
|
||||
public static InvitedOrganizationUser FromEntity(OrganizationUser entity)
|
||||
{
|
||||
if (entity.Status != OrganizationUserStatusType.Invited)
|
||||
var isRevoked = entity.Status == OrganizationUserStatusType.Revoked;
|
||||
|
||||
if (!isRevoked && entity.Status != OrganizationUserStatusType.Invited)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create InvitedOrganizationUser from entity with status {entity.Status}");
|
||||
}
|
||||
|
||||
if (isRevoked)
|
||||
{
|
||||
// Validate that the revoked user's pre-revoked status is Invited
|
||||
var preRevokedStatus = OrganizationService.GetPriorActiveOrganizationUserStatusType(entity);
|
||||
if (preRevokedStatus != OrganizationUserStatusType.Invited)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create InvitedOrganizationUser from revoked entity with pre-revoked status {preRevokedStatus}");
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(entity.Email))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create InvitedOrganizationUser from entity with null Email");
|
||||
@@ -135,7 +160,8 @@ public class InvitedOrganizationUser : IExternal, IOrganizationUserPermissions
|
||||
CreationDate = entity.CreationDate,
|
||||
RevisionDate = entity.RevisionDate,
|
||||
Permissions = entity.Permissions,
|
||||
AccessSecretsManager = entity.AccessSecretsManager
|
||||
AccessSecretsManager = entity.AccessSecretsManager,
|
||||
Revoked = isRevoked
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user