add new option for dev keys to allow includes
closes PLAT-5154 flag = developer_key_support_includes Test Plan: - Create or Edit an API Developer Key - set the flag on the Developer Key to allow includes 'allow_includes' - Use an API tool to authenticate and hit an API endpoint and include 'include' parameters (see Clint or Weston on how to authenticate) ex: /api/v1/courses/:id?include[]=permissions&include[]=concluded - verify that in the response json, the included data exists Change-Id: I268f59287505151b9e3cb0c0024a4f837e33412e Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/222143 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Clint Furse <cfurse@instructure.com> Reviewed-by: Weston Dransfield <wdransfield@instructure.com> QA-Review: Weston Dransfield <wdransfield@instructure.com>
This commit is contained in:
parent
b33e5461d2
commit
1d2ad17214
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# Copyright (C) 2019 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class AddAllowIncludeParamsToDeveloperKey < ActiveRecord::Migration[5.2]
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
add_column :developer_keys, :allow_includes, :boolean
|
||||
change_column_default(:developer_keys, :allow_includes, false)
|
||||
DataFixup::BackfillNulls.run(DeveloperKey, :allow_includes, default_value: false)
|
||||
change_column_null(:developer_keys, :allow_includes, false)
|
||||
end
|
||||
end
|
|
@ -94,18 +94,20 @@ module AuthenticationMethods
|
|||
end
|
||||
|
||||
def validate_scopes
|
||||
if @access_token
|
||||
developer_key = @access_token.developer_key
|
||||
request_method = request.method.casecmp('HEAD') == 0 ? 'GET' : request.method.upcase
|
||||
return unless @access_token
|
||||
|
||||
if developer_key.try(:require_scopes)
|
||||
scope_patterns = @access_token.url_scopes_for_method(request_method).concat(AccessToken.always_allowed_scopes)
|
||||
if scope_patterns.any? { |scope| scope =~ request.path }
|
||||
developer_key = @access_token.developer_key
|
||||
request_method = request.method.casecmp('HEAD') == 0 ? 'GET' : request.method.upcase
|
||||
|
||||
if developer_key.try(:require_scopes)
|
||||
scope_patterns = @access_token.url_scopes_for_method(request_method).concat(AccessToken.always_allowed_scopes)
|
||||
if scope_patterns.any? { |scope| scope =~ request.path }
|
||||
unless developer_key.try(:allow_includes)
|
||||
filter_includes(:include)
|
||||
filter_includes(:includes)
|
||||
else
|
||||
raise AccessTokenScopeError
|
||||
end
|
||||
else
|
||||
raise AccessTokenScopeError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1614,6 +1614,24 @@ describe CoursesController do
|
|||
expect(params).to eq(include: [], includes: ['uuid'])
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid scopes and allow includes on dev key' do
|
||||
let(:developer_key) { DeveloperKey.create!(require_scopes: true, allow_includes: true, scopes: ['url:GET|/api/v1/accounts']) }
|
||||
|
||||
it 'keeps includes for adequately scoped requests' do
|
||||
user = user_model
|
||||
token = AccessToken.create!(user: user, developer_key: developer_key, scopes: ['url:GET|/api/v1/accounts'])
|
||||
controller.instance_variable_set(:@access_token, token)
|
||||
allow(controller).to receive(:request).and_return(double({
|
||||
method: 'GET',
|
||||
path: '/api/v1/accounts'
|
||||
}))
|
||||
params = { include: ['a'], includes: ['uuid', 'b']}
|
||||
allow(controller).to receive(:params).and_return(params)
|
||||
controller.send(:validate_scopes)
|
||||
expect(params).to eq(include: ['a'], includes: ['uuid', 'b'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue