1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-22 12:15:36 +01:00

job to delete trashed ciphers nightly (#1243)

* job to delete trashed items nightly

* remove script from migration project file

* admin setting for controlling trash deleting dates
This commit is contained in:
Kyle Spearrin 2021-04-02 11:14:21 -04:00 committed by GitHub
parent 1b8b9b7539
commit 597fa01344
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 122 additions and 1 deletions

View File

@ -4,6 +4,7 @@
{
public virtual string Admins { get; set; }
public virtual CloudflareSettings Cloudflare { get; set; }
public int? DeleteTrashDaysAgo { get; set; }
public class CloudflareSettings
{

View File

@ -0,0 +1,40 @@
using System;
using System.Threading.Tasks;
using Bit.Core;
using Bit.Core.Jobs;
using Bit.Core.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Quartz;
namespace Bit.Admin.Jobs
{
public class DeleteCiphersJob : BaseJob
{
private readonly ICipherRepository _cipherRepository;
private readonly AdminSettings _adminSettings;
public DeleteCiphersJob(
ICipherRepository cipherRepository,
IOptions<AdminSettings> adminSettings,
ILogger<DeleteCiphersJob> logger)
: base(logger)
{
_cipherRepository = cipherRepository;
_adminSettings = adminSettings?.Value;
}
protected async override Task ExecuteJobAsync(IJobExecutionContext context)
{
_logger.LogInformation(Constants.BypassFiltersEventId, "Execute job task: DeleteDeletedAsync");
var deleteDate = DateTime.UtcNow.AddDays(-30);
var daysAgoSetting = (_adminSettings?.DeleteTrashDaysAgo).GetValueOrDefault();
if (daysAgoSetting > 0)
{
deleteDate = DateTime.UtcNow.AddDays(-1 * daysAgoSetting);
}
await _cipherRepository.DeleteDeletedAsync(deleteDate);
_logger.LogInformation(Constants.BypassFiltersEventId, "Finished job task: DeleteDeletedAsync");
}
}
}

View File

@ -55,13 +55,19 @@ namespace Bit.Admin.Jobs
.StartNow()
.WithCronSchedule("0 0 0 ? * SUN", x => x.InTimeZone(timeZone))
.Build();
var everyDayAtMidnightUtc = TriggerBuilder.Create()
.WithIdentity("EveryDayAtMidnightUtc")
.StartNow()
.WithCronSchedule("0 0 0 * * ?")
.Build();
var jobs = new List<Tuple<Type, ITrigger>>
{
new Tuple<Type, ITrigger>(typeof(DeleteSendsJob), everyFiveMinutesTrigger),
new Tuple<Type, ITrigger>(typeof(DatabaseExpiredGrantsJob), everyFridayAt10pmTrigger),
new Tuple<Type, ITrigger>(typeof(DatabaseUpdateStatisticsJob), everySaturdayAtMidnightTrigger),
new Tuple<Type, ITrigger>(typeof(DatabaseRebuildlIndexesJob), everySundayAtMidnightTrigger)
new Tuple<Type, ITrigger>(typeof(DatabaseRebuildlIndexesJob), everySundayAtMidnightTrigger),
new Tuple<Type, ITrigger>(typeof(DeleteCiphersJob), everyDayAtMidnightUtc)
};
if (!_globalSettings.SelfHosted)
@ -83,6 +89,7 @@ namespace Bit.Admin.Jobs
services.AddTransient<DatabaseRebuildlIndexesJob>();
services.AddTransient<DatabaseExpiredGrantsJob>();
services.AddTransient<DeleteSendsJob>();
services.AddTransient<DeleteCiphersJob>();
}
}
}

View File

@ -36,5 +36,6 @@ namespace Bit.Core.Repositories
Task SoftDeleteAsync(IEnumerable<Guid> ids, Guid userId);
Task SoftDeleteByIdsOrganizationIdAsync(IEnumerable<Guid> ids, Guid organizationId);
Task<DateTime> RestoreAsync(IEnumerable<Guid> ids, Guid userId);
Task DeleteDeletedAsync(DateTime deletedDateBefore);
}
}

View File

@ -624,6 +624,18 @@ namespace Bit.Core.Repositories.SqlServer
}
}
public async Task DeleteDeletedAsync(DateTime deletedDateBefore)
{
using (var connection = new SqlConnection(ConnectionString))
{
await connection.ExecuteAsync(
$"[{Schema}].[Cipher_DeleteDeleted]",
new { DeletedDateBefore = deletedDateBefore },
commandType: CommandType.StoredProcedure,
commandTimeout: 43200);
}
}
private DataTable BuildCiphersTable(SqlBulkCopy bulkCopy, IEnumerable<Cipher> ciphers)
{
var c = ciphers.FirstOrDefault();

View File

@ -0,0 +1,19 @@
CREATE PROCEDURE [dbo].[Cipher_DeleteDeleted]
@DeletedDateBefore DATETIME2 (7)
AS
BEGIN
SET NOCOUNT ON
DECLARE @BatchSize INT = 100
WHILE @BatchSize > 0
BEGIN
DELETE TOP(@BatchSize)
FROM
[dbo].[Cipher]
WHERE
[DeletedDate] < @DeletedDateBefore
SET @BatchSize = @@ROWCOUNT
END
END

View File

@ -26,3 +26,8 @@ GO
CREATE NONCLUSTERED INDEX [IX_Cipher_OrganizationId]
ON [dbo].[Cipher]([OrganizationId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_Cipher_DeletedDate]
ON [dbo].[Cipher]([DeletedDate] ASC);

View File

@ -0,0 +1,36 @@
IF OBJECT_ID('[dbo].[Cipher_DeleteDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[Cipher_DeleteDeleted]
END
GO
CREATE PROCEDURE [dbo].[Cipher_DeleteDeleted]
@DeletedDateBefore DATETIME2 (7)
AS
BEGIN
SET NOCOUNT ON
DECLARE @BatchSize INT = 100
WHILE @BatchSize > 0
BEGIN
DELETE TOP(@BatchSize)
FROM
[dbo].[Cipher]
WHERE
[DeletedDate] < @DeletedDateBefore
SET @BatchSize = @@ROWCOUNT
END
END
GO
IF NOT EXISTS (
SELECT * FROM sys.indexes WHERE [Name]='IX_Cipher_DeletedDate'
AND object_id = OBJECT_ID('[dbo].[Cipher]')
)
BEGIN
CREATE NONCLUSTERED INDEX [IX_Cipher_DeletedDate]
ON [dbo].[Cipher]([DeletedDate] ASC)
END
GO