-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow for bulk processing new login device requests #4064
Allow for bulk processing new login device requests #4064
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4064 +/- ##
==========================================
+ Coverage 39.09% 39.31% +0.22%
==========================================
Files 1202 1210 +8
Lines 58110 58335 +225
Branches 5349 5369 +20
==========================================
+ Hits 22717 22934 +217
+ Misses 34323 34321 -2
- Partials 1070 1080 +10 ☔ View full report in Codecov by Sentry. |
640de72
to
a1777e5
Compare
bc7770c
to
e9cb44f
Compare
fc353d3
to
a42b1da
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bunch of smaller stuff, overall looking good!
src/Core/AdminConsole/OrganizationAuth/Models/ApprovedAuthRequestIsMissingKeyException.cs
Outdated
Show resolved
Hide resolved
src/Core/AdminConsole/OrganizationAuth/UpdateOrganizationAuthRequestCommand.cs
Outdated
Show resolved
Hide resolved
src/Core/AdminConsole/OrganizationAuth/UpdateOrganizationAuthRequestCommand.cs
Show resolved
Hide resolved
src/Core/AdminConsole/OrganizationAuth/UpdateOrganizationAuthRequestCommand.cs
Outdated
Show resolved
Hide resolved
await _eventService.LogOrganizationUserEventsAsync( | ||
organizationUsers.Select(ou => | ||
{ | ||
var e = events.FirstOrDefault(e => e.AuthRequest.OrganizationId == ou.Id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a typo:
var e = events.FirstOrDefault(e => e.AuthRequest.OrganizationId == ou.Id); | |
var e = events.FirstOrDefault(e => e.AuthRequest.OrganizationUserId == ou.Id); |
Is there any way tests could've picked this up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This got caught by being more terse on 51a837a
Resolved!
src/Core/AdminConsole/OrganizationAuth/Models/AuthRequestUpdateProcessor.cs
Outdated
Show resolved
Hide resolved
src/Core/AdminConsole/OrganizationAuth/Models/AuthRequestUpdateProcessor.cs
Outdated
Show resolved
Hide resolved
test/Core.Test/AdminConsole/OrganizationAuth/Models/AuthRequestUpdateProcessorTests.cs
Outdated
Show resolved
Hide resolved
test/Core.Test/AdminConsole/OrganizationAuth/UpdateOrganizationAuthRequestCommandTests.cs
Show resolved
Hide resolved
// Assert that because we passed in good data we call a save | ||
// operation and raise all events | ||
await sutProvider.GetDependency<IAuthRequestRepository>().ReceivedWithAnyArgs().UpdateManyAsync(Arg.Any<IEnumerable<OrganizationAdminAuthRequest>>()); | ||
await sutProvider.GetDependency<IPushNotificationService>().DidNotReceiveWithAnyArgs().PushAuthRequestResponseAsync(Arg.Any<AuthRequest>()); | ||
await sutProvider.GetDependency<IMailService>().DidNotReceiveWithAnyArgs().SendTrustedDeviceAdminApprovalEmailAsync( | ||
Arg.Any<string>(), | ||
Arg.Any<DateTime>(), | ||
Arg.Any<string>(), | ||
Arg.Any<string>() | ||
); | ||
await sutProvider.GetDependency<IEventService>().ReceivedWithAnyArgs().LogOrganizationUserEventsAsync( | ||
Arg.Any<IEnumerable<(OrganizationUser, EventType, DateTime?)>>() | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use Arg.Is
to assert some basic values here - I think that asserting calls with Arg.Any
is not very precise. And while the processor tests test that the callbacks are called, you want to make sure that the callback has passed on the arguments to the dependency correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't really know how to do this, but appreciate the push to do it because it was fun. The test is more precise as of 51a837a.
I left the denied specific test alone, since it's really just a big test to make sure notifications don't ever get sent.
9059960
to
aa56cac
Compare
aa56cac
to
456fdb3
Compare
996bbd1
to
44af01f
Compare
2b31eb4
to
7f17510
Compare
7f17510
to
cdb5a32
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed changes to date and resolved most feedback. I can see you're still working on a couple of items.
var isExpired = DateTime.UtcNow > | ||
_unprocessedAuthRequest.CreationDate | ||
.Add(_configuration.AuthRequestExpiresAfter); | ||
var isSpent = _unprocessedAuthRequest == null || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This null check is now unnecessary because it's already checked above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented as suggested on 23b60d4
* Define a model for updating many auth requests In order to facilitate a command method that can update many auth requests at one time a new model must be defined that accepts valid input for the command's needs. To achieve this a new file has been created at `Core/AdminConsole/OrganizationAuth/Models/OrganizationAuthRequestUpdateCommandModel.cs` that contains a class of the same name. It's properties match those that need to come from any calling API request models to fulfill the request. * Declare a new command interface method Calling API functions of the `UpdateOrganizationAuthRequestCommand` need a function that can accept many auth request response objects and process them as approved or denied. To achieve this a new function has been added to `IUpdateOrganizationAuthRequestCommand` called `UpdateManyAsync()` that accepts an `IEnumberable<OrganizationAuthRequest>` and returns a `Task`. Implementations of this interface method will be used to bulk process auth requests as approved or denied. * Stub out method implementation for unit testing To facilitate a bulk device login request approval workflow in the admin console `UpdateOrganizationAuthRequestCommand` needs to be updated to include an `UpdateMany()` method. It should accept a list of `OrganizationAuthRequestUpdateCommandModel` objects, perform some simple data validation checks, and then pass those along to `AuthRequestRepository` for updating in the database. This commit stubs out this method for the purpose of writing unit tests. At this stage the method throws a `NotImplementedException()`. It will be expand after writing assertions. * Inject `IAuthRequestRepository` into `UpdateOrganizationAuthCommand` The updates to `UpdateOrganizationAuthRequestCommand` require a new direct dependency on `IAuthRequestRepository`. This commit simply registers this dependency in the `UpdateOrganizationAuthRequest` constructor for use in unit tests and the `UpdateManyAsync()` implementation. * Write tests * Rename `UpdateManyAsync()` to `UpdateAsync` * Drop the `CommandModel` suffix * Invert business logic update filters * Rework everything to be more model-centric * Bulk send push notifications * Write tests that validate the command as a whole * Fix a test that I broke by mistake * Swap to using await instead of chained methods for processing * Seperate a function arguement into a variable declaration * Ungeneric-ify the processor * Adjust ternary formatting * Adjust naming of methods regarding logging organization events * Throw an exception if Process is called with no auth request loaded * Rename `_updates` -> `_update` * Rename email methods * Stop returning `this` * Allow callbacks to be null * Make some assertions about the state of a processed auth request * Be more terse about arguements in happy path test * Remove unneeded null check * Expose an endpoint for bulk processing of organization auth requests (#4077) --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
Type of change
Objective
To facilitate a new bulk device login request in the admin console server
logic needs to be written that can bulk approve and deny new device login
requests safely. This logic will need to accept a list of ids, keys, and
approval states and process those requests to apply the keys and approval
states.
Code changes
See the commits tab
References
database functionality needed to bulk update
AuthRequest
table records.UpdateManyAsync
command written here.