using System.Net; using Bit.Api.Models.Public.Request; using Bit.Api.Models.Public.Response; using Bit.Api.Utilities.DiagnosticTools; using Bit.Core.Context; using Bit.Core.Models.Data; using Bit.Core.Repositories; using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; using Bit.Core.Vault.Repositories; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.Public.Controllers; [Route("public/events")] [Authorize("Organization")] public class EventsController : Controller { private readonly IEventRepository _eventRepository; private readonly ICipherRepository _cipherRepository; private readonly ICurrentContext _currentContext; private readonly ISecretRepository _secretRepository; private readonly IProjectRepository _projectRepository; private readonly IUserService _userService; private readonly ILogger _logger; private readonly IFeatureService _featureService; public EventsController( IEventRepository eventRepository, ICipherRepository cipherRepository, ICurrentContext currentContext, ISecretRepository secretRepository, IProjectRepository projectRepository, IUserService userService, ILogger logger, IFeatureService featureService) { _eventRepository = eventRepository; _cipherRepository = cipherRepository; _currentContext = currentContext; _secretRepository = secretRepository; _projectRepository = projectRepository; _userService = userService; _logger = logger; _featureService = featureService; } /// /// List all events. /// /// /// Returns a filtered list of your organization's event logs, paged by a continuation token. /// If no filters are provided, it will return the last 30 days of event for the organization. /// [HttpGet] [ProducesResponseType(typeof(PagedListResponseModel), (int)HttpStatusCode.OK)] public async Task List([FromQuery] EventFilterRequestModel request) { if (!_currentContext.OrganizationId.HasValue) { return new JsonResult(new PagedListResponseModel([], "")); } var organizationId = _currentContext.OrganizationId.Value; var dateRange = request.ToDateRange(); var result = new PagedResult(); if (request.ActingUserId.HasValue) { result = await _eventRepository.GetManyByOrganizationActingUserAsync( organizationId, request.ActingUserId.Value, dateRange.Item1, dateRange.Item2, new PageOptions { ContinuationToken = request.ContinuationToken }); } else if (request.ItemId.HasValue) { var cipher = await _cipherRepository.GetByIdAsync(request.ItemId.Value); if (cipher != null && cipher.OrganizationId == organizationId) { result = await _eventRepository.GetManyByCipherAsync( cipher, dateRange.Item1, dateRange.Item2, new PageOptions { ContinuationToken = request.ContinuationToken }); } } else if (request.SecretId.HasValue) { var secret = await _secretRepository.GetByIdAsync(request.SecretId.Value); if (secret == null) { secret = new Core.SecretsManager.Entities.Secret { Id = request.SecretId.Value, OrganizationId = organizationId }; } if (secret.OrganizationId == organizationId) { result = await _eventRepository.GetManyBySecretAsync( secret, dateRange.Item1, dateRange.Item2, new PageOptions { ContinuationToken = request.ContinuationToken }); } else { return new JsonResult(new PagedListResponseModel([], "")); } } else if (request.ProjectId.HasValue) { var project = await _projectRepository.GetByIdAsync(request.ProjectId.Value); if (project != null && project.OrganizationId == organizationId) { result = await _eventRepository.GetManyByProjectAsync( project, dateRange.Item1, dateRange.Item2, new PageOptions { ContinuationToken = request.ContinuationToken }); } else { return new JsonResult(new PagedListResponseModel([], "")); } } else { result = await _eventRepository.GetManyByOrganizationAsync( organizationId, dateRange.Item1, dateRange.Item2, new PageOptions { ContinuationToken = request.ContinuationToken }); } var eventResponses = result.Data.Select(e => new EventResponseModel(e)); var response = new PagedListResponseModel(eventResponses, result.ContinuationToken ?? ""); _logger.LogAggregateData(_featureService, organizationId, response, request); return new JsonResult(response); } }