1
0
mirror of https://github.com/bitwarden/server synced 2025-12-27 05:33:17 +00:00
Files
server/src/Api/AdminConsole/Public/Controllers/EventsController.cs
cd-bitwarden 1274fe6562 [SM-1575] Add ability to retrieve events based on projectId/SecretId (#6316)
* adding event filters

* allow user to see deleted secret event logs through public api

* nullable changes to event controller

* fixing tests

* fixing permissions issues with public API

* fix for bug

* Update src/Api/AdminConsole/Public/Controllers/EventsController.cs

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>

* Update src/Api/AdminConsole/Public/Controllers/EventsController.cs

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2025-11-14 18:21:48 -05:00

134 lines
5.2 KiB
C#

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<EventsController> _logger;
private readonly IFeatureService _featureService;
public EventsController(
IEventRepository eventRepository,
ICipherRepository cipherRepository,
ICurrentContext currentContext,
ISecretRepository secretRepository,
IProjectRepository projectRepository,
IUserService userService,
ILogger<EventsController> logger,
IFeatureService featureService)
{
_eventRepository = eventRepository;
_cipherRepository = cipherRepository;
_currentContext = currentContext;
_secretRepository = secretRepository;
_projectRepository = projectRepository;
_userService = userService;
_logger = logger;
_featureService = featureService;
}
/// <summary>
/// List all events.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[HttpGet]
[ProducesResponseType(typeof(PagedListResponseModel<EventResponseModel>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> List([FromQuery] EventFilterRequestModel request)
{
if (!_currentContext.OrganizationId.HasValue)
{
return new JsonResult(new PagedListResponseModel<EventResponseModel>([], ""));
}
var organizationId = _currentContext.OrganizationId.Value;
var dateRange = request.ToDateRange();
var result = new PagedResult<IEvent>();
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<EventResponseModel>([], ""));
}
}
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<EventResponseModel>([], ""));
}
}
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<EventResponseModel>(eventResponses, result.ContinuationToken ?? "");
_logger.LogAggregateData(_featureService, organizationId, response, request);
return new JsonResult(response);
}
}