Skip to content

Missing generate_rsa_keypair in Dynamic Registration LTI Tool Creation #2648

Description

@Stephen-A-Steyaert

Describe the bug

I am creating an LTI tool, and while debugging, I ran into the private key not being generated on tool creation. I have patched it locally, in the dynamic_registration_controller.rb where the tool is created on line 324/325, but I figured it would be good to point out.

This is what I updated it to be:

Lines 310-334 of app/controllers/lti/ims/deep_linking_controller.rb

        root_account.shard.activate do
          current_user = User.find(jwt["user_id"])
          developer_key = DeveloperKey.new(
            current_user:,
            name: registration_attrs["client_name"],
            account: root_account.site_admin? ? nil : root_account,
            redirect_uris: registration_attrs["redirect_uris"],
            public_jwk_url: registration_attrs["jwks_uri"],
            oidc_initiation_url: registration_attrs["initiate_login_uri"],
            is_lti_key: true,
            scopes: registration_attrs["scopes"],
            icon_url: registration_attrs["logo_uri"],
            skip_lti_sync: true
          )

          developer_key.generate_rsa_keypair!
          
          ims_registration = Lti::IMS::Registration.new(
            developer_key:,
            root_account_id: root_account.id,
            guid: jwt["uuid"],
            unified_tool_id: jwt["unified_tool_id"],
            registration_url:,
            **registration_attrs
          )

'Preciate y'all

Edit: the code above didn't work for the signing.

Screenshots or screen recordings

No response

Steps to reproduce

  1. Create an LTI tool using dynamic registration
  2. Add app to course
  3. Attempt to create an assignment with aforementioned tool

It should give you something like in the log output

What browsers are you seeing the problem on (if applicable)?

No response

Backtrace

Full Stack Trace:
==================

/home/docker/.gem/3.4/gems/json-jwt-1.17.0/lib/json/jws.rb:107:in 'JSON::JWS#sign'
/home/docker/.gem/3.4/gems/json-jwt-1.17.0/lib/json/jws.rb:17:in 'JSON::JWS#sign!'
/home/docker/.gem/3.4/gems/json-jwt-1.17.0/lib/json/jwt.rb:41:in 'JSON::JWT#sign'
/usr/src/app/gems/lti-advantage/lib/lti_advantage/messages/jwt_message.rb:77:in 'LtiAdvantage::Messages::JwtMessage.create_jws'
/usr/src/app/lib/lti/messages/jwt_message.rb:53:in 'Lti::Messages::JwtMessage.generate_id_token'
/usr/src/app/app/controllers/lti/ims/authentication_controller.rb:225:in 'Lti::IMS::AuthenticationController#id_token'
/usr/src/app/app/controllers/lti/ims/authentication_controller.rb:163:in 'Lti::IMS::AuthenticationController#validate_launch_eligibility!'
/usr/src/app/app/controllers/lti/ims/authentication_controller.rb:115:in 'block in Lti::IMS::AuthenticationController#authorize'
/usr/src/app/lib/utils/inst_statsd_utils/timing.rb:50:in 'Utils::InstStatsdUtils::Timing.track'
/usr/src/app/app/controllers/lti/ims/authentication_controller.rb:78:in 'Lti::IMS::AuthenticationController#authorize'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal/basic_implicit_render.rb:8:in 'ActionController::BasicImplicitRender#send_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/abstract_controller/base.rb:215:in 'AbstractController::Base#process_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal/rendering.rb:193:in 'ActionController::Rendering#process_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/abstract_controller/callbacks.rb:261:in 'block in AbstractController::Callbacks#process_action'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:120:in 'block in ActiveSupport::Callbacks#run_callbacks'
/usr/src/app/app/controllers/application_controller.rb:3558:in 'ApplicationController#manage_live_events_context'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/usr/src/app/app/controllers/application_controller.rb:1128:in 'ApplicationController#compute_http_cost'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/home/docker/.gem/3.4/gems/inst_statsd-3.4.0/lib/inst_statsd/statsd.rb:111:in 'InstStatsd::Statsd.batch'
/usr/src/app/app/controllers/application_controller.rb:1123:in 'ApplicationController#batch_statsd'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/usr/src/app/lib/base/temp_cache.rb:30:in 'TempCache.enable'
/usr/src/app/app/controllers/application_controller.rb:1119:in 'ApplicationController#enable_request_cache'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/usr/src/app/app/controllers/application_controller.rb:1115:in 'ApplicationController#set_timezone'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/usr/src/app/app/controllers/application_controller.rb:1105:in 'ApplicationController#set_locale'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/usr/src/app/app/controllers/application_controller.rb:154:in 'ApplicationController#n_plus_one_detection'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/home/docker/.gem/3.4/gems/sentry-rails-6.5.0/lib/sentry/rails/controller_transaction.rb:34:in 'block in Sentry::Rails::ControllerTransaction#sentry_around_action'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry/hub.rb:139:in 'Sentry::Hub#with_child_span'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry-ruby.rb:526:in 'Sentry.with_child_span'
/home/docker/.gem/3.4/gems/sentry-rails-6.5.0/lib/sentry/rails/controller_transaction.rb:18:in 'Sentry::Rails::ControllerTransaction#sentry_around_action'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:140:in 'ActiveSupport::Callbacks#run_callbacks'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/abstract_controller/callbacks.rb:260:in 'AbstractController::Callbacks#process_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal/rescue.rb:27:in 'ActionController::Rescue#process_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal/instrumentation.rb:76:in 'block in ActionController::Instrumentation#process_action'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/notifications.rb:210:in 'block in ActiveSupport::Notifications.instrument'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/notifications.rb:210:in 'ActiveSupport::Notifications.instrument'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal/instrumentation.rb:75:in 'ActionController::Instrumentation#process_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal/params_wrapper.rb:259:in 'ActionController::ParamsWrapper#process_action'
/home/docker/.gem/3.4/gems/activerecord-8.0.5/lib/active_record/railties/controller_runtime.rb:39:in 'ActiveRecord::Railties::ControllerRuntime#process_action'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/abstract_controller/base.rb:152:in 'AbstractController::Base#process'
/home/docker/.gem/3.4/gems/actionview-8.0.5/lib/action_view/rendering.rb:40:in 'ActionView::Rendering#process'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal.rb:252:in 'ActionController::Metal#dispatch'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_controller/metal.rb:335:in 'ActionController::Metal.dispatch'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/routing/route_set.rb:67:in 'ActionDispatch::Routing::RouteSet::Dispatcher#dispatch'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/routing/route_set.rb:50:in 'ActionDispatch::Routing::RouteSet::Dispatcher#serve'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/journey/router.rb:53:in 'block in ActionDispatch::Journey::Router#serve'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/journey/router.rb:133:in 'block in ActionDispatch::Journey::Router#find_routes'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/journey/router.rb:126:in 'Array#each'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/journey/router.rb:126:in 'ActionDispatch::Journey::Router#find_routes'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/journey/router.rb:34:in 'ActionDispatch::Journey::Router#serve'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/routing/route_set.rb:908:in 'ActionDispatch::Routing::RouteSet#call'
/home/docker/.gem/3.4/gems/railties-8.0.5/lib/rails/engine/lazy_route_set.rb:60:in 'Rails::Engine::LazyRouteSet#call'
/usr/src/app/gems/plugins/respondus_soap_endpoint/lib/respondus_soap_endpoint/middleware.rb:81:in 'RespondusSoapEndpoint::Middleware#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/tempfile_reaper.rb:20:in 'Rack::TempfileReaper#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/etag.rb:29:in 'Rack::ETag#call'
/home/docker/.gem/3.4/gems/rack3-brotli-1.0.1/lib/rack/brotli/deflater.rb:30:in 'Rack::Brotli::Deflater#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/deflater.rb:47:in 'Rack::Deflater#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/conditional_get.rb:31:in 'Rack::ConditionalGet#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/head.rb:15:in 'Rack::Head#call'
/usr/src/app/app/middleware/request_throttle.rb:73:in 'block in RequestThrottle#call'
/usr/src/app/app/middleware/request_throttle.rb:425:in 'RequestThrottle::LeakyBucket#reserve_capacity'
/usr/src/app/app/middleware/request_throttle.rb:71:in 'RequestThrottle#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/http/permissions_policy.rb:38:in 'ActionDispatch::PermissionsPolicy::Middleware#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/http/content_security_policy.rb:38:in 'ActionDispatch::ContentSecurityPolicy::Middleware#call'
/usr/src/app/gems/request_context/lib/request_context/session.rb:28:in 'RequestContext::Session#call'
/home/docker/.gem/3.4/gems/rack-session-2.1.2/lib/rack/session/abstract/id.rb:274:in 'Rack::Session::Abstract::Persisted#context'
/home/docker/.gem/3.4/gems/rack-session-2.1.2/lib/rack/session/abstract/id.rb:268:in 'Rack::Session::Abstract::Persisted#call'
/usr/src/app/app/middleware/load_account.rb:50:in 'LoadAccount#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/cookies.rb:706:in 'ActionDispatch::Cookies#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/callbacks.rb:31:in 'block in ActionDispatch::Callbacks#call'
/home/docker/.gem/3.4/gems/activesupport-8.0.5/lib/active_support/callbacks.rb:100:in 'ActiveSupport::Callbacks#run_callbacks'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/callbacks.rb:30:in 'ActionDispatch::Callbacks#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/executor.rb:16:in 'ActionDispatch::Executor#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/actionable_exceptions.rb:18:in 'ActionDispatch::ActionableExceptions#call'
/home/docker/.gem/3.4/gems/sentry-rails-6.5.0/lib/sentry/rails/rescued_exception_interceptor.rb:14:in 'Sentry::Rails::RescuedExceptionInterceptor#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/debug_exceptions.rb:31:in 'ActionDispatch::DebugExceptions#call'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry/rack/capture_exceptions.rb:30:in 'block (2 levels) in Sentry::Rack::CaptureExceptions#call'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry/hub.rb:333:in 'Sentry::Hub#with_session_tracking'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry-ruby.rb:419:in 'Sentry.with_session_tracking'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry/rack/capture_exceptions.rb:21:in 'block in Sentry::Rack::CaptureExceptions#call'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry/hub.rb:89:in 'Sentry::Hub#with_scope'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry-ruby.rb:399:in 'Sentry.with_scope'
/home/docker/.gem/3.4/gems/sentry-ruby-6.5.0/lib/sentry/rack/capture_exceptions.rb:20:in 'Sentry::Rack::CaptureExceptions#call'
/usr/src/app/app/middleware/sentry_trace_scrubber.rb:40:in 'SentryTraceScrubber#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/show_exceptions.rb:32:in 'ActionDispatch::ShowExceptions#call'
/home/docker/.gem/3.4/gems/railties-8.0.5/lib/rails/rack/logger.rb:41:in 'Rails::Rack::Logger#call_app'
/home/docker/.gem/3.4/gems/railties-8.0.5/lib/rails/rack/logger.rb:29:in 'Rails::Rack::Logger#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/remote_ip.rb:96:in 'ActionDispatch::RemoteIp#call'
/home/docker/.gem/3.4/gems/request_store-1.7.0/lib/request_store/middleware.rb:19:in 'RequestStore::Middleware#call'
/usr/src/app/gems/request_context/lib/request_context/generator.rb:73:in 'RequestContext::Generator#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/method_override.rb:28:in 'Rack::MethodOverride#call'
/usr/src/app/app/middleware/prevent_non_multipart_parse.rb:35:in 'PreventNonMultipartParse#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/runtime.rb:24:in 'Rack::Runtime#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/server_timing.rb:61:in 'block in ActionDispatch::ServerTiming#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/server_timing.rb:26:in 'ActionDispatch::ServerTiming::Subscriber#collect_events'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/server_timing.rb:60:in 'ActionDispatch::ServerTiming#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/executor.rb:16:in 'ActionDispatch::Executor#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/static.rb:27:in 'ActionDispatch::Static#call'
/home/docker/.gem/3.4/gems/rack-3.2.6/lib/rack/sendfile.rb:131:in 'Rack::Sendfile#call'
/home/docker/.gem/3.4/gems/actionpack-8.0.5/lib/action_dispatch/middleware/host_authorization.rb:143:in 'ActionDispatch::HostAuthorization#call'
/home/docker/.gem/3.4/gems/railties-8.0.5/lib/rails/engine.rb:535:in 'Rails::Engine#call'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/configuration.rb:296:in 'Puma::Configuration::ConfigMiddleware#call'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/request.rb:103:in 'block in Puma::Request#handle_request'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/thread_pool.rb:355:in 'Puma::ThreadPool#with_force_shutdown'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/request.rb:102:in 'Puma::Request#handle_request'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/server.rb:503:in 'Puma::Server#process_client'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/server.rb:262:in 'block in Puma::Server#run'
/home/docker/.gem/3.4/gems/puma-7.2.0/lib/puma/thread_pool.rb:182:in 'block in Puma::ThreadPool#spawn_thread'

Relevant log output

From iframe:

{"errors":[{"message":"An error occurred.","error_code":"internal_server_error"}],"error_report_id":19} 

From console:

 GET http://localhost:8001/api/lti/authorize?client_id=10&login_hint=6cd2e0d65bd5aef3b5ee56a64bdcd595e447bc8f&lti_message_hint=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJpZmllciI6IjEwNTM4YTU3NTc3NWRjYzNjMzMxZTQ4NWQ2MWQxZGUzYmYxMmM3YWMwOTU1Yzk5Yzc1Y2QyOWNlMGE3ODdhODk1ZmRiODUyMWMyYjk3N2ZlZDlmMjdkMjNhMDI0MTI5ZmQ2YmNhODdmYjczNzViMWMzMzAwYjdhODk5ZTRlMGMwIiwiY2FudmFzX2RvbWFpbiI6ImxvY2FsaG9zdDo4MDAxIiwiY29udGV4dF90eXBlIjoiQ291cnNlIiwiY29udGV4dF9pZCI6MSwiY2FudmFzX2xvY2FsZSI6ImVuIiwiaW5jbHVkZV9zdG9yYWdlX3RhcmdldCI6dHJ1ZSwiZXhwIjoxNzgzNDQ5NTM3fQ.P5k2k9ILxnRXbFVgF9GsHAcMAS8TMi5mf6MdzNbUp7U&nonce=18e695c6-2f1e-4b22-943de044ab0e1da7&prompt=none&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fapi%2Flti%2Flaunch&response_mode=form_post&response_type=id_token&scope=openid&state=eyJhbGciOiJIUzI1NiJ9.eyJub25jZSI6IjE4ZTY5NWM2LTJmMWUtNGIyMi05NDNkLWUwNDRhYjBlMWRhNyIsImlzcyI6Imh0dHA6Ly9ob3N0LmRvY2tlci5pbnRlcm5hbDo4MDAxIiwiY2xpZW50X2lkIjoiMTAiLCJ0YXJnZXRfbGlua191cmkiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAvYXBpL2x0aS9kZWVwLWxpbmtpbmciLCJleHAiOjE3ODM0NDk4Mzl9.YZnBLcaYOa0Udk8hnUPm_cbR3o7Sz1w1TdYL4nF7jDU 500 (Internal Server Error)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions