Skip to content

Commit

Permalink
Add ability to fetch events by service account
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas-Avery committed Oct 9, 2023
1 parent 3a71e7b commit ba36b29
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Bit.Api.Models.Response;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data;
using Bit.Core.Repositories;
using Bit.Core.SecretsManager.AuthorizationRequirements;
using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Bit.Api.SecretsManager.Controllers;

[Authorize("secrets")]
[SelfHosted(NotSelfHostedOnly = true)]
public class SecretsManagerEventsController : Controller
{
private readonly IAuthorizationService _authorizationService;
private readonly IEventRepository _eventRepository;
private readonly IServiceAccountRepository _serviceAccountRepository;

public SecretsManagerEventsController(
IEventRepository eventRepository,
IServiceAccountRepository serviceAccountRepository,
IAuthorizationService authorizationService)
{
_authorizationService = authorizationService;
_serviceAccountRepository = serviceAccountRepository;
_eventRepository = eventRepository;
}

[HttpGet("sm/events/service-accounts/{serviceAccountId}")]
public async Task<ListResponseModel<EventResponseModel>> GetServiceAccountEventsAsync(Guid serviceAccountId,
[FromQuery] DateTime? start = null, [FromQuery] DateTime? end = null,
[FromQuery] string continuationToken = null)
{
var serviceAccount = await _serviceAccountRepository.GetByIdAsync(serviceAccountId);
var authorizationResult =
await _authorizationService.AuthorizeAsync(User, serviceAccount, ServiceAccountOperations.Update);

if (!authorizationResult.Succeeded)
{
throw new NotFoundException();
}

var dateRange = GetDateRange(start, end);

var result = await _eventRepository.GetManyByServiceAccountAsync(serviceAccount.OrganizationId,
serviceAccount.Id, dateRange.Item1, dateRange.Item2,
new PageOptions { ContinuationToken = continuationToken });
var responses = result.Data.Select(e => new EventResponseModel(e));
return new ListResponseModel<EventResponseModel>(responses, result.ContinuationToken);
}

private Tuple<DateTime, DateTime> GetDateRange(DateTime? start, DateTime? end)
{
if (!end.HasValue || !start.HasValue)
{
end = DateTime.UtcNow.Date.AddDays(1).AddMilliseconds(-1);
start = DateTime.UtcNow.Date.AddDays(-30);
}
else if (start.Value > end.Value)
{
var newEnd = start;
start = end;
end = newEnd;
}

if (end.Value - start.Value > TimeSpan.FromDays(367))
{
throw new BadRequestException("Range too large.");
}

return new Tuple<DateTime, DateTime>(start.Value, end.Value);
}
}
2 changes: 2 additions & 0 deletions src/Core/Repositories/IEventRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ Task<PagedResult<IEvent>> GetManyByCipherAsync(Cipher cipher, DateTime startDate
PageOptions pageOptions);
Task CreateAsync(IEvent e);
Task CreateManyAsync(IEnumerable<IEvent> e);
Task<PagedResult<IEvent>> GetManyByServiceAccountAsync(Guid organizationId, Guid serviceAccountId,
DateTime startDate, DateTime endDate, PageOptions pageOptions);
}
8 changes: 8 additions & 0 deletions src/Core/Repositories/TableStorage/EventRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ public async Task<PagedResult<IEvent>> GetManyByCipherAsync(Cipher cipher, DateT
return await GetManyAsync(partitionKey, $"CipherId={cipher.Id}__Date={{0}}", startDate, endDate, pageOptions);
}

public async Task<PagedResult<IEvent>> GetManyByServiceAccountAsync(Guid organizationId,
Guid serviceAccountId, DateTime startDate, DateTime endDate, PageOptions pageOptions)
{

return await GetManyAsync($"OrganizationId={organizationId}",
$"ServiceAccountId={serviceAccountId}__Date={{0}}", startDate, endDate, pageOptions);
}

public async Task CreateAsync(IEvent e)
{
if (!(e is EventTableEntity entity))
Expand Down
5 changes: 5 additions & 0 deletions src/Infrastructure.Dapper/Repositories/EventRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ public async Task CreateManyAsync(IEnumerable<IEvent> entities)
}
}

//TODO
public Task<PagedResult<IEvent>> GetManyByServiceAccountAsync(Guid organizationId, Guid serviceAccountId, DateTime startDate, DateTime endDate,
PageOptions pageOptions) =>
throw new NotImplementedException();

private async Task<PagedResult<IEvent>> GetManyAsync(string sprocName,
IDictionary<string, object> sprocParams, DateTime startDate, DateTime endDate, PageOptions pageOptions)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public async Task CreateManyAsync(IEnumerable<IEvent> entities)
}
}

// TODO
public Task<PagedResult<IEvent>> GetManyByServiceAccountAsync(Guid organizationId, Guid serviceAccountId, DateTime startDate, DateTime endDate,
PageOptions pageOptions) =>
throw new NotImplementedException();

public async Task<PagedResult<IEvent>> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate, PageOptions pageOptions)
{
DateTime? beforeDate = null;
Expand Down

0 comments on commit ba36b29

Please sign in to comment.