Add subscription show to LTI DataServices
closes PLAT-4761 Test Plan: - see that a call to this endpoint will show a sub Change-Id: Ifc299aebe5cfbadaf82a1970f75ad182ffa31b29 Reviewed-on: https://gerrit.instructure.com/206489 Reviewed-by: Xander Moffatt <xmoffatt@instructure.com> Tested-by: Jenkins QA-Review: Marc Phillips <mphillips@instructure.com> Product-Review: Marc Phillips <mphillips@instructure.com>
This commit is contained in:
parent
78a25bf4e8
commit
1f2394e982
|
@ -16,12 +16,55 @@
|
|||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module Lti
|
||||
# @API Data Services
|
||||
#
|
||||
# Data service api for tools.
|
||||
#
|
||||
# @model DataServiceSubscription
|
||||
# {
|
||||
# "id": "DataServiceSubscription",
|
||||
# "description": "A subscription to a data service live event.",
|
||||
# "properties": {
|
||||
# "ContextId": {
|
||||
# "description": "The id of the context for the subscription.",
|
||||
# "example": "8ADadf-asdfas-asdfas-asdfaew",
|
||||
# "type": "string"
|
||||
# },
|
||||
# "ContextType": {
|
||||
# "description": "The type of context for the subscription. Must be 'assignment', or 'root_account'",
|
||||
# "example": "root_account",
|
||||
# "type": "string"
|
||||
# },
|
||||
# "EventTypes": {
|
||||
# "description": "Array of strings representing the event types for the subscription.",
|
||||
# "example": ["asset_accessed"],
|
||||
# "type": "array",
|
||||
# "items": {"type": "string"}
|
||||
# },
|
||||
# "Format": {
|
||||
# "description": "Format to deliver the live events. Must be 'live-event' or 'caliper'.",
|
||||
# "example": "caliper",
|
||||
# "type": "string"
|
||||
# },
|
||||
# "TransportMetadata": {
|
||||
# "description": "An object with a single key: 'Url'.",
|
||||
# "example": "{\n\t\"Url\":\"sqs.example\"}",
|
||||
# "type": "string"
|
||||
# },
|
||||
# "TransportType": {
|
||||
# "description": "The type of transport for the event. Must be either 'sqs' or 'https'.",
|
||||
# "example": "sqs",
|
||||
# "type": "string"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
class DataServicesController < ApplicationController
|
||||
include Ims::Concerns::AdvantageServices
|
||||
MIME_TYPE = 'application/vnd.canvas.dataservices+json'.freeze
|
||||
|
||||
ACTION_SCOPE_MATCHERS = {
|
||||
create: all_of(TokenScopes::LTI_CREATE_DATA_SERVICE_SUBSCRIPTION_SCOPE)
|
||||
create: all_of(TokenScopes::LTI_CREATE_DATA_SERVICE_SUBSCRIPTION_SCOPE),
|
||||
show: all_of(TokenScopes::LTI_SHOW_DATA_SERVICE_SUBSCRIPTION_SCOPE)
|
||||
}.freeze.with_indifferent_access
|
||||
|
||||
rescue_from Lti::SubscriptionsValidator::InvalidContextType do
|
||||
|
@ -34,7 +77,7 @@ module Lti
|
|||
|
||||
before_action :verify_service_configured
|
||||
|
||||
# @API Create a Webhook Subscription
|
||||
# @API Create a Data Services Event Subscription
|
||||
# Creates a webook subscription for the specified event type and
|
||||
# context.
|
||||
#
|
||||
|
@ -57,6 +100,8 @@ module Lti
|
|||
#
|
||||
# @argument subscription[TransportType] [Required, String]
|
||||
# Must be either 'sqs' or 'https'.
|
||||
#
|
||||
# @returns DataServiceSubscription
|
||||
def create
|
||||
sub = params.require(:subscription)
|
||||
SubscriptionsValidator.validate_subscription_context!(sub)
|
||||
|
@ -64,6 +109,15 @@ module Lti
|
|||
forward_service_response(response)
|
||||
end
|
||||
|
||||
# @API Show a Data Services Event Subscription
|
||||
# Show existing Data Services Event Subscription
|
||||
#
|
||||
# @returns DataServiceSubscription
|
||||
def show
|
||||
response = Services::LiveEventsSubscriptionService.show(jwt_body, params.require(:id))
|
||||
forward_service_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scopes_matcher
|
||||
|
@ -81,8 +135,9 @@ module Lti
|
|||
end
|
||||
|
||||
def jwt_body
|
||||
dk_id = developer_key.global_id.to_s
|
||||
{
|
||||
sub: SecureRandom.uuid,
|
||||
sub: "#{dk_id}:#{context.uuid}",
|
||||
DeveloperKey: developer_key.global_id.to_s,
|
||||
RootAccountId: context.global_id,
|
||||
RootAccountUUID: context.uuid
|
||||
|
|
|
@ -2347,6 +2347,7 @@ CanvasRails::Application.routes.draw do
|
|||
# Data Services Service
|
||||
scope(controller: 'lti/data_services') do
|
||||
post "/accounts/:account_id/data_services", action: :create, as: :data_services_create
|
||||
get "/accounts/:account_id/data_services/:id", action: :show, as: :data_services_show
|
||||
end
|
||||
|
||||
# Names and Roles Provisioning (NRPS) v2 Service
|
||||
|
|
|
@ -55,7 +55,8 @@ module Schemas::Lti
|
|||
"https://purl.imsglobal.org/spec/lti-ags/scope/score",
|
||||
"https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly",
|
||||
"https://canvas.instructure.com/lti/public_jwk/scope/update",
|
||||
"https://canvas.instructure.com/lti/data_services/scope/create"
|
||||
"https://canvas.instructure.com/lti/data_services/scope/create",
|
||||
"https://canvas.instructure.com/lti/data_services/scope/show"
|
||||
].freeze
|
||||
}
|
||||
}.freeze,
|
||||
|
|
|
@ -29,6 +29,7 @@ class TokenScopes
|
|||
LTI_NRPS_V2_SCOPE = "https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly".freeze
|
||||
LTI_UPDATE_PUBLIC_JWK_SCOPE = "https://canvas.instructure.com/lti/public_jwk/scope/update".freeze
|
||||
LTI_CREATE_DATA_SERVICE_SUBSCRIPTION_SCOPE = "https://canvas.instructure.com/lti/data_services/scope/create".freeze
|
||||
LTI_SHOW_DATA_SERVICE_SUBSCRIPTION_SCOPE = "https://canvas.instructure.com/lti/data_services/scope/show".freeze
|
||||
LTI_SCOPES = {
|
||||
LTI_AGS_LINE_ITEM_SCOPE => I18n.t("Can create and view assignment data in the gradebook associated with the tool."),
|
||||
LTI_AGS_LINE_ITEM_READ_ONLY_SCOPE => I18n.t("Can view assignment data in the gradebook associated with the tool."),
|
||||
|
@ -36,7 +37,8 @@ class TokenScopes
|
|||
LTI_AGS_SCORE_SCOPE => I18n.t("Can create and update submission results for assignments associated with the tool."),
|
||||
LTI_NRPS_V2_SCOPE => I18n.t("Can retrieve user data associated with the context the tool is installed in."),
|
||||
LTI_UPDATE_PUBLIC_JWK_SCOPE => I18n.t("Can update public jwk for LTI services."),
|
||||
LTI_CREATE_DATA_SERVICE_SUBSCRIPTION_SCOPE => I18n.t("Can create subscription to data service data.")
|
||||
LTI_CREATE_DATA_SERVICE_SUBSCRIPTION_SCOPE => I18n.t("Can create subscription to data service data."),
|
||||
LTI_SHOW_DATA_SERVICE_SUBSCRIPTION_SCOPE => I18n.t("Can show subscription to data service data.")
|
||||
}.freeze
|
||||
LTI_AGS_SCOPES = [ LTI_AGS_LINE_ITEM_SCOPE, LTI_AGS_LINE_ITEM_READ_ONLY_SCOPE, LTI_AGS_RESULT_READ_ONLY_SCOPE, LTI_AGS_SCORE_SCOPE ].freeze
|
||||
|
||||
|
|
|
@ -22,28 +22,28 @@ require File.expand_path(File.dirname(__FILE__) + '/ims/concerns/lti_services_sh
|
|||
require_dependency "lti/public_jwk_controller"
|
||||
|
||||
describe Lti::DataServicesController do
|
||||
include WebMock::API
|
||||
|
||||
include_context 'advantage services context'
|
||||
|
||||
let(:subscription) do
|
||||
{
|
||||
ContextId: root_account.uuid,
|
||||
ContextType: 'root_account',
|
||||
EventTypes: ['discussion_topic_created'],
|
||||
Format: 'live-event',
|
||||
TransportMetadata: { Url: 'sqs.example' },
|
||||
TransportType: 'sqs'
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Canvas::Security::ServicesJwt).to receive(:encryption_secret).and_return('setecastronomy92' * 2)
|
||||
allow(Canvas::Security::ServicesJwt).to receive(:signing_secret).and_return('donttell' * 10)
|
||||
allow(HTTParty).to receive(:send).and_return(double(body: subscription, code: 200))
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
include WebMock::API
|
||||
|
||||
include_context 'advantage services context'
|
||||
|
||||
let(:subscription) do
|
||||
{
|
||||
ContextId: root_account.uuid,
|
||||
ContextType: 'root_account',
|
||||
EventTypes: ['discussion_topic_created'],
|
||||
Format: 'live-event',
|
||||
TransportMetadata: { Url: 'sqs.example' },
|
||||
TransportType: 'sqs'
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Canvas::Security::ServicesJwt).to receive(:encryption_secret).and_return('setecastronomy92' * 2)
|
||||
allow(Canvas::Security::ServicesJwt).to receive(:signing_secret).and_return('donttell' * 10)
|
||||
allow(HTTParty).to receive(:send).and_return(double(body: subscription, code: 200))
|
||||
end
|
||||
|
||||
it_behaves_like 'lti services' do
|
||||
let(:action) { :create }
|
||||
let(:expected_mime_type) { described_class::MIME_TYPE }
|
||||
|
@ -53,4 +53,15 @@ describe Lti::DataServicesController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
it_behaves_like 'lti services' do
|
||||
let(:action) { :show }
|
||||
let(:expected_mime_type) { described_class::MIME_TYPE }
|
||||
let(:scope_to_remove) { "https://canvas.instructure.com/lti/data_services/scope/show"}
|
||||
let(:params_overrides) do
|
||||
{ subscription: subscription, account_id: root_account.id, id: 'testid' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,11 +28,14 @@ shared_context 'advantage services context' do
|
|||
dk
|
||||
end
|
||||
let(:access_token_scopes) do
|
||||
%w(https://purl.imsglobal.org/spec/lti-ags/scope/lineitem
|
||||
%w(
|
||||
https://purl.imsglobal.org/spec/lti-ags/scope/lineitem
|
||||
https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly
|
||||
https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly
|
||||
https://canvas.instructure.com/lti/public_jwk/scope/update
|
||||
https://canvas.instructure.com/lti/data_services/scope/create).join(' ')
|
||||
https://canvas.instructure.com/lti/data_services/scope/create
|
||||
https://canvas.instructure.com/lti/data_services/scope/show
|
||||
).join(' ')
|
||||
end
|
||||
let(:access_token_signing_key) { Canvas::Security.encryption_key }
|
||||
let(:test_request_host) { 'test.host' }
|
||||
|
|
Loading…
Reference in New Issue