DEV: Add support for allowed parameters in user api key scopes
Initially, this feature is only intended for use in core/plugins, so there is no API for requesting a parameter-scoped key. That may change in future.
This commit is contained in:
parent
1cec333f48
commit
23e5c605f6
|
@ -12,7 +12,8 @@ class UserApiKeyScope < ActiveRecord::Base
|
|||
RouteMatcher.new(methods: :get, actions: 'notifications#index'),
|
||||
RouteMatcher.new(methods: :put, actions: 'notifications#mark_read')
|
||||
],
|
||||
session_info: [ RouteMatcher.new(methods: :get, actions: 'session#current') ]
|
||||
session_info: [ RouteMatcher.new(methods: :get, actions: 'session#current') ],
|
||||
bookmarks_calendar: [ RouteMatcher.new(methods: :get, actions: 'users#bookmarks', formats: :ics, params: %i[username]) ]
|
||||
}
|
||||
|
||||
def self.all_scopes
|
||||
|
@ -20,7 +21,7 @@ class UserApiKeyScope < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def permits?(env)
|
||||
matchers.any? { |m| m.match?(env: env) }
|
||||
matchers.any? { |m| m.with_allowed_param_values(allowed_parameters).match?(env: env) }
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -40,6 +41,7 @@ end
|
|||
# name :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# allowed_parameters :jsonb
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -1049,6 +1049,7 @@ en:
|
|||
read: "Read all"
|
||||
write: "Write all"
|
||||
one_time_password: "Create a one-time login token"
|
||||
bookmarks_calendar: "Read bookmark reminders"
|
||||
invalid_public_key: "Sorry, the public key is invalid."
|
||||
invalid_auth_redirect: "Sorry, this auth_redirect host is not allowed."
|
||||
invalid_token: "Missing, invalid or expired token."
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAllowedParametersToUserApiKeyScope < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :user_api_key_scopes, :allowed_parameters, :jsonb
|
||||
end
|
||||
end
|
|
@ -8,3 +8,10 @@ Fabricator(:readonly_user_api_key, from: :user_api_key) do
|
|||
client_id { SecureRandom.hex }
|
||||
application_name 'some app'
|
||||
end
|
||||
|
||||
Fabricator(:bookmarks_calendar_user_api_key, from: :user_api_key) do
|
||||
user
|
||||
scopes { [Fabricate.build(:user_api_key_scope, name: 'bookmarks_calendar')] }
|
||||
client_id { SecureRandom.hex }
|
||||
application_name 'some app'
|
||||
end
|
||||
|
|
|
@ -99,4 +99,33 @@ describe 'user api keys' do
|
|||
expect(response.status).to eq(302)
|
||||
end
|
||||
|
||||
it "can restrict scopes by parameters" do
|
||||
admin = Fabricate(:admin)
|
||||
|
||||
calendar_key = Fabricate(:bookmarks_calendar_user_api_key, user: admin)
|
||||
|
||||
get "/u/#{user.username}/bookmarks.json", headers: {
|
||||
HTTP_USER_API_KEY: calendar_key.key,
|
||||
}
|
||||
expect(response.status).to eq(403) # Does not allow json
|
||||
|
||||
get "/u/#{user.username}/bookmarks.ics", headers: {
|
||||
HTTP_USER_API_KEY: calendar_key.key,
|
||||
}
|
||||
expect(response.status).to eq(200) # Allows ICS
|
||||
|
||||
# Now restrict the key
|
||||
calendar_key.scopes.first.update(allowed_parameters: { username: admin.username })
|
||||
|
||||
get "/u/#{user.username}/bookmarks.ics", headers: {
|
||||
HTTP_USER_API_KEY: calendar_key.key,
|
||||
}
|
||||
expect(response.status).to eq(403) # Cannot access another users calendar
|
||||
|
||||
get "/u/#{admin.username}/bookmarks.ics", headers: {
|
||||
HTTP_USER_API_KEY: calendar_key.key,
|
||||
}
|
||||
expect(response.status).to eq(200) # Can access own calendar
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue