-
-
Notifications
You must be signed in to change notification settings - Fork 531
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
4503 super admin create users #5097
base: main
Are you sure you want to change the base?
4503 super admin create users #5097
Conversation
…esources should be available seems like it would come down to the user's permissions, which a controller should handle
…le type is selected
…der of role-resource and double-select controller action doesn't impact behavior
…s super admin, added comments explaining constraints
…sers in addition to org users
… user if only ORG_ADMIN role is specified
…checking for error messages on missing role type or resoruce id
…verify organizations are preloaded for the new user page as this is no longer the case
…sers, automatically add the ORG_USER role, and raise an error when no resource is provided
…e hidden if super admin role is selected
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.
Thanks Benjamin...
Please address this failing sequence.....
Sign in as superadmin
Add a superuser (entirely new user -- I used myself)
accept the invitation (you'll want to sign out first -- I use a different browser as my default so I didn't have to)
As that new user
Users|All Users
find the [email protected] user
Edit
BOOM!
Edit -- you don't have to go into the new user -- you can just try editing any superuser, including the one you just added.
Apologies for missing this. The error you're describing I also encountered while working on PR #5047 and since that PR fixed the bug and I didn't replicate the fix for this one. #5047 is merged into main now so it should be working. There was also a test failing due to a small mistake I made in #5047 though that is fixed now as well. I suspect the remaining failing test, |
@Benjamin-Couey Whoops, didn't realize you had already fixed that test. Let me know if I should close my PR |
Sorry, I'm going back and forth on this. I still think the fix is tangential to the issue in this PR but maybe that's fine? It makes it easier for reviewers to test the behavior? That's probably the reason to keep the commit and delete the PR. |
raise "Please select an organization for the user." if organization_id.blank? | ||
|
||
organization_id | ||
raise "Please select an associated resource for the role." if params[:resource_type].to_s != Role::SUPER_ADMIN.to_s && params[:resource_id].blank? |
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.
Rather than hardcoding SUPER_ADMIN, can we have a set of non-resource roles in the Role
class which right now would only have SUPER_ADMIN
as a member of the set? If we ever add roles to this set (which we have discussed in the past) it would mean not having to change this.
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.
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.
Stimulus controllers should be defined generically whenever possible. Here this has nothing to do with roles and more to do with toggling classes on the destination target. You should be able to pass in the set of "toggle values" to the controller.
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.
|
||
def load_resources | ||
@resources = Role::TITLES.invert | ||
end |
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.
Can you not just reference this in the view? Seems odd to have a separate callback to "load" these in the controller - this is not hitting the database.
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 recent commit makes this change.
app/services/user_invite_service.rb
Outdated
# multiple roles being based makes sense is ORG_USER and ORG_ADMIN. | ||
|
||
# Resource can be nil when the only role being added is the SUPER_ADMIN role. | ||
# binding.pry |
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.
Remove comment please
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 is addressed in the recent commit.
app/services/user_invite_service.rb
Outdated
|
||
# Resource can be nil when the only role being added is the SUPER_ADMIN role. | ||
# binding.pry | ||
raise "Resource not found!" if resource.nil? && roles.first.to_s != Role::SUPER_ADMIN.to_s |
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 above - we should use the same list of "no-resource roles".
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 recent commit makes this change.
app/services/user_invite_service.rb
Outdated
# The logic is placed here instead of relying on the AddRoleService, as that | ||
# currently only accepts users by id, and new user will not have an id | ||
# until after they are invited. | ||
if roles.all? { |role| role.to_s == Role::ORG_ADMIN.to_s } |
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 seems odd because it implies that we can give users multiple org admin roles, which we shouldn't be able to do in a single call.
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 had done this because I needed to cast all the roles
to string for the comparison (there are examples of roles
being passed as string and symbol) but I agree it creates a strange implication.
This recent commit address this.
…serInviteService to use this definition
…ews can just reference Role::TITLES directly
…l against and passed new Role::ROLES_WITHOUT_RESOURCE
…r role should be added for each org_admin role
…s error if any of the submitted roles require a resource and one isn't provided, added associated test to verify
…OLES_WITHOUT_RESOURCE
@dorner Apologies for the wait, but I believe my recent commits address your comments. |
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.
Getting closer!
export default class extends Controller { | ||
static targets = ["source", "destination"] | ||
static values = { | ||
valuestohide: Array |
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 is JavaScript, so this should be camelCase: valuesToHide
. You would call it as values-to-hide
in the HTML.
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.
Should be addressed in the recent commit.
import { Controller } from "@hotwired/stimulus" | ||
|
||
export default class extends Controller { | ||
static targets = ["source", "destination"] |
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 spacing in this file seems very out of whack.
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.
Should be addressed in the recent commit.
sourceChanged() { | ||
const val = $(this.sourceTarget).val() | ||
this.destinationTargets.forEach( | ||
destination_target => { $(destination_target).toggleClass("d-none", this.valuestohideValue.includes(val)); } |
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.
destination_target => { $(destination_target).toggleClass("d-none", this.valuestohideValue.includes(val)); } | |
destinationTarget => { $(destinationTarget).toggleClass("d-none", this.valuesToHideValue.includes(val)); } |
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.
Should be addressed in the recent commit.
app/services/user_invite_service.rb
Outdated
# The logic is placed here instead of relying on the AddRoleService, as that | ||
# currently only accepts users by id, and new user will not have an id | ||
# until after they are invited. | ||
if roles.map(&:to_s).include?(Role::ORG_ADMIN.to_s) |
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.
Why do we need to cast both the role and the comparison to string, if they're both symbols?
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.
Thanks for pushing back on this. I had got it in my head that UserInviteService.invite
was called with role as both a symbol and string. Looking more closely, it was only my modifications to Admin::UsersController
that were submitting a string.
Should be addressed in the recent commit.
app/views/admin/users/new.html.erb
Outdated
<%= render 'admin/users/user_form_fields', f: f %> | ||
|
||
<div data-controller="double-select" data-double-select-url-value="<%= resource_ids_admin_users_url %>"> | ||
|
||
<div data-controller="hide-by-source-val" data-hide-by-source-val-valuestohide-value="<%= Role::ROLES_WITHOUT_RESOURCE.to_json %>"> |
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.
You don't need a second div, you can add all the values to the same div:
<div data-controller="double-select hide-by-source-val"
data-double-select-url-value="<%= resource_ids_admin_users_url %>"
data-hide-by-source-val-values-to-hide-value="<%= Role::ROLES_WITHOUT_RESOURCE.to_json %>">
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.
Should be addressed in the recent commit.
… div and removed redundant div
…vice to symbol, removed unnecessary casts from UserInviteService, ran linter
@dorner my recent commits should address your latest comments. There is a failing test, I will look further into it and report what I find. |
Resolves #4503
Description
This PR modifies
app/controllers/admin/users_controller.rb
andapp/views/admin/users/new.html.erb
so that the super admin form for inviting a new user lets one select both the role the new user should have and the resource that role should be associated with if necessary. For the super admin role, no resource is required and so the resource dropdown is hidden via a new stimulus controller.This PR also modifies
UserInviteService
in order to fascilitate the above behavior. The service now permitsnil
as a resource when the sole role being added is super admin, and will automatically add the org user role if only the org admin role is specified.It is possible that some of this logic does not belong in the
UserInviteService
. Notably, theAddRoleService
already contains logic to automatically add the org user role when the org admin role is added. In theory, theUserInviteService
could call theAddRoleService
instead of directly callingadd_role
. However,AddRoleService
relies on being passed the id of the user to add roles to, and newly created users won't have an id until after the invitation. While it would be possible to refactorAddRoleService
, that seemed outside the scope of this PR and so the current solution was selected.Type of change
How Has This Been Tested?
This was manually tested to verify that the form worked as expected when creating all the different roles.
Tests were added to
spec/requests/admin/users_requests_spec.rb
to verify that post requests could create new users with all of the possible roles (org user, org admin, partner, super admin) and that the request would fail and report an error if a role wasn't specified, or a resource wasn't specified for a role which required one. Additionally, tests were modified and added to verify that the available roles were loaded for the new and create actions.Tests were added to
spec/services/user_invite_service_spec.rb
to verify that the service will accept a nil resource for the super admin role, raise an error for a nil resource for other roles, and that it will automatically add the org user role if only the org admin role is specified.Tests were added to
spec/system/admin/users_system_spec.rb
to verify the workflow of a super admin creating an org user and super admin user. Tests were also added to verify that the resource dropdown is hidden when the super admin role is selected, and a flash message is shown if the form is submitted without selecting a resource with a role that requires one.Screenshots
The new user form, showing the resource dropdown for an organization role
The new user form, hiding the resource dropdown for a the super admin role
The new user form, showing the organizations in the dropdown
The new user form, showing the partners in the dropdown