mirror of
https://github.com/bitwarden/server
synced 2026-01-04 17:43:53 +00:00
api adjustments for manager role and collections
This commit is contained in:
@@ -111,6 +111,16 @@ namespace Bit.Core
|
||||
Type = OrganizationUserType.User
|
||||
}));
|
||||
}
|
||||
|
||||
if(claimsDict.ContainsKey("orgmanager"))
|
||||
{
|
||||
Organizations.AddRange(claimsDict["orgmanager"].Select(c =>
|
||||
new CurrentContentOrganization
|
||||
{
|
||||
Id = new Guid(c.Value),
|
||||
Type = OrganizationUserType.Manager
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public bool OrganizationUser(Guid orgId)
|
||||
@@ -118,6 +128,13 @@ namespace Bit.Core
|
||||
return Organizations?.Any(o => o.Id == orgId) ?? false;
|
||||
}
|
||||
|
||||
public bool OrganizationManager(Guid orgId)
|
||||
{
|
||||
return Organizations?.Any(o => o.Id == orgId &&
|
||||
(o.Type == OrganizationUserType.Owner || o.Type == OrganizationUserType.Admin ||
|
||||
o.Type == OrganizationUserType.Manager)) ?? false;
|
||||
}
|
||||
|
||||
public bool OrganizationAdmin(Guid orgId)
|
||||
{
|
||||
return Organizations?.Any(o => o.Id == orgId &&
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{
|
||||
Owner = 0,
|
||||
Admin = 1,
|
||||
User = 2
|
||||
User = 2,
|
||||
Manager = 3,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Bit.Core.IdentityServer
|
||||
"device",
|
||||
"orgowner",
|
||||
"orgadmin",
|
||||
"orgmanager",
|
||||
"orguser"
|
||||
}),
|
||||
new ApiResource("internal", new string[] { JwtClaimTypes.Subject }),
|
||||
|
||||
@@ -75,6 +75,12 @@ namespace Bit.Core.IdentityServer
|
||||
newClaims.Add(new Claim("orgadmin", org.Id.ToString()));
|
||||
}
|
||||
break;
|
||||
case Enums.OrganizationUserType.Manager:
|
||||
foreach(var org in group)
|
||||
{
|
||||
newClaims.Add(new Claim("orgmanager", org.Id.ToString()));
|
||||
}
|
||||
break;
|
||||
case Enums.OrganizationUserType.User:
|
||||
foreach(var org in group)
|
||||
{
|
||||
|
||||
@@ -10,11 +10,14 @@ namespace Bit.Core.Repositories
|
||||
{
|
||||
Task<int> GetCountByOrganizationIdAsync(Guid organizationId);
|
||||
Task<Tuple<Collection, ICollection<SelectionReadOnly>>> GetByIdWithGroupsAsync(Guid id);
|
||||
Task<Tuple<CollectionDetails, ICollection<SelectionReadOnly>>> GetByIdWithGroupsAsync(Guid id, Guid userId);
|
||||
Task<ICollection<Collection>> GetManyByOrganizationIdAsync(Guid organizationId);
|
||||
Task<CollectionDetails> GetByIdAsync(Guid id, Guid userId);
|
||||
Task<ICollection<CollectionDetails>> GetManyByUserIdAsync(Guid userId);
|
||||
Task<ICollection<CollectionUserDetails>> GetManyUserDetailsByIdAsync(Guid organizationId, Guid collectionId);
|
||||
Task CreateAsync(Collection obj, IEnumerable<SelectionReadOnly> groups);
|
||||
Task ReplaceAsync(Collection obj, IEnumerable<SelectionReadOnly> groups);
|
||||
Task DeleteUserAsync(Guid collectionId, Guid organizationUserId);
|
||||
Task UpdateUsersAsync(Guid id, IEnumerable<SelectionReadOnly> users);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,23 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Tuple<CollectionDetails, ICollection<SelectionReadOnly>>> GetByIdWithGroupsAsync(
|
||||
Guid id, Guid userId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryMultipleAsync(
|
||||
$"[{Schema}].[Collection_ReadWithGroupsByIdUserId]",
|
||||
new { Id = id, UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
var collection = await results.ReadFirstOrDefaultAsync<CollectionDetails>();
|
||||
var groups = (await results.ReadAsync<SelectionReadOnly>()).ToList();
|
||||
|
||||
return new Tuple<CollectionDetails, ICollection<SelectionReadOnly>>(collection, groups);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<Collection>> GetManyByOrganizationIdAsync(Guid organizationId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
@@ -64,6 +81,19 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<CollectionDetails> GetByIdAsync(Guid id, Guid userId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<CollectionDetails>(
|
||||
$"[{Schema}].[Collection_ReadByIdUserId]",
|
||||
new { Id = id, UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<CollectionDetails>> GetManyByUserIdAsync(Guid userId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
@@ -108,7 +138,7 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.ExecuteAsync(
|
||||
$"[{Schema}].[Collection_CreateWithGroups]",
|
||||
$"[{Schema}].[Collection_CreateWithGroupsAndUsers]",
|
||||
objWithGroups,
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
@@ -128,6 +158,17 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CreateUserAsync(Guid collectionId, Guid organizationUserId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.ExecuteAsync(
|
||||
$"[{Schema}].[CollectionUser_Create]",
|
||||
new { CollectionId = collectionId, OrganizationUserId = organizationUserId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteUserAsync(Guid collectionId, Guid organizationUserId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
@@ -139,6 +180,17 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateUsersAsync(Guid id, IEnumerable<SelectionReadOnly> users)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.ExecuteAsync(
|
||||
$"[{Schema}].[Collection_UpdateUsers]",
|
||||
new { Id = id, Users = users.ToArrayTVP() },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
}
|
||||
|
||||
public class CollectionWithGroups : Collection
|
||||
{
|
||||
public DataTable Groups { get; set; }
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public interface ICollectionService
|
||||
{
|
||||
Task SaveAsync(Collection collection, IEnumerable<SelectionReadOnly> groups = null);
|
||||
Task SaveAsync(Collection collection, IEnumerable<SelectionReadOnly> groups = null, Guid? assignUserId = null);
|
||||
Task DeleteAsync(Collection collection);
|
||||
Task DeleteUserAsync(Collection collection, Guid organizationUserId);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ namespace Bit.Core.Services
|
||||
_mailService = mailService;
|
||||
}
|
||||
|
||||
public async Task SaveAsync(Collection collection, IEnumerable<SelectionReadOnly> groups = null)
|
||||
public async Task SaveAsync(Collection collection, IEnumerable<SelectionReadOnly> groups = null,
|
||||
Guid? assignUserId = null)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
|
||||
if(org == null)
|
||||
@@ -62,6 +63,18 @@ namespace Bit.Core.Services
|
||||
await _collectionRepository.CreateAsync(collection, groups);
|
||||
}
|
||||
|
||||
// Assign a user to the newly created collection.
|
||||
if(assignUserId.HasValue)
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, assignUserId.Value);
|
||||
if(orgUser != null && orgUser.Status == Enums.OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
await _collectionRepository.UpdateUsersAsync(collection.Id,
|
||||
new List<SelectionReadOnly> {
|
||||
new SelectionReadOnly { Id = orgUser.Id, ReadOnly = false } });
|
||||
}
|
||||
}
|
||||
|
||||
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Created);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user