mirror of
https://github.com/bitwarden/server
synced 2026-01-08 03:23:20 +00:00
[PM-20092] Refactor OrganizationUsersController Get to return account recovery users (#5756)
* wip * wip * add dict conversion to Get * wip * clean up * clean up * continue refactor * Fix feature flag Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> --------- Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
#nullable enable
|
||||
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Authorization.Requirements;
|
||||
|
||||
public class ManageAccountRecoveryRequirement : IOrganizationRequirement
|
||||
{
|
||||
public async Task<bool> AuthorizeAsync(
|
||||
CurrentContextOrganization? organizationClaims,
|
||||
Func<Task<bool>> isProviderUserForOrg)
|
||||
=> organizationClaims switch
|
||||
{
|
||||
{ Type: OrganizationUserType.Owner } => true,
|
||||
{ Type: OrganizationUserType.Admin } => true,
|
||||
{ Permissions.ManageResetPassword: true } => true,
|
||||
_ => await isProviderUserForOrg()
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
using Bit.Api.AdminConsole.Authorization.Requirements;
|
||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
using Bit.Api.Models.Request.Organizations;
|
||||
using Bit.Api.Models.Response;
|
||||
@@ -162,6 +163,12 @@ public class OrganizationUsersController : Controller
|
||||
[HttpGet("")]
|
||||
public async Task<ListResponseModel<OrganizationUserUserDetailsResponseModel>> Get(Guid orgId, bool includeGroups = false, bool includeCollections = false)
|
||||
{
|
||||
|
||||
if (_featureService.IsEnabled(FeatureFlagKeys.SeparateCustomRolePermissions))
|
||||
{
|
||||
return await GetvNextAsync(orgId, includeGroups, includeCollections);
|
||||
}
|
||||
|
||||
var authorized = (await _authorizationService.AuthorizeAsync(
|
||||
User, new OrganizationScope(orgId), OrganizationUserUserDetailsOperations.ReadAll)).Succeeded;
|
||||
if (!authorized)
|
||||
@@ -191,6 +198,37 @@ public class OrganizationUsersController : Controller
|
||||
return new ListResponseModel<OrganizationUserUserDetailsResponseModel>(responses);
|
||||
}
|
||||
|
||||
private async Task<ListResponseModel<OrganizationUserUserDetailsResponseModel>> GetvNextAsync(Guid orgId, bool includeGroups = false, bool includeCollections = false)
|
||||
{
|
||||
var request = new OrganizationUserUserDetailsQueryRequest
|
||||
{
|
||||
OrganizationId = orgId,
|
||||
IncludeGroups = includeGroups,
|
||||
IncludeCollections = includeCollections,
|
||||
};
|
||||
|
||||
if ((await _authorizationService.AuthorizeAsync(User, new ManageUsersRequirement())).Succeeded)
|
||||
{
|
||||
return GetResultListResponseModel(await _organizationUserUserDetailsQuery.Get(request));
|
||||
}
|
||||
|
||||
if ((await _authorizationService.AuthorizeAsync(User, new ManageAccountRecoveryRequirement())).Succeeded)
|
||||
{
|
||||
return GetResultListResponseModel(await _organizationUserUserDetailsQuery.GetAccountRecoveryEnrolledUsers(request));
|
||||
}
|
||||
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
private ListResponseModel<OrganizationUserUserDetailsResponseModel> GetResultListResponseModel(IEnumerable<(OrganizationUserUserDetails OrgUser,
|
||||
bool TwoFactorEnabled, bool ClaimedByOrganization)> results)
|
||||
{
|
||||
return new ListResponseModel<OrganizationUserUserDetailsResponseModel>(results
|
||||
.Select(result => new OrganizationUserUserDetailsResponseModel(result))
|
||||
.ToList());
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{id}/groups")]
|
||||
public async Task<IEnumerable<string>> GetGroups(string orgId, string id)
|
||||
{
|
||||
|
||||
@@ -126,6 +126,26 @@ public class OrganizationUserUserMiniDetailsResponseModel : ResponseModel
|
||||
|
||||
public class OrganizationUserUserDetailsResponseModel : OrganizationUserResponseModel
|
||||
{
|
||||
public OrganizationUserUserDetailsResponseModel((OrganizationUserUserDetails OrgUser, bool TwoFactorEnabled, bool ClaimedByOrganization) data, string obj = "organizationUserUserDetails")
|
||||
: base(data.OrgUser, obj)
|
||||
{
|
||||
if (data.OrgUser == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(data.OrgUser));
|
||||
}
|
||||
|
||||
Name = data.OrgUser.Name;
|
||||
Email = data.OrgUser.Email;
|
||||
AvatarColor = data.OrgUser.AvatarColor;
|
||||
TwoFactorEnabled = data.TwoFactorEnabled;
|
||||
SsoBound = !string.IsNullOrWhiteSpace(data.OrgUser.SsoExternalId);
|
||||
Collections = data.OrgUser.Collections.Select(c => new SelectionReadOnlyResponseModel(c));
|
||||
Groups = data.OrgUser.Groups;
|
||||
// Prevent reset password when using key connector.
|
||||
ResetPasswordEnrolled = ResetPasswordEnrolled && !data.OrgUser.UsesKeyConnector;
|
||||
ClaimedByOrganization = data.ClaimedByOrganization;
|
||||
}
|
||||
|
||||
public OrganizationUserUserDetailsResponseModel(OrganizationUserUserDetails organizationUser,
|
||||
bool twoFactorEnabled, bool claimedByOrganization, string obj = "organizationUserUserDetails")
|
||||
: base(organizationUser, obj)
|
||||
|
||||
Reference in New Issue
Block a user