Add endpoint to retrieve list of possible api scopes

fixes PLAT-3025

Test plan:
* Do a get request to /api/v1/scopes
* Ensure list of scopes is returned
* Ensure documentation for endpoint

Change-Id: Iabcfef360728a5e3397ccd837d38133cc8d1d24c
Reviewed-on: https://gerrit.instructure.com/139207
Reviewed-by: Nathan Mills <nathanm@instructure.com>
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Product-Review: Andrew Butterfield <abutterfield@instructure.com>
This commit is contained in:
Andrew Butterfield 2018-01-25 15:03:18 -08:00
parent a43d57e055
commit 12d9d2d3e7
4 changed files with 130 additions and 3 deletions

View File

@ -0,0 +1,52 @@
#
# Copyright (C) 2018 - 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/>.
#
# @API Scopes
# API for retrieving API scopes
#
# @model Scope
# {
# "id": "Scope",
# "description": "",
# "properties": {
# "name": {
# "description": "The identifier for the scope",
# "example": "https://api.instructure.com/auth/canvas.manage_groups",
# "type": "string"
# },
# "label": {
# "description": "A human readable description of what the scope allows",
# "example": "Manage (create / edit / delete) groups",
# "type": "string"
# }
# }
# }
#
class ScopesApiController < ApplicationController
before_action :require_context
# @API List scopes
# A list of scopes that can be applied to developer keys and access tokens.
#
# @returns [Scope]
def index
if authorized_action(@context, @current_user, :manage_role_overrides)
render :json => RoleOverride.manageable_access_token_scopes(@context)
end
end
end

View File

@ -423,7 +423,8 @@ class RoleOverride < ActiveRecord::Base
'DesignerEnrollment',
'TeacherEnrollment',
'AccountAdmin'
]
],
:acts_as_access_token_scope => true
},
:view_group_pages => {
:label => lambda { t('permissions.view_group_pages', "View the group pages of all student groups") },
@ -460,7 +461,8 @@ class RoleOverride < ActiveRecord::Base
'DesignerEnrollment',
'TeacherEnrollment',
'AccountAdmin'
]
],
:acts_as_access_token_scope => true
},
:manage_assignments => {
:label => lambda { t('permissions.manage_assignments', "Manage (add / edit / delete) assignments and quizzes") },
@ -478,7 +480,8 @@ class RoleOverride < ActiveRecord::Base
'DesignerEnrollment',
'TeacherEnrollment',
'AccountAdmin'
]
],
:acts_as_access_token_scope => true
},
:undelete_courses => {
:label => lambda { t('permissions.undelete_courses', "Undelete courses") },
@ -800,6 +803,8 @@ class RoleOverride < ActiveRecord::Base
}
})
ACCESS_TOKEN_SCOPE_PREFIX = 'https://api.instructure.com/auth/canvas'.freeze
def self.permissions
Permissions.retrieve
end
@ -820,6 +825,18 @@ class RoleOverride < ActiveRecord::Base
permissions
end
def self.manageable_access_token_scopes(context)
permissions = manageable_permissions(context).dup
permissions.select! { |_, p| p[:acts_as_access_token_scope].present? }
permissions.map do |k, p|
{
name: "#{ACCESS_TOKEN_SCOPE_PREFIX}.#{k}",
label: p[:label].call
}
end
end
def self.css_class_for(context, permission, role, role_context=nil)
generated_permission = self.permission_for(context, permission, role, role_context=nil)

View File

@ -965,6 +965,10 @@ CanvasRails::Application.routes.draw do
put "courses/:course_id/tabs/:tab_id", action: :update
end
scope(controller: :scopes_api) do
get "accounts/:account_id/scopes", action: :index
end
scope(controller: :sections) do
get 'courses/:course_id/sections', action: :index, as: 'course_sections'
get 'courses/:course_id/sections/:id', action: :show, as: 'course_section'

View File

@ -0,0 +1,54 @@
#
# Copyright (C) 2018 - 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/>.
#
require File.expand_path(File.dirname(__FILE__) + '/../api_spec_helper')
describe ScopesApiController, type: :request do
describe "index" do
context "with admin" do
before :once do
@account = account_model
account_admin_user(:account => @account)
user_with_pseudonym(:user => @admin)
end
it "returns expected scopes" do
json = api_call(:get, "/api/v1/accounts/#{@account.id}/scopes", { controller: 'scopes_api', action: 'index', format: 'json', account_id: @account.id.to_s })
[
'manage_assignments',
'manage_files',
'manage_groups'
].each do |scope|
expect(json.one? { |s| s['name'] == "#{RoleOverride::ACCESS_TOKEN_SCOPE_PREFIX}.#{scope}" }).to eq true
end
end
end
context "with nonadmin" do
before :once do
@account = account_model
user_with_pseudonym(account: @account)
end
it "returns a 401" do
json = api_call(:get, "/api/v1/accounts/#{@account.id}/scopes", { controller: 'scopes_api', action: 'index', format: 'json', account_id: @account.id.to_s })
expect(response.code).to eql '401'
end
end
end
end