mirror of
https://github.com/bitwarden/server.git
synced 2025-04-05 05:00:19 -05:00
Use closures
This commit is contained in:
parent
72ce1f147d
commit
faa2ff8b1d
@ -10,25 +10,46 @@ namespace Bit.Api.AdminConsole.Authorization;
|
|||||||
|
|
||||||
public static class ClaimsExtensions
|
public static class ClaimsExtensions
|
||||||
{
|
{
|
||||||
// Relevant claim types for organization roles, SM access, and custom permissions
|
/// <summary>
|
||||||
private static readonly IEnumerable<string> _relevantClaimTypes = new List<string>{
|
/// A delegate that returns true if the user has the specified claim type for an organization, false otherwise.
|
||||||
|
/// </summary>
|
||||||
|
private delegate bool HasClaim(string claimType);
|
||||||
|
|
||||||
|
// Relevant claim types required to build a CurrentContextOrganization object.
|
||||||
|
private static readonly IEnumerable<string> _relevantClaimTypes = new HashSet<string>{
|
||||||
Claims.OrganizationOwner,
|
Claims.OrganizationOwner,
|
||||||
Claims.OrganizationAdmin,
|
Claims.OrganizationAdmin,
|
||||||
Claims.OrganizationCustom,
|
Claims.OrganizationCustom,
|
||||||
Claims.OrganizationUser,
|
Claims.OrganizationUser,
|
||||||
Claims.SecretsManagerAccess,
|
Claims.SecretsManagerAccess,
|
||||||
}.Concat(new Permissions().ClaimsMap.Select(c => c.ClaimName));
|
Claims.CustomPermissions.AccessEventLogs,
|
||||||
|
Claims.CustomPermissions.AccessImportExport,
|
||||||
|
Claims.CustomPermissions.AccessReports,
|
||||||
|
Claims.CustomPermissions.CreateNewCollections,
|
||||||
|
Claims.CustomPermissions.EditAnyCollection,
|
||||||
|
Claims.CustomPermissions.DeleteAnyCollection,
|
||||||
|
Claims.CustomPermissions.ManageGroups,
|
||||||
|
Claims.CustomPermissions.ManagePolicies,
|
||||||
|
Claims.CustomPermissions.ManageSso,
|
||||||
|
Claims.CustomPermissions.ManageUsers,
|
||||||
|
Claims.CustomPermissions.ManageResetPassword,
|
||||||
|
Claims.CustomPermissions.ManageScim,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses a user's claims and returns an object representing their claims for the specified organization.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">The user who has the claims.</param>
|
||||||
|
/// <param name="organizationId">The organizationId to look for in the claims.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="CurrentContextOrganization"/> representing the user's claims for that organization, or null
|
||||||
|
/// if the user does not have any claims for that organization.
|
||||||
|
/// </returns>
|
||||||
public static CurrentContextOrganization? GetCurrentContextOrganization(this ClaimsPrincipal user, Guid organizationId)
|
public static CurrentContextOrganization? GetCurrentContextOrganization(this ClaimsPrincipal user, Guid organizationId)
|
||||||
{
|
{
|
||||||
var claimsDict = user.Claims
|
var hasClaim = GetClaimsParser(user, organizationId);
|
||||||
.Where(c => _relevantClaimTypes.Contains(c.Type) && Guid.TryParse(c.Value, out _))
|
|
||||||
.GroupBy(c => c.Type)
|
|
||||||
.ToDictionary(
|
|
||||||
c => c.Key,
|
|
||||||
c => c.Select(v => new Guid(v.Value)));
|
|
||||||
|
|
||||||
var role = claimsDict.GetRoleForOrganizationId(organizationId);
|
var role = GetRoleFromClaims(hasClaim);
|
||||||
if (!role.HasValue)
|
if (!role.HasValue)
|
||||||
{
|
{
|
||||||
// Not an organization member
|
// Not an organization member
|
||||||
@ -39,37 +60,48 @@ public static class ClaimsExtensions
|
|||||||
{
|
{
|
||||||
Id = organizationId,
|
Id = organizationId,
|
||||||
Type = role.Value,
|
Type = role.Value,
|
||||||
AccessSecretsManager = claimsDict.ContainsOrganizationId(Claims.SecretsManagerAccess, organizationId),
|
AccessSecretsManager = hasClaim(Claims.SecretsManagerAccess),
|
||||||
Permissions = role == OrganizationUserType.Custom
|
Permissions = role == OrganizationUserType.Custom
|
||||||
? claimsDict.GetPermissionsFromClaims(organizationId)
|
? GetPermissionsFromClaims(hasClaim)
|
||||||
: null
|
: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ContainsOrganizationId(this Dictionary<string, IEnumerable<Guid>> claimsDict, string claimType,
|
/// <summary>
|
||||||
Guid organizationId)
|
/// Creates a <see cref="HasClaim"/> delegate specific to the user and organization.
|
||||||
=> claimsDict.TryGetValue(claimType, out var claimValue) &&
|
/// </summary>
|
||||||
claimValue.Any(guid => guid == organizationId);
|
private static HasClaim GetClaimsParser(ClaimsPrincipal user, Guid organizationId)
|
||||||
|
|
||||||
private static OrganizationUserType? GetRoleForOrganizationId(this Dictionary<string, IEnumerable<Guid>> claimsDict,
|
|
||||||
Guid organizationId)
|
|
||||||
{
|
{
|
||||||
if (claimsDict.ContainsOrganizationId(Claims.OrganizationOwner, organizationId))
|
var claimsDict = user.Claims
|
||||||
|
.Where(c => _relevantClaimTypes.Contains(c.Type) && Guid.TryParse(c.Value, out _))
|
||||||
|
.GroupBy(c => c.Type)
|
||||||
|
.ToDictionary(
|
||||||
|
c => c.Key,
|
||||||
|
c => c.Select(v => new Guid(v.Value)));
|
||||||
|
|
||||||
|
return claimType
|
||||||
|
=> claimsDict.TryGetValue(claimType, out var claimValue) &&
|
||||||
|
claimValue.Any(v => v == organizationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OrganizationUserType? GetRoleFromClaims(HasClaim hasClaim)
|
||||||
|
{
|
||||||
|
if (hasClaim(Claims.OrganizationOwner))
|
||||||
{
|
{
|
||||||
return OrganizationUserType.Owner;
|
return OrganizationUserType.Owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (claimsDict.ContainsOrganizationId(Claims.OrganizationAdmin, organizationId))
|
if (hasClaim(Claims.OrganizationAdmin))
|
||||||
{
|
{
|
||||||
return OrganizationUserType.Admin;
|
return OrganizationUserType.Admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (claimsDict.ContainsOrganizationId(Claims.OrganizationCustom, organizationId))
|
if (hasClaim(Claims.OrganizationCustom))
|
||||||
{
|
{
|
||||||
return OrganizationUserType.Custom;
|
return OrganizationUserType.Custom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (claimsDict.ContainsOrganizationId(Claims.OrganizationUser, organizationId))
|
if (hasClaim(Claims.OrganizationUser))
|
||||||
{
|
{
|
||||||
return OrganizationUserType.User;
|
return OrganizationUserType.User;
|
||||||
}
|
}
|
||||||
@ -77,22 +109,20 @@ public static class ClaimsExtensions
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Permissions GetPermissionsFromClaims(this Dictionary<string, IEnumerable<Guid>> claimsDict, Guid organizationId)
|
private static Permissions GetPermissionsFromClaims(HasClaim hasClaim)
|
||||||
|
=> new()
|
||||||
{
|
{
|
||||||
return new Permissions
|
AccessEventLogs = hasClaim(Claims.CustomPermissions.AccessEventLogs),
|
||||||
{
|
AccessImportExport = hasClaim(Claims.CustomPermissions.AccessImportExport),
|
||||||
AccessEventLogs = claimsDict.ContainsOrganizationId(Claims.AccessEventLogs, organizationId),
|
AccessReports = hasClaim(Claims.CustomPermissions.AccessReports),
|
||||||
AccessImportExport = claimsDict.ContainsOrganizationId(Claims.AccessImportExport, organizationId),
|
CreateNewCollections = hasClaim(Claims.CustomPermissions.CreateNewCollections),
|
||||||
AccessReports = claimsDict.ContainsOrganizationId(Claims.AccessReports, organizationId),
|
EditAnyCollection = hasClaim(Claims.CustomPermissions.EditAnyCollection),
|
||||||
CreateNewCollections = claimsDict.ContainsOrganizationId(Claims.CreateNewCollections, organizationId),
|
DeleteAnyCollection = hasClaim(Claims.CustomPermissions.DeleteAnyCollection),
|
||||||
EditAnyCollection = claimsDict.ContainsOrganizationId(Claims.EditAnyCollection, organizationId),
|
ManageGroups = hasClaim(Claims.CustomPermissions.ManageGroups),
|
||||||
DeleteAnyCollection = claimsDict.ContainsOrganizationId(Claims.DeleteAnyCollection, organizationId),
|
ManagePolicies = hasClaim(Claims.CustomPermissions.ManagePolicies),
|
||||||
ManageGroups = claimsDict.ContainsOrganizationId(Claims.ManageGroups, organizationId),
|
ManageSso = hasClaim(Claims.CustomPermissions.ManageSso),
|
||||||
ManagePolicies = claimsDict.ContainsOrganizationId(Claims.ManagePolicies, organizationId),
|
ManageUsers = hasClaim(Claims.CustomPermissions.ManageUsers),
|
||||||
ManageSso = claimsDict.ContainsOrganizationId(Claims.ManageSso, organizationId),
|
ManageResetPassword = hasClaim(Claims.CustomPermissions.ManageResetPassword),
|
||||||
ManageUsers = claimsDict.ContainsOrganizationId(Claims.ManageUsers, organizationId),
|
ManageScim = hasClaim(Claims.CustomPermissions.ManageScim),
|
||||||
ManageResetPassword = claimsDict.ContainsOrganizationId(Claims.ManageResetPassword, organizationId),
|
};
|
||||||
ManageScim = claimsDict.ContainsOrganizationId(Claims.ManageScim, organizationId),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,17 +21,17 @@ public class Permissions
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public List<(bool Permission, string ClaimName)> ClaimsMap => new()
|
public List<(bool Permission, string ClaimName)> ClaimsMap => new()
|
||||||
{
|
{
|
||||||
(AccessEventLogs, Claims.AccessEventLogs),
|
(AccessEventLogs, Claims.CustomPermissions.AccessEventLogs),
|
||||||
(AccessImportExport, Claims.AccessImportExport),
|
(AccessImportExport, Claims.CustomPermissions.AccessImportExport),
|
||||||
(AccessReports, Claims.AccessReports),
|
(AccessReports, Claims.CustomPermissions.AccessReports),
|
||||||
(CreateNewCollections, Claims.CreateNewCollections),
|
(CreateNewCollections, Claims.CustomPermissions.CreateNewCollections),
|
||||||
(EditAnyCollection, Claims.EditAnyCollection),
|
(EditAnyCollection, Claims.CustomPermissions.EditAnyCollection),
|
||||||
(DeleteAnyCollection, Claims.DeleteAnyCollection),
|
(DeleteAnyCollection, Claims.CustomPermissions.DeleteAnyCollection),
|
||||||
(ManageGroups, Claims.ManageGroups),
|
(ManageGroups, Claims.CustomPermissions.ManageGroups),
|
||||||
(ManagePolicies, Claims.ManagePolicies),
|
(ManagePolicies, Claims.CustomPermissions.ManagePolicies),
|
||||||
(ManageSso, Claims.ManageSso),
|
(ManageSso, Claims.CustomPermissions.ManageSso),
|
||||||
(ManageUsers, Claims.ManageUsers),
|
(ManageUsers, Claims.CustomPermissions.ManageUsers),
|
||||||
(ManageResetPassword, Claims.ManageResetPassword),
|
(ManageResetPassword, Claims.CustomPermissions.ManageResetPassword),
|
||||||
(ManageScim, Claims.ManageScim),
|
(ManageScim, Claims.CustomPermissions.ManageScim),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,17 +23,20 @@ public static class Claims
|
|||||||
// General
|
// General
|
||||||
public const string Type = "type";
|
public const string Type = "type";
|
||||||
|
|
||||||
// Organization permissions
|
// Organization custom permissions
|
||||||
public const string AccessEventLogs = "accesseventlogs";
|
public static class CustomPermissions
|
||||||
public const string AccessImportExport = "accessimportexport";
|
{
|
||||||
public const string AccessReports = "accessreports";
|
public const string AccessEventLogs = "accesseventlogs";
|
||||||
public const string CreateNewCollections = "createnewcollections";
|
public const string AccessImportExport = "accessimportexport";
|
||||||
public const string EditAnyCollection = "editanycollection";
|
public const string AccessReports = "accessreports";
|
||||||
public const string DeleteAnyCollection = "deleteanycollection";
|
public const string CreateNewCollections = "createnewcollections";
|
||||||
public const string ManageGroups = "managegroups";
|
public const string EditAnyCollection = "editanycollection";
|
||||||
public const string ManagePolicies = "managepolicies";
|
public const string DeleteAnyCollection = "deleteanycollection";
|
||||||
public const string ManageSso = "managesso";
|
public const string ManageGroups = "managegroups";
|
||||||
public const string ManageUsers = "manageusers";
|
public const string ManagePolicies = "managepolicies";
|
||||||
public const string ManageResetPassword = "manageresetpassword";
|
public const string ManageSso = "managesso";
|
||||||
public const string ManageScim = "managescim";
|
public const string ManageUsers = "manageusers";
|
||||||
|
public const string ManageResetPassword = "manageresetpassword";
|
||||||
|
public const string ManageScim = "managescim";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user