1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 23:52:50 -05:00

[PM-14377] Add PATCH complete endpoint (#5100)

* 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 OperationAuthorizationRequirement for secruity task

* Added and registered MarkTaskAsCompletedCommand

* Added unit tests for the command

* Added complete endpoint

* removed false value
This commit is contained in:
SmithThe4th
2024-12-13 14:50:20 -05:00
committed by GitHub
parent c0a9c55891
commit 141a046a28
7 changed files with 207 additions and 2 deletions

View File

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Authorization.Infrastructure;
namespace Bit.Core.Vault.Authorization;
public class SecurityTaskOperationRequirement : OperationAuthorizationRequirement
{
public SecurityTaskOperationRequirement(string name)
{
Name = name;
}
}
public static class SecurityTaskOperations
{
public static readonly SecurityTaskOperationRequirement Update = new(nameof(Update));
}

View File

@ -0,0 +1,11 @@
namespace Bit.Core.Vault.Commands.Interfaces;
public interface IMarkTaskAsCompleteCommand
{
/// <summary>
/// Marks a task as complete.
/// </summary>
/// <param name="taskId">The unique identifier of the task to complete</param>
/// <returns>A task representing the async operation</returns>
Task CompleteAsync(Guid taskId);
}

View File

@ -0,0 +1,50 @@
using Bit.Core.Context;
using Bit.Core.Exceptions;
using Bit.Core.Utilities;
using Bit.Core.Vault.Authorization;
using Bit.Core.Vault.Commands.Interfaces;
using Bit.Core.Vault.Enums;
using Bit.Core.Vault.Repositories;
using Microsoft.AspNetCore.Authorization;
namespace Bit.Core.Vault.Commands;
public class MarkTaskAsCompletedCommand : IMarkTaskAsCompleteCommand
{
private readonly ISecurityTaskRepository _securityTaskRepository;
private readonly IAuthorizationService _authorizationService;
private readonly ICurrentContext _currentContext;
public MarkTaskAsCompletedCommand(
ISecurityTaskRepository securityTaskRepository,
IAuthorizationService authorizationService,
ICurrentContext currentContext)
{
_securityTaskRepository = securityTaskRepository;
_authorizationService = authorizationService;
_currentContext = currentContext;
}
/// <inheritdoc />
public async Task CompleteAsync(Guid taskId)
{
if (!_currentContext.UserId.HasValue)
{
throw new NotFoundException();
}
var task = await _securityTaskRepository.GetByIdAsync(taskId);
if (task is null)
{
throw new NotFoundException();
}
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, task,
SecurityTaskOperations.Update);
task.Status = SecurityTaskStatus.Completed;
task.RevisionDate = DateTime.UtcNow;
await _securityTaskRepository.ReplaceAsync(task);
}
}

View File

@ -1,4 +1,6 @@
using Bit.Core.Vault.Queries;
using Bit.Core.Vault.Commands;
using Bit.Core.Vault.Commands.Interfaces;
using Bit.Core.Vault.Queries;
using Microsoft.Extensions.DependencyInjection;
namespace Bit.Core.Vault;
@ -16,5 +18,6 @@ public static class VaultServiceCollectionExtensions
{
services.AddScoped<IOrganizationCiphersQuery, OrganizationCiphersQuery>();
services.AddScoped<IGetTaskDetailsForUserQuery, GetTaskDetailsForUserQuery>();
services.AddScoped<IMarkTaskAsCompleteCommand, MarkTaskAsCompletedCommand>();
}
}