1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-01 08:02:49 -05:00

SqlServer split manage collection permission (#1594)

* SqlServer split manage collection permission

* Clarify names

* Test claims generation

* Test permission serialization

* Simplify claims building

* Use new collections permissions

* Throw on use of deprecated permissions

* Lower case all claims

* Remove todos

* Clean nonexistent project from test solution

* JsonIgnore for both system and newtonsoft json

* Make migrations more robust to multiple runs

* remove duplicate usings

* Remove obsolete permissions

* Test solutions separately to detect failures

* Handle dos line endings

* Fix collections create/update permissions

* Change restore cipher to edit permissions

* Improve formatting

* Simplify map

* Refactor test
This commit is contained in:
Matt Gibson
2021-10-05 11:12:05 -05:00
committed by GitHub
parent 55fa4a5f63
commit bd297fb7a2
25 changed files with 3639 additions and 129 deletions

View File

@ -142,7 +142,7 @@ namespace Bit.Core.Context
Organizations = GetOrganizations(claimsDict, orgApi);
Providers = GetProviders(claimsDict);
return Task.FromResult(0);
}
@ -210,7 +210,7 @@ namespace Bit.Core.Context
return organizations;
}
private List<CurrentContentProvider> GetProviders(Dictionary<string, IEnumerable<Claim>> claimsDict)
{
var providers = new List<CurrentContentProvider>();
@ -274,6 +274,7 @@ namespace Bit.Core.Context
return Task.FromResult(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Custom) ?? false);
}
public async Task<bool> AccessBusinessPortal(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
@ -298,16 +299,44 @@ namespace Bit.Core.Context
&& (o.Permissions?.AccessReports ?? false)) ?? false);
}
public async Task<bool> ManageAllCollections(Guid orgId)
public async Task<bool> CreateNewCollections(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageAllCollections ?? false)) ?? false);
&& (o.Permissions?.CreateNewCollections ?? false)) ?? false);
}
public async Task<bool> ManageAssignedCollections(Guid orgId)
public async Task<bool> EditAnyCollection(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.EditAnyCollection ?? false)) ?? false);
}
public async Task<bool> DeleteAnyCollection(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.DeleteAnyCollection ?? false)) ?? false);
}
public async Task<bool> ViewAllCollections(Guid orgId)
{
return await EditAnyCollection(orgId) || await DeleteAnyCollection(orgId);
}
public async Task<bool> EditAssignedCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageAssignedCollections ?? false)) ?? false);
&& (o.Permissions?.EditAssignedCollections ?? false)) ?? false);
}
public async Task<bool> DeleteAssignedCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.DeleteAssignedCollections ?? false)) ?? false);
}
public async Task<bool> ViewAssignedCollections(Guid orgId)
{
return await EditAssignedCollections(orgId) || await DeleteAssignedCollections(orgId);
}
public async Task<bool> ManageGroups(Guid orgId)
@ -431,8 +460,11 @@ namespace Bit.Core.Context
AccessEventLogs = hasClaim("accesseventlogs"),
AccessImportExport = hasClaim("accessimportexport"),
AccessReports = hasClaim("accessreports"),
ManageAllCollections = hasClaim("manageallcollections"),
ManageAssignedCollections = hasClaim("manageassignedcollections"),
CreateNewCollections = hasClaim("createnewcollections"),
EditAnyCollection = hasClaim("editanycollection"),
DeleteAnyCollection = hasClaim("deleteanycollection"),
EditAssignedCollections = hasClaim("editassignedcollections"),
DeleteAssignedCollections = hasClaim("deleteassignedcollections"),
ManageGroups = hasClaim("managegroups"),
ManagePolicies = hasClaim("managepolicies"),
ManageSso = hasClaim("managesso"),

View File

@ -40,8 +40,13 @@ namespace Bit.Core.Context
Task<bool> AccessEventLogs(Guid orgId);
Task<bool> AccessImportExport(Guid orgId);
Task<bool> AccessReports(Guid orgId);
Task<bool> ManageAllCollections(Guid orgId);
Task<bool> ManageAssignedCollections(Guid orgId);
Task<bool> CreateNewCollections(Guid orgId);
Task<bool> EditAnyCollection(Guid orgId);
Task<bool> DeleteAnyCollection(Guid orgId);
Task<bool> ViewAllCollections(Guid orgId);
Task<bool> EditAssignedCollections(Guid orgId);
Task<bool> DeleteAssignedCollections(Guid orgId);
Task<bool> ViewAssignedCollections(Guid orgId);
Task<bool> ManageGroups(Guid orgId);
Task<bool> ManagePolicies(Guid orgId);
Task<bool> ManageSso(Guid orgId);

View File

@ -1,3 +1,7 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Bit.Core.Models.Data
{
public class Permissions
@ -6,12 +10,39 @@ namespace Bit.Core.Models.Data
public bool AccessEventLogs { get; set; }
public bool AccessImportExport { get; set; }
public bool AccessReports { get; set; }
public bool ManageAssignedCollections { get; set; }
public bool ManageAllCollections { get; set; }
[Obsolete("This permission exists for client backwards-compatibility. It should not be used to determine permissions in this repository", true)]
public bool ManageAllCollections => CreateNewCollections && EditAnyCollection && DeleteAnyCollection;
public bool CreateNewCollections { get; set; }
public bool EditAnyCollection { get; set; }
public bool DeleteAnyCollection { get; set; }
[Obsolete("This permission exists for client backwards-compatibility. It should not be used to determine permissions in this repository", true)]
public bool ManageAssignedCollections => EditAssignedCollections && DeleteAssignedCollections;
public bool EditAssignedCollections { get; set; }
public bool DeleteAssignedCollections { get; set; }
public bool ManageGroups { get; set; }
public bool ManagePolicies { get; set; }
public bool ManageSso { get; set; }
public bool ManageUsers { get; set; }
public bool ManageResetPassword { get; set; }
[JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public List<(bool Permission, string ClaimName)> ClaimsMap => new()
{
(AccessBusinessPortal, "accessbusinessportal"),
(AccessEventLogs, "accesseventlogs"),
(AccessImportExport, "accessimportexport"),
(AccessReports, "accessreports"),
(CreateNewCollections, "createnewcollections"),
(EditAnyCollection, "editanycollection"),
(DeleteAnyCollection, "deleteanycollection"),
(EditAssignedCollections, "editassignedcollections"),
(DeleteAssignedCollections, "deleteassignedcollections"),
(ManageGroups, "managegroups"),
(ManagePolicies, "managepolicies"),
(ManageSso, "managesso"),
(ManageUsers, "manageusers"),
(ManageResetPassword, "manageresetpassword"),
};
}
}

View File

@ -242,6 +242,17 @@ namespace Bit.Core.Utilities
}
}
public static string GetEmbeddedResourceContentsAsync(string file)
{
var assembly = Assembly.GetCallingAssembly();
var resourceName = assembly.GetManifestResourceNames().Single(n => n.EndsWith(file));
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
public async static Task<X509Certificate2> GetBlobCertificateAsync(CloudStorageAccount cloudStorageAccount,
string container, string file, string password)
{
@ -827,60 +838,14 @@ namespace Bit.Core.Utilities
foreach (var org in group)
{
claims.Add(new KeyValuePair<string, string>("orgcustom", org.Id.ToString()));
foreach (var (permission, claimName) in org.Permissions.ClaimsMap)
{
if (!permission)
{
continue;
}
if (org.Permissions.AccessBusinessPortal)
{
claims.Add(new KeyValuePair<string, string>("accessbusinessportal", org.Id.ToString()));
}
if (org.Permissions.AccessEventLogs)
{
claims.Add(new KeyValuePair<string, string>("accesseventlogs", org.Id.ToString()));
}
if (org.Permissions.AccessImportExport)
{
claims.Add(new KeyValuePair<string, string>("accessimportexport", org.Id.ToString()));
}
if (org.Permissions.AccessReports)
{
claims.Add(new KeyValuePair<string, string>("accessreports", org.Id.ToString()));
}
if (org.Permissions.ManageAllCollections)
{
claims.Add(new KeyValuePair<string, string>("manageallcollections", org.Id.ToString()));
}
if (org.Permissions.ManageAssignedCollections)
{
claims.Add(new KeyValuePair<string, string>("manageassignedcollections", org.Id.ToString()));
}
if (org.Permissions.ManageGroups)
{
claims.Add(new KeyValuePair<string, string>("managegroups", org.Id.ToString()));
}
if (org.Permissions.ManagePolicies)
{
claims.Add(new KeyValuePair<string, string>("managepolicies", org.Id.ToString()));
}
if (org.Permissions.ManageSso)
{
claims.Add(new KeyValuePair<string, string>("managesso", org.Id.ToString()));
}
if (org.Permissions.ManageUsers)
{
claims.Add(new KeyValuePair<string, string>("manageusers", org.Id.ToString()));
}
if (org.Permissions.ManageResetPassword)
{
claims.Add(new KeyValuePair<string, string>("manageresetpassword", org.Id.ToString()));
claims.Add(new KeyValuePair<string, string>(claimName, org.Id.ToString()));
}
}
break;