Use only token capabilities when a token is provided

The Authenticate#allow? method (from oauth-plugin) sets current_user as a side
effect of checking the token. But this allows a valid token to access
all actions that are available to that user, beyond the capabilities for
that token.
This commit is contained in:
Andy Allan 2018-12-12 13:58:38 +01:00
parent a3a10237f7
commit 981e4a34b5
2 changed files with 33 additions and 2 deletions

View file

@ -446,9 +446,9 @@ class ApplicationController < ActionController::Base
end
def current_ability
# Add in capabilities from the oauth token if it exists and is a valid access token
# Use capabilities from the oauth token if it exists and is a valid access token
if Authenticator.new(self, [:token]).allow?
Ability.new(current_user).merge(Capability.new(current_token))
Capability.new(current_token)
else
Ability.new(current_user)
end

View file

@ -210,4 +210,35 @@ class UserPreferencesControllerTest < ActionController::TestCase
UserPreference.find([user.id, "key"])
end
end
# Ensure that a valid access token with correct capabilities can be used to
# read preferences
def test_read_one_using_token
user = create(:user)
token = create(:access_token, :user => user, :allow_read_prefs => true)
create(:user_preference, :user => user, :k => "key", :v => "value")
# Hack together an oauth request - an alternative would be to sign the request properly
@request.env["oauth.version"] = 1
@request.env["oauth.strategies"] = [:token]
@request.env["oauth.token"] = token
get :read_one, :params => { :preference_key => "key" }
assert_response :success
end
# Ensure that a valid access token with incorrect capabilities can't be used
# to read preferences even, though the owner of that token could read them
# by other methods.
def test_read_one_using_token_fail
user = create(:user)
token = create(:access_token, :user => user, :allow_read_prefs => false)
create(:user_preference, :user => user, :k => "key", :v => "value")
@request.env["oauth.version"] = 1
@request.env["oauth.strategies"] = [:token]
@request.env["oauth.token"] = token
get :read_one, :params => { :preference_key => "key" }
assert_response :forbidden
end
end