mirror of
https://github.com/bitwarden/server.git
synced 2025-04-19 12:08:11 -05:00

* Updated sprocs to return unmanaged collection column, updated reponse to return to return unmanaged * reformatted sproc
101 lines
4.5 KiB
C#
101 lines
4.5 KiB
C#
using Bit.Core.Enums;
|
|
using Bit.Core.Models.Data;
|
|
|
|
namespace Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
|
|
|
/// <summary>
|
|
/// Query to get collection details, including permissions for the specified user if provided.
|
|
/// </summary>
|
|
public class CollectionAdminDetailsQuery : IQuery<CollectionAdminDetails>
|
|
{
|
|
private readonly Guid? _userId;
|
|
private readonly Guid? _organizationId;
|
|
private readonly Guid? _collectionId;
|
|
|
|
private CollectionAdminDetailsQuery(Guid? userId, Guid? organizationId, Guid? collectionId)
|
|
{
|
|
_userId = userId;
|
|
_organizationId = organizationId;
|
|
_collectionId = collectionId;
|
|
}
|
|
|
|
public virtual IQueryable<CollectionAdminDetails> Run(DatabaseContext dbContext)
|
|
{
|
|
var baseCollectionQuery = from c in dbContext.Collections
|
|
join ou in dbContext.OrganizationUsers
|
|
on new { c.OrganizationId, UserId = _userId } equals
|
|
new { ou.OrganizationId, ou.UserId } into ou_g
|
|
from ou in ou_g.DefaultIfEmpty()
|
|
|
|
join cu in dbContext.CollectionUsers
|
|
on new { CollectionId = c.Id, OrganizationUserId = ou.Id } equals
|
|
new { cu.CollectionId, cu.OrganizationUserId } into cu_g
|
|
from cu in cu_g.DefaultIfEmpty()
|
|
|
|
join gu in dbContext.GroupUsers
|
|
on new { CollectionId = (Guid?)cu.CollectionId, OrganizationUserId = ou.Id } equals
|
|
new { CollectionId = (Guid?)null, gu.OrganizationUserId } into gu_g
|
|
from gu in gu_g.DefaultIfEmpty()
|
|
|
|
join g in dbContext.Groups
|
|
on gu.GroupId equals g.Id into g_g
|
|
from g in g_g.DefaultIfEmpty()
|
|
|
|
join cg in dbContext.CollectionGroups
|
|
on new { CollectionId = c.Id, gu.GroupId } equals
|
|
new { cg.CollectionId, cg.GroupId } into cg_g
|
|
from cg in cg_g.DefaultIfEmpty()
|
|
select new { c, cu, cg };
|
|
|
|
// Subqueries to determine if a colection is managed by an active user or group.
|
|
var activeUserManageRights = from cu in dbContext.CollectionUsers
|
|
join ou in dbContext.OrganizationUsers
|
|
on cu.OrganizationUserId equals ou.Id
|
|
where ou.Status == OrganizationUserStatusType.Confirmed && cu.Manage
|
|
select cu.CollectionId;
|
|
|
|
var activeGroupManageRights = from cg in dbContext.CollectionGroups
|
|
where cg.Manage
|
|
select cg.CollectionId;
|
|
|
|
if (_organizationId.HasValue)
|
|
{
|
|
baseCollectionQuery = baseCollectionQuery.Where(x => x.c.OrganizationId == _organizationId);
|
|
}
|
|
else if (_collectionId.HasValue)
|
|
{
|
|
baseCollectionQuery = baseCollectionQuery.Where(x => x.c.Id == _collectionId);
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("OrganizationId or CollectionId must be specified.");
|
|
}
|
|
|
|
return baseCollectionQuery.Select(x => new CollectionAdminDetails
|
|
{
|
|
Id = x.c.Id,
|
|
OrganizationId = x.c.OrganizationId,
|
|
Name = x.c.Name,
|
|
ExternalId = x.c.ExternalId,
|
|
CreationDate = x.c.CreationDate,
|
|
RevisionDate = x.c.RevisionDate,
|
|
ReadOnly = (bool?)x.cu.ReadOnly ?? (bool?)x.cg.ReadOnly ?? false,
|
|
HidePasswords = (bool?)x.cu.HidePasswords ?? (bool?)x.cg.HidePasswords ?? false,
|
|
Manage = (bool?)x.cu.Manage ?? (bool?)x.cg.Manage ?? false,
|
|
Assigned = x.cu != null || x.cg != null,
|
|
Unmanaged = !activeUserManageRights.Contains(x.c.Id) && !activeGroupManageRights.Contains(x.c.Id),
|
|
});
|
|
}
|
|
|
|
public static CollectionAdminDetailsQuery ByCollectionId(Guid collectionId, Guid? userId)
|
|
{
|
|
return new CollectionAdminDetailsQuery(userId, null, collectionId);
|
|
}
|
|
|
|
public static CollectionAdminDetailsQuery ByOrganizationId(Guid organizationId, Guid? userId)
|
|
{
|
|
return new CollectionAdminDetailsQuery(userId, organizationId, null);
|
|
}
|
|
|
|
}
|