mirror of
https://github.com/bitwarden/server.git
synced 2025-07-13 05:38:25 -05:00
[PM-14376] Add GET tasks endpoint (#5089)
* Added CQRS pattern * Added the GetManyByUserIdAsync signature to the repositiory * Added sql sproc Created user defined type to hold status Created migration file * Added ef core query * Added absract and concrete implementation for GetManyByUserIdStatusAsync * Added integration tests * Updated params to status * Implemented new query to utilize repository method * Added controller for the security task endpoint * Fixed lint issues * Added documentation * simplified to require single status modified script to check for users with edit rights * Updated ef core query * Added new assertions * simplified to require single status * fixed formatting * Fixed sql script * Removed default null * Added security tasks feature flag
This commit is contained in:
@ -0,0 +1,90 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Vault.Entities;
|
||||
using Bit.Core.Vault.Enums;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Vault.Repositories.Queries;
|
||||
|
||||
public class SecurityTaskReadByUserIdStatusQuery : IQuery<SecurityTask>
|
||||
{
|
||||
private readonly Guid _userId;
|
||||
private readonly SecurityTaskStatus? _status;
|
||||
|
||||
public SecurityTaskReadByUserIdStatusQuery(Guid userId, SecurityTaskStatus? status)
|
||||
{
|
||||
_userId = userId;
|
||||
_status = status;
|
||||
}
|
||||
|
||||
public IQueryable<SecurityTask> Run(DatabaseContext dbContext)
|
||||
{
|
||||
var query = from st in dbContext.SecurityTasks
|
||||
|
||||
join ou in dbContext.OrganizationUsers
|
||||
on st.OrganizationId equals ou.OrganizationId
|
||||
|
||||
join o in dbContext.Organizations
|
||||
on st.OrganizationId equals o.Id
|
||||
|
||||
join c in dbContext.Ciphers
|
||||
on st.CipherId equals c.Id into c_g
|
||||
from c in c_g.DefaultIfEmpty()
|
||||
|
||||
join cc in dbContext.CollectionCiphers
|
||||
on c.Id equals cc.CipherId into cc_g
|
||||
from cc in cc_g.DefaultIfEmpty()
|
||||
|
||||
join cu in dbContext.CollectionUsers
|
||||
on new { cc.CollectionId, 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 cg in dbContext.CollectionGroups
|
||||
on new { cc.CollectionId, gu.GroupId } equals
|
||||
new { cg.CollectionId, cg.GroupId } into cg_g
|
||||
from cg in cg_g.DefaultIfEmpty()
|
||||
|
||||
where
|
||||
ou.UserId == _userId &&
|
||||
ou.Status == OrganizationUserStatusType.Confirmed &&
|
||||
o.Enabled &&
|
||||
(
|
||||
st.CipherId == null ||
|
||||
(
|
||||
c != null &&
|
||||
(
|
||||
(cu != null && !cu.ReadOnly) || (cg != null && !cg.ReadOnly && cu == null)
|
||||
)
|
||||
)
|
||||
) &&
|
||||
(_status == null || st.Status == _status)
|
||||
group st by new
|
||||
{
|
||||
st.Id,
|
||||
st.OrganizationId,
|
||||
st.CipherId,
|
||||
st.Type,
|
||||
st.Status,
|
||||
st.CreationDate,
|
||||
st.RevisionDate
|
||||
} into g
|
||||
select new SecurityTask
|
||||
{
|
||||
Id = g.Key.Id,
|
||||
OrganizationId = g.Key.OrganizationId,
|
||||
CipherId = g.Key.CipherId,
|
||||
Type = g.Key.Type,
|
||||
Status = g.Key.Status,
|
||||
CreationDate = g.Key.CreationDate,
|
||||
RevisionDate = g.Key.RevisionDate
|
||||
};
|
||||
|
||||
return query.OrderByDescending(st => st.CreationDate);
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
using AutoMapper;
|
||||
using Bit.Core.Vault.Enums;
|
||||
using Bit.Core.Vault.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Vault.Models;
|
||||
using Bit.Infrastructure.EntityFramework.Vault.Repositories.Queries;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Vault.Repositories;
|
||||
@ -11,4 +14,15 @@ public class SecurityTaskRepository : Repository<Core.Vault.Entities.SecurityTas
|
||||
public SecurityTaskRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
|
||||
: base(serviceScopeFactory, mapper, (context) => context.SecurityTasks)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ICollection<Core.Vault.Entities.SecurityTask>> GetManyByUserIdStatusAsync(Guid userId,
|
||||
SecurityTaskStatus? status = null)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var query = new SecurityTaskReadByUserIdStatusQuery(userId, status);
|
||||
var data = await query.Run(dbContext).ToListAsync();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user