1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-01 13:43:23 +01:00

PM-10563: continuation token hack

This commit is contained in:
Maciej Zieniuk 2024-10-03 19:45:05 +01:00
parent ef32d33489
commit 8bd88a52ad
No known key found for this signature in database
GPG Key ID: 9CACE59F1272ACD9
3 changed files with 62 additions and 18 deletions

View File

@ -1,10 +1,13 @@
#nullable enable
using System.Text.Json;
using Bit.Api.Models.Response;
using Bit.Api.NotificationCenter.Models;
using Bit.Api.NotificationCenter.Models.Request;
using Bit.Api.NotificationCenter.Models.Response;
using Bit.Core.NotificationCenter.Commands.Interfaces;
using Bit.Core.NotificationCenter.Models.Filter;
using Bit.Core.NotificationCenter.Queries.Interfaces;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@ -32,6 +35,7 @@ public class NotificationsController : Controller
public async Task<ListResponseModel<NotificationResponseModel>> List(
[FromQuery] NotificationFilterRequestModel filter)
{
var continuationToken = ParseContinuationToken(filter.ContinuationToken);
var notificationStatusFilter = new NotificationStatusFilter
{
Read = filter.ReadStatusFilter,
@ -40,12 +44,27 @@ public class NotificationsController : Controller
var notifications = await _getNotificationsForUserQuery.GetByUserIdStatusFilterAsync(notificationStatusFilter);
var filteredNotifications = notifications
.Where(n => n.RevisionDate >= filter.Start && n.RevisionDate < filter.End)
.Take(filter.PageSize);
if (continuationToken != null)
{
notifications = notifications
.Where(n => n.Priority <= continuationToken.Priority && n.RevisionDate < continuationToken.Date);
}
var responses = filteredNotifications.Select(n => new NotificationResponseModel(n));
return new ListResponseModel<NotificationResponseModel>(responses);
var responses = notifications
.Take(10)
.Select(n => new NotificationResponseModel(n))
.ToList();
var nextContinuationToken = responses.Count > 0 && responses.Count < 10
? new NotificationContinuationToken
{
Priority = responses.Last().Priority,
Date = responses.Last().Date
}
: null;
return new ListResponseModel<NotificationResponseModel>(responses,
CreateContinuationToken(nextContinuationToken));
}
[HttpPatch("{id}/delete")]
@ -59,4 +78,27 @@ public class NotificationsController : Controller
{
await _markNotificationReadCommand.MarkReadAsync(id);
}
private NotificationContinuationToken? ParseContinuationToken(string? continuationToken)
{
if (continuationToken == null)
{
return null;
}
var decodedContinuationToken = CoreHelpers.Base64UrlDecodeString(continuationToken);
return JsonSerializer.Deserialize<NotificationContinuationToken>(decodedContinuationToken,
JsonHelpers.IgnoreCase);
}
private string? CreateContinuationToken(NotificationContinuationToken? notificationContinuationToken)
{
if (notificationContinuationToken == null)
{
return null;
}
var serializedContinuationToken = JsonSerializer.Serialize(notificationContinuationToken);
return CoreHelpers.Base64UrlEncodeString(serializedContinuationToken);
}
}

View File

@ -0,0 +1,11 @@
#nullable enable
using Bit.Core.NotificationCenter.Enums;
namespace Bit.Api.NotificationCenter.Models;
public class NotificationContinuationToken
{
public Priority Priority { get; set; }
public DateTime Date { get; set; }
}

View File

@ -1,4 +1,5 @@
namespace Bit.Api.NotificationCenter.Models.Request;
#nullable enable
namespace Bit.Api.NotificationCenter.Models.Request;
public class NotificationFilterRequestModel
{
@ -13,17 +14,7 @@ public class NotificationFilterRequestModel
public bool? DeletedStatusFilter { get; set; }
/// <summary>
/// The start date. Must be less than the end date. Inclusive.
/// A cursor for use in pagination.
/// </summary>
public DateTime Start { get; set; } = DateTime.MinValue;
/// <summary>
/// The end date. Must be greater than the start date. Not inclusive.
/// </summary>
public DateTime End { get; set; } = DateTime.MaxValue;
/// <summary>
/// Number of items to return. Defaults to 10.
/// </summary>
public int PageSize { get; set; } = 10;
public string? ContinuationToken { get; set; }
}