Browse Source
* Add PasswordlessAuth Settings * Update Repository Method to Take TimeSpan * Update AuthRequest_DeleteIfExpired - Take Configurable Expiration - Add Special Cases for AdminApproval AuthRequests * Add AuthRequestRepositoryTests * Run Formatting * Remove Comment * Fix Bug in EF Repo * Add Test Covering Expired Rejected AuthRequest * Use Longer Param Names * Use Longer Names in Test Helperspull/2969/head
9 changed files with 172 additions and 11 deletions
@ -1,6 +1,19 @@
@@ -1,6 +1,19 @@
|
||||
CREATE PROCEDURE [dbo].[AuthRequest_DeleteIfExpired] |
||||
-- UserExpirationSeconds to 15 minutes (15 * 60) |
||||
-- AdminExpirationSeconds to 7 days (7 * 24 * 60 * 60) |
||||
-- AdminApprovalExpirationSeconds to 12 hour (12 * 60 * 60) |
||||
|
||||
CREATE PROCEDURE [dbo].[AuthRequest_DeleteIfExpired] |
||||
@UserExpirationSeconds INT = 900, |
||||
@AdminExpirationSeconds INT = 604800, |
||||
@AdminApprovalExpirationSeconds INT = 43200 |
||||
AS |
||||
BEGIN |
||||
SET NOCOUNT OFF |
||||
DELETE FROM [dbo].[AuthRequest] WHERE [CreationDate] < DATEADD(minute, -15, GETUTCDATE()); |
||||
DELETE FROM [dbo].[AuthRequest] |
||||
-- User requests expire after 15 minutes (by default) of their creation |
||||
WHERE ([Type] != 2 AND DATEADD(second, @UserExpirationSeconds, [CreationDate]) < GETUTCDATE()) |
||||
-- Admin requests expire after 7 days (by default) of their creation if they have not been approved |
||||
OR ([Type] = 2 AND ([Approved] IS NULL OR [Approved] = 0) AND DATEADD(second, @AdminExpirationSeconds,[CreationDate]) < GETUTCDATE()) |
||||
-- Admin requests expire after 12 hours (by default) of their approval |
||||
OR ([Type] = 2 AND [Approved] = 1 AND DATEADD(second, @AdminApprovalExpirationSeconds, [ResponseDate]) < GETUTCDATE()); |
||||
END |
||||
|
||||
@ -0,0 +1,99 @@
@@ -0,0 +1,99 @@
|
||||
using Bit.Core.Auth.Entities; |
||||
using Bit.Core.Auth.Enums; |
||||
using Bit.Core.Entities; |
||||
using Bit.Core.Repositories; |
||||
using Xunit; |
||||
|
||||
namespace Bit.Infrastructure.IntegrationTest.Auth.Repositories; |
||||
|
||||
public class AuthRequestRepositoryTests |
||||
{ |
||||
private readonly static TimeSpan _userRequestExpiration = TimeSpan.FromMinutes(15); |
||||
private readonly static TimeSpan _adminRequestExpiration = TimeSpan.FromDays(6); |
||||
private readonly static TimeSpan _afterAdminApprovalExpiration = TimeSpan.FromHours(12); |
||||
|
||||
[DatabaseTheory, DatabaseData] |
||||
public async Task DeleteExpiredAsync_Works( |
||||
IAuthRequestRepository authRequestRepository, |
||||
IUserRepository userRepository, |
||||
ITestDatabaseHelper helper) |
||||
{ |
||||
var user = await userRepository.CreateAsync(new User |
||||
{ |
||||
Name = "Test User", |
||||
Email = $"test+{Guid.NewGuid()}@email.com", |
||||
ApiKey = "TEST", |
||||
SecurityStamp = "stamp", |
||||
}); |
||||
|
||||
// A user auth request type that has passed it's expiration time, should be deleted. |
||||
var userExpiredAuthRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.AuthenticateAndUnlock, CreateExpiredDate(_userRequestExpiration))); |
||||
|
||||
// An AdminApproval request that hasn't had any action taken on it and has passed it's expiration time, should be deleted. |
||||
var adminApprovalExpiredAuthRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.AdminApproval, CreateExpiredDate(_adminRequestExpiration))); |
||||
|
||||
// An AdminApproval request that was approved before it expired but the user has been approved for too long, should be deleted. |
||||
var adminApprovedExpiredAuthRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.AdminApproval, DateTime.UtcNow.AddDays(-6), true, CreateExpiredDate(_afterAdminApprovalExpiration))); |
||||
|
||||
// An AdminApproval request that was rejected within it's allowed lifetime but has no gone past it's expiration time, should be deleted. |
||||
var adminRejectedExpiredAuthRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.AdminApproval, CreateExpiredDate(_adminRequestExpiration), false, DateTime.UtcNow.AddHours(-1))); |
||||
|
||||
// A User AuthRequest that was created just a minute ago. |
||||
var notExpiredUserAuthRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.Unlock, DateTime.UtcNow.AddMinutes(-1))); |
||||
|
||||
// An AdminApproval AuthRequest that was create 6 days 23 hours 59 minutes 59 seconds ago which is right on the edge of still being valid |
||||
var notExpiredAdminApprovalRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.AdminApproval, DateTime.UtcNow.Add(new TimeSpan(days: 6, hours: 23, minutes: 59, seconds: 59)))); |
||||
|
||||
// An AdminApproval AuthRequest that was created a week ago but just approved 11 hours ago. |
||||
var notExpiredApprovedAdminApprovalRequest = await authRequestRepository.CreateAsync( |
||||
CreateAuthRequest(user.Id, AuthRequestType.AdminApproval, DateTime.UtcNow.AddDays(7), true, DateTime.UtcNow.AddHours(11))); |
||||
|
||||
helper.ClearTracker(); |
||||
|
||||
var numberOfDeleted = await authRequestRepository.DeleteExpiredAsync(_userRequestExpiration, _adminRequestExpiration, _afterAdminApprovalExpiration); |
||||
|
||||
// Ensure all the AuthRequests that should have been deleted, have been deleted. |
||||
Assert.Null(await authRequestRepository.GetByIdAsync(userExpiredAuthRequest.Id)); |
||||
Assert.Null(await authRequestRepository.GetByIdAsync(adminApprovalExpiredAuthRequest.Id)); |
||||
Assert.Null(await authRequestRepository.GetByIdAsync(adminApprovedExpiredAuthRequest.Id)); |
||||
Assert.Null(await authRequestRepository.GetByIdAsync(adminRejectedExpiredAuthRequest.Id)); |
||||
|
||||
// Ensure that all the AuthRequests that should have been left alone, were. |
||||
Assert.NotNull(await authRequestRepository.GetByIdAsync(notExpiredUserAuthRequest.Id)); |
||||
Assert.NotNull(await authRequestRepository.GetByIdAsync(notExpiredAdminApprovalRequest.Id)); |
||||
Assert.NotNull(await authRequestRepository.GetByIdAsync(notExpiredApprovedAdminApprovalRequest.Id)); |
||||
|
||||
// Ensure the repository responds with the amount of items it deleted and it deleted the right amount. |
||||
// NOTE: On local development this might fail on it's first run because the developer could have expired AuthRequests |
||||
// on their machine but aren't running the job that would delete them. The second run of this test should succeed. |
||||
Assert.Equal(4, numberOfDeleted); |
||||
} |
||||
|
||||
private static AuthRequest CreateAuthRequest(Guid userId, AuthRequestType authRequestType, DateTime creationDate, bool? approved = null, DateTime? responseDate = null) |
||||
{ |
||||
return new AuthRequest |
||||
{ |
||||
UserId = userId, |
||||
Type = authRequestType, |
||||
Approved = approved, |
||||
RequestDeviceIdentifier = "something", // TODO: EF Doesn't enforce this as not null |
||||
RequestIpAddress = "1.1.1.1", // TODO: EF Doesn't enforce this as not null |
||||
AccessCode = "test_access_code", // TODO: EF Doesn't enforce this as not null |
||||
PublicKey = "test_public_key", // TODO: EF Doesn't enforce this as not null |
||||
CreationDate = creationDate, |
||||
ResponseDate = responseDate, |
||||
}; |
||||
} |
||||
|
||||
private static DateTime CreateExpiredDate(TimeSpan expirationPeriod) |
||||
{ |
||||
var exp = expirationPeriod + TimeSpan.FromMinutes(1); |
||||
return DateTime.UtcNow.Add(exp.Negate()); |
||||
} |
||||
} |
||||
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
IF OBJECT_ID('[dbo].[AuthRequest_DeleteIfExpired]') IS NOT NULL |
||||
BEGIN |
||||
DROP PROCEDURE [dbo].[AuthRequest_DeleteIfExpired] |
||||
END |
||||
GO |
||||
|
||||
-- UserExpirationSeconds to 15 minutes (15 * 60) |
||||
-- AdminExpirationSeconds to 7 days (7 * 24 * 60 * 60) |
||||
-- AdminApprovalExpirationSeconds to 12 hour (12 * 60 * 60) |
||||
|
||||
CREATE PROCEDURE [dbo].[AuthRequest_DeleteIfExpired] |
||||
@UserExpirationSeconds INT = 900, |
||||
@AdminExpirationSeconds INT = 604800, |
||||
@AdminApprovalExpirationSeconds INT = 43200 |
||||
AS |
||||
BEGIN |
||||
SET NOCOUNT OFF |
||||
DELETE FROM [dbo].[AuthRequest] |
||||
-- User requests expire after 15 minutes (by default) of their creation |
||||
WHERE ([Type] != 2 AND DATEADD(second, @UserExpirationSeconds, [CreationDate]) < GETUTCDATE()) |
||||
-- Admin requests expire after 7 days (by default) of their creation if they have not been approved |
||||
OR ([Type] = 2 AND ([Approved] IS NULL OR [Approved] = 0) AND DATEADD(second, @AdminExpirationSeconds,[CreationDate]) < GETUTCDATE()) |
||||
-- Admin requests expire after 12 hours (by default) of their approval |
||||
OR ([Type] = 2 AND [Approved] = 1 AND DATEADD(second, @AdminApprovalExpirationSeconds, [ResponseDate]) < GETUTCDATE()); |
||||
END |
||||
Loading…
Reference in new issue