mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 00:22:50 -05:00
[AC-1139] Created new CollectionOperationRequirement ReadAllWithAccess
This commit is contained in:
@ -521,7 +521,7 @@ public class CollectionsController : Controller
|
|||||||
.GetManyByUserIdWithAccessAsync(_currentContext.UserId.Value, orgId);
|
.GetManyByUserIdWithAccessAsync(_currentContext.UserId.Value, orgId);
|
||||||
|
|
||||||
var readAllAuthorized =
|
var readAllAuthorized =
|
||||||
(await _authorizationService.AuthorizeAsync(User, CollectionOperations.ReadAll(orgId))).Succeeded;
|
(await _authorizationService.AuthorizeAsync(User, CollectionOperations.ReadAllWithAccess(orgId))).Succeeded;
|
||||||
if (readAllAuthorized)
|
if (readAllAuthorized)
|
||||||
{
|
{
|
||||||
// The user can view all collections, but they may not always be assigned to all of them
|
// The user can view all collections, but they may not always be assigned to all of them
|
||||||
|
@ -55,6 +55,10 @@ public class CollectionAuthorizationHandler : AuthorizationHandler<CollectionOpe
|
|||||||
case not null when requirement.Name == nameof(CollectionOperations.ReadAll):
|
case not null when requirement.Name == nameof(CollectionOperations.ReadAll):
|
||||||
await CanReadAllAsync(context, requirement, org);
|
await CanReadAllAsync(context, requirement, org);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case not null when requirement.Name == nameof(CollectionOperations.ReadAllWithAccess):
|
||||||
|
await CanReadAllWithAccessAsync(context, requirement, org);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,4 +92,34 @@ public class CollectionAuthorizationHandler : AuthorizationHandler<CollectionOpe
|
|||||||
// Acting user is neither a member of the target organization or a provider user, fail
|
// Acting user is neither a member of the target organization or a provider user, fail
|
||||||
context.Fail();
|
context.Fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task CanReadAllWithAccessAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
||||||
|
CurrentContextOrganization org)
|
||||||
|
{
|
||||||
|
if (org != null)
|
||||||
|
{
|
||||||
|
// Acting user is a member of the target organization, check permissions
|
||||||
|
if (org.Type is OrganizationUserType.Owner or OrganizationUserType.Admin ||
|
||||||
|
org.Permissions.ManageGroups ||
|
||||||
|
org.Permissions.ManageUsers ||
|
||||||
|
org.Permissions.EditAnyCollection ||
|
||||||
|
org.Permissions.DeleteAnyCollection)
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check if acting user is a provider user for the target organization
|
||||||
|
if (await _currentContext.ProviderUserForOrgAsync(requirement.OrganizationId))
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acting user is neither a member of the target organization or a provider user, fail
|
||||||
|
context.Fail();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,10 @@ public static class CollectionOperations
|
|||||||
{
|
{
|
||||||
return new CollectionOperationRequirement(nameof(ReadAll), organizationId);
|
return new CollectionOperationRequirement(nameof(ReadAll), organizationId);
|
||||||
}
|
}
|
||||||
|
public static CollectionOperationRequirement ReadAllWithAccess(Guid organizationId)
|
||||||
|
{
|
||||||
|
return new CollectionOperationRequirement(nameof(ReadAllWithAccess), organizationId);
|
||||||
|
}
|
||||||
public static readonly CollectionOperationRequirement Update = new() { Name = nameof(Update) };
|
public static readonly CollectionOperationRequirement Update = new() { Name = nameof(Update) };
|
||||||
public static readonly CollectionOperationRequirement Delete = new() { Name = nameof(Delete) };
|
public static readonly CollectionOperationRequirement Delete = new() { Name = nameof(Delete) };
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -100,7 +100,7 @@ public class CollectionsControllerTests
|
|||||||
Arg.Any<object>(),
|
Arg.Any<object>(),
|
||||||
Arg.Is<IEnumerable<IAuthorizationRequirement>>(requirements =>
|
Arg.Is<IEnumerable<IAuthorizationRequirement>>(requirements =>
|
||||||
requirements.Cast<CollectionOperationRequirement>().All(operation =>
|
requirements.Cast<CollectionOperationRequirement>().All(operation =>
|
||||||
operation.Name == nameof(CollectionOperations.ReadAll)
|
operation.Name == nameof(CollectionOperations.ReadAllWithAccess)
|
||||||
&& operation.OrganizationId == organization.Id)))
|
&& operation.OrganizationId == organization.Id)))
|
||||||
.Returns(AuthorizationResult.Success());
|
.Returns(AuthorizationResult.Success());
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ public class CollectionsControllerTests
|
|||||||
Arg.Any<object>(),
|
Arg.Any<object>(),
|
||||||
Arg.Is<IEnumerable<IAuthorizationRequirement>>(requirements =>
|
Arg.Is<IEnumerable<IAuthorizationRequirement>>(requirements =>
|
||||||
requirements.Cast<CollectionOperationRequirement>().All(operation =>
|
requirements.Cast<CollectionOperationRequirement>().All(operation =>
|
||||||
operation.Name == nameof(CollectionOperations.ReadAll)
|
operation.Name == nameof(CollectionOperations.ReadAllWithAccess)
|
||||||
&& operation.OrganizationId == organization.Id)))
|
&& operation.OrganizationId == organization.Id)))
|
||||||
.Returns(AuthorizationResult.Failed());
|
.Returns(AuthorizationResult.Failed());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user