using Bit.Api.Models.Response; using Bit.Api.Vault.Models.Request; using Bit.Api.Vault.Models.Response; using Bit.Core; using Bit.Core.Services; using Bit.Core.Utilities; using Bit.Core.Vault.Commands.Interfaces; using Bit.Core.Vault.Enums; using Bit.Core.Vault.Queries; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.Vault.Controllers; [Route("tasks")] [Authorize("Application")] [RequireFeature(FeatureFlagKeys.SecurityTasks)] public class SecurityTaskController : Controller { private readonly IUserService _userService; private readonly IGetTaskDetailsForUserQuery _getTaskDetailsForUserQuery; private readonly IMarkTaskAsCompleteCommand _markTaskAsCompleteCommand; private readonly IGetTasksForOrganizationQuery _getTasksForOrganizationQuery; private readonly ICreateManyTasksCommand _createManyTasksCommand; private readonly ICreateManyTaskNotificationsCommand _createManyTaskNotificationsCommand; public SecurityTaskController( IUserService userService, IGetTaskDetailsForUserQuery getTaskDetailsForUserQuery, IMarkTaskAsCompleteCommand markTaskAsCompleteCommand, IGetTasksForOrganizationQuery getTasksForOrganizationQuery, ICreateManyTasksCommand createManyTasksCommand, ICreateManyTaskNotificationsCommand createManyTaskNotificationsCommand) { _userService = userService; _getTaskDetailsForUserQuery = getTaskDetailsForUserQuery; _markTaskAsCompleteCommand = markTaskAsCompleteCommand; _getTasksForOrganizationQuery = getTasksForOrganizationQuery; _createManyTasksCommand = createManyTasksCommand; _createManyTaskNotificationsCommand = createManyTaskNotificationsCommand; } /// /// Retrieves security tasks for the current user. /// /// Optional filter for task status. If not provided returns tasks of all statuses. /// A list response model containing the security tasks for the user. [HttpGet("")] public async Task> Get([FromQuery] SecurityTaskStatus? status) { var userId = _userService.GetProperUserId(User).Value; var securityTasks = await _getTaskDetailsForUserQuery.GetTaskDetailsForUserAsync(userId, status); var response = securityTasks.Select(x => new SecurityTasksResponseModel(x)).ToList(); return new ListResponseModel(response); } /// /// Marks a task as complete. The user must have edit permission on the cipher associated with the task. /// /// The unique identifier of the task to complete [HttpPatch("{taskId:guid}/complete")] public async Task Complete(Guid taskId) { await _markTaskAsCompleteCommand.CompleteAsync(taskId); return NoContent(); } /// /// Retrieves security tasks for an organization. Restricted to organization administrators. /// /// The organization Id /// Optional filter for task status. If not provided, returns tasks of all statuses. [HttpGet("organization")] public async Task> ListForOrganization( [FromQuery] Guid organizationId, [FromQuery] SecurityTaskStatus? status) { var securityTasks = await _getTasksForOrganizationQuery.GetTasksAsync(organizationId, status); var response = securityTasks.Select(x => new SecurityTasksResponseModel(x)).ToList(); return new ListResponseModel(response); } /// /// Bulk create security tasks for an organization. /// /// /// /// A list response model containing the security tasks created for the organization. [HttpPost("{orgId:guid}/bulk-create")] public async Task> BulkCreateTasks(Guid orgId, [FromBody] BulkCreateSecurityTasksRequestModel model) { var securityTasks = await _createManyTasksCommand.CreateAsync(orgId, model.Tasks); await _createManyTaskNotificationsCommand.CreateAsync(orgId, securityTasks); var response = securityTasks.Select(x => new SecurityTasksResponseModel(x)).ToList(); return new ListResponseModel(response); } }