-
Notifications
You must be signed in to change notification settings - Fork 991
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
Fixes #37936 - As a user, I want to invalidate jwt for specific user #10357
base: develop
Are you sure you want to change the base?
Conversation
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.
Leaving the comment for the the proper review, this can be easily missed but I believe is important to get it right.
render :json => { :error => _("User %s does not exist.") % @user.login} | ||
elsif [email protected]?(:edit_users) | ||
deny_access N_("User %s does not have permissions to invalidate" % @user.login) | ||
else @user.can?(:edit_users) && @user.invalidate_jwt.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.
I think this is not enough. edit_users
permission may have specific conditions set. This would allow any user that can edit one specific user's profile to invalidate token for all users, introducing a privilege escalation.
If you look at can?
definition you can see it also accepts subject
which should the permission be verified on. We need to be checking that user can edit_users
on the specific @user
.
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.
Ack, I'll look into updating the subject
app/helpers/users_helper.rb
Outdated
@@ -33,14 +33,22 @@ def user_action_buttons(user, additional_actions = []) | |||
:method => :post, | |||
:data => { :no_turbolink => true }) | |||
end | |||
|
|||
if user != User.current | |||
additional_actions << display_link_if_authorized(_("Invalidate JWT"), |
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 exact same problem like with can?
above, the auth object needs to be specified. If this is used on some users listing page, to avoid N+1 issue, an authorized object needs to be used.
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 am already adding :auth_object
here, is this what you're talking about?
47ec499
to
37cd91b
Compare
@@ -111,6 +111,23 @@ def update | |||
end | |||
end | |||
|
|||
api :PATCH, "/users/:id/invalidate_jwt", N_("Get vm attributes of host") |
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.
Copy-paste leftovers?
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, my bad
@@ -111,6 +111,23 @@ def update | |||
end | |||
end | |||
|
|||
api :PATCH, "/users/:id/invalidate_jwt", N_("Get vm attributes of host") | |||
param :id, String, :required => 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.
I suppose you would want to have an array parameter here. To be able to invalidate tokens for multiple users.
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.
currently in the scope, (atleast UI wise) we can invalidate tokens for a specific user or all users because otherwise I would have to add a select action in the UI. I was thinking, I can add another endpoint to invalidate all at once. Allowing multiple (but not all) users token invalidation can take some time to integrate
DOC | ||
|
||
def invalidate_jwt | ||
@user = User.find(params[: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.
@user = User.find(params[:id]) | |
@user = User.where(id: params[:id]).authorized(:edit_user) |
This will filter only the users that edit_user
permission applies to them, including custom filters.
Now you will have a set of users that you can safely delete the tokens for:
JwtSecret.where(user_id: @users).destroy_all
@@ -12,8 +12,8 @@ class UsersController < V2::BaseController | |||
['compute_attributes'] | |||
|
|||
before_action :find_optional_nested_object | |||
skip_before_action :authorize, :only => [:extlogin] | |||
before_action :authenticate, :only => [:extlogin] | |||
skip_before_action :authorize, :only => [:extlogin, :invalidate_jwt] |
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 you need to skip authorization for invalidate_jwt
action?
You can specify the action in the security block:
:"api/v2/users" => [:update] |
This will make sure the current user has the
edit_users
permission before accessing the endpoint.
@@ -8,7 +8,7 @@ class UsersController < ApplicationController | |||
rescue_from ActionController::InvalidAuthenticityToken, with: :login_token_reload | |||
skip_before_action :require_mail, :only => [:edit, :update, :logout, :stop_impersonation] | |||
skip_before_action :require_login, :check_user_enabled, :authorize, :session_expiry, :update_activity_time, :set_taxonomy, :set_gettext_locale_db, :only => [:login, :logout, :extlogout] | |||
skip_before_action :authorize, :only => [:extlogin, :impersonate, :stop_impersonation] | |||
skip_before_action :authorize, :only => [:extlogin, :impersonate, :stop_impersonation, :invalidate_jwt] |
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 same as for the API endpoint. You can specify the new action in the security block:
:users => [:edit, :update], |
Tested and does as needed, one small thing that acts weird to me is that a user cant invalidate their own jwt, so for example admin doesnt have the invalidate button, but a user with edit_users permission can invalidate admins tokens. |
It's because there will be a different button in the user details page for this, from UI Perspective, for a user to invalidate tokens for themselves, they will have it in the profile page |
@girijaasoni I think it looks a bit weird in the UI that other users have the invalidate button, but not the current (admin) user: |
|
Please feel free to review the code and test the PR while I continue writing the tests!
WIP: currently writing tests