-
Notifications
You must be signed in to change notification settings - Fork 643
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
[Organizations]: UI for creating migration request #5241
Conversation
fe400b7
to
0e0ad2d
Compare
Was using the word "Transform" discussed? I have a feeling "Convert" would be more appropriate here. As in "Convert to organization account". |
[Authorize] | ||
public virtual ActionResult Transform() | ||
{ | ||
var accountToTransform = GetCurrentUser(); |
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.
null check for accountToTransform?
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.
The Authorize attribute should ensure that there is an authenticated user.
|
||
public async Task RequestTransformToOrganizationAccount(User accountToTransform, User adminUser) | ||
{ | ||
accountToTransform = accountToTransform ?? throw new ArgumentNullException(nameof(accountToTransform)); |
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.
Will the proposed admin requested to accept the request of becoming an admin?
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.
see PR #5228 for the confirmation
The proposed/pending organization admin must log in and confirm using the generated confirmationToken.
|
||
public async Task RequestTransformToOrganizationAccount(User accountToTransform, User adminUser) | ||
{ | ||
accountToTransform = accountToTransform ?? throw new ArgumentNullException(nameof(accountToTransform)); |
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.
Do we handle the cases when the accountToTransform is already an organization ?
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.
Yes, it's handled in UserService.CanTransformToOrganization
accountToTransform.OrganizationMigrationRequest.ConfirmationToken = Crypto.GenerateToken(); | ||
accountToTransform.OrganizationMigrationRequest.RequestDate = DateTime.UtcNow; | ||
|
||
await UserRepository.CommitChangesAsync(); |
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.
Does it make sense as the requests to have a Status? Will they be ever completed?
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.
No, the confirmation logic is very similar to email confirmation. The user must be authenticated and verify against the token we generate. Nothing fancy is needed for status.
We considered whether to expire the confirmation after 24hr, but chose to do the same as email confirmation which doesn't expire. We do store RequestDate in case we want to change this.
accountToTransform.OrganizationMigrationRequest.ConfirmationToken = Crypto.GenerateToken(); | ||
accountToTransform.OrganizationMigrationRequest.RequestDate = DateTime.UtcNow; | ||
|
||
await UserRepository.CommitChangesAsync(); |
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.
Do we want to add auditing for this scenario?
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.
Yes, there's a separate work item to track auditing which will be done at lower priority.
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.
LGTM - few comments.
src/NuGetGallery/Strings.resx
Outdated
<value>Administrator account '{0}' does not exist.</value> | ||
</data> | ||
<data name="TransformAccount_AdminAccountNotConfirmed" xml:space="preserve"> | ||
<value>Administrator account '{0}' has not validated their email address.</value> |
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.
we should use "confirmed" instead of "validated" for this message because that's how it appears elsewhere on the site
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.
For some reason I chose 'validated' instead of 'confirmed' because I thought it was consistent with other strings. Will try to be consistent and run any messages by @anangaur.
<div> | ||
<aside class="col-md-3 col-md-push-9"> | ||
@Html.Label("Logo") | ||
@ViewHelpers.GravatarImage(CurrentUser.EmailAddress, CurrentUser.Username, 332, responsive: true) |
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 couple thoughts--
1 - I noticed 332
was what we also used on the profile page. Can we put this in a constant of some sort?
2 - Make sure you check how this looks on smaller screens.
|
||
<div class="row form-group col-md-9 col-md-pull-3"> | ||
@Html.Label("Organization") | ||
@Html.ShowTextBoxFor(m => CurrentUser.Username, enabled: false) |
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.
} | ||
|
||
[Fact] | ||
public async Task Post_CanTransformReturnsFalse_ShowsError() |
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 recommend splitting the Get
and Post
into separate classes and creating a base for the shared logic.
E.g.
public class TheTransformActions : TestContainer
{
protected UsersController CreateController(string accountToTransform, string canTransformErrorReason = "")
{
...
}
}
public class TheGetTransformAction : TheTransformActions
{
...
}
public class ThePostTransformAction : TheTransformActions
{
...
}
for (int i = 0; i < (testOverwrite ? 2 : 1); i++) | ||
{ | ||
// Act | ||
await service.RequestTransformToOrganizationAccount(account, admin); |
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.
it may make this test stronger if, for the rewrite test, a different admin user was used
for example, if there was a bug that didn't set the admin of the request to the new admin but still succeeded the request, this test would return a false negative
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.
done
|
||
[HttpGet] | ||
[Authorize] | ||
public virtual ActionResult Transform() |
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.
One additional thing I noticed--I think something like TransformAccountToOrganization
would be more descriptive and potentially a better name for this action.
@scottbommarito new screenshot below - |
@chenriksson Looks much better! Great work! |
Screenshot, when request already created (will overwrite):
Screenshot, when admin is not found: