From b9950390963c29324c2d2e477c4c026951269999 Mon Sep 17 00:00:00 2001 From: DW-Arthur Date: Wed, 24 Aug 2022 17:33:23 +0000 Subject: [PATCH] LTI-120: Fixed replaced ENV to Rails Environmental Variable configurations --- .rubocop.yml | 4 ++ Gemfile | 6 +- Gemfile.lock | 37 +++++----- app/controllers/auth_controller.rb | 8 +-- app/controllers/concerns/apps_validator.rb | 6 +- app/controllers/concerns/deep_link_service.rb | 2 +- .../concerns/open_id_authenticator.rb | 9 +-- .../concerns/platform_grades_service.rb | 3 +- .../concerns/platform_service_connector.rb | 4 +- app/controllers/concerns/temporary_store.rb | 2 +- app/controllers/message_controller.rb | 27 +++---- app/controllers/registration_controller.rb | 8 +-- app/controllers/tool_profile_controller.rb | 22 +++--- app/services/temporary_storage.rb | 2 +- config/application.rb | 8 +++ config/environments/development.rb | 7 -- config/environments/production.rb | 12 +--- config/puma.rb | 15 ++-- config/routes.rb | 2 +- db/schema.rb | 19 ++--- lib/tasks/db_keys.rake | 6 +- lib/tasks/db_registration.rake | 70 +++++++++---------- .../tool_profile_controller_spec.rb | 2 +- .../tool_profile_controller_test.rb | 4 +- 24 files changed, 142 insertions(+), 143 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 015d0a25..2b5b8581 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -70,3 +70,7 @@ Rails/HelperInstanceVariable: Enabled: false Lint/LiteralInInterpolation: Enabled: false +Lint/MissingSuper: + Exclude: + - 'app/controllers/**/*' + - 'lib/**/*' diff --git a/Gemfile b/Gemfile index a8aff334..28351da7 100644 --- a/Gemfile +++ b/Gemfile @@ -23,10 +23,10 @@ gem 'coffee-rails', '~> 5.0', '>= 5.0.0' gem 'http' gem 'addressable', '~> 2.7' +gem 'bundler', '>=2.1.4' gem 'faraday' gem 'oauthenticator', '~> 1.3' - -gem 'bundler', '>=2.1.4' +gem 'psych', '< 4' # Use jquery as the JavaScript library gem 'jquery-rails' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks @@ -68,7 +68,7 @@ group :development, :test do end group :development do - gem 'rubocop', '~> 0.90.0', require: false + gem 'rubocop', '~> 1.10.0', require: false gem 'rubocop-rails', '~> 2.4.0', require: false # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'listen', '~> 3.0.5' diff --git a/Gemfile.lock b/Gemfile.lock index c6561cea..69b73b90 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -119,7 +119,7 @@ GEM railties (>= 3.2) erubi (1.11.0) execjs (2.8.1) - faraday (1.10.1) + faraday (1.10.0) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -161,7 +161,7 @@ GEM http-cookie (1.0.5) domain_name (~> 0.5) http-form_data (2.3.0) - i18n (1.12.0) + i18n (1.11.0) concurrent-ruby (~> 1.0) ims-lti (2.3.2) addressable (~> 2.5, >= 2.5.1) @@ -205,14 +205,12 @@ GEM marcel (1.0.2) method_source (1.0.0) mini_mime (1.1.2) - mini_portile2 (2.8.0) minitest (5.16.2) minitest-stub_any_instance (1.0.3) multi_json (1.15.0) multipart-post (2.2.3) nio4r (2.5.8) - nokogiri (1.13.8) - mini_portile2 (~> 2.8.0) + nokogiri (1.13.7-x86_64-linux) racc (~> 1.4) oauth (0.5.10) oauthenticator (1.4.0) @@ -221,10 +219,11 @@ GEM json rack (>= 1.4, < 3.0) parallel (1.22.1) - parser (3.1.2.1) + parser (3.1.2.0) ast (~> 2.4.1) - pg (1.4.3) + pg (1.4.1) popper_js (1.16.0) + psych (3.3.2) public_suffix (4.0.7) puma (5.6.4) nio4r (~> 2.0) @@ -298,17 +297,17 @@ GEM rspec-mocks (~> 3.10) rspec-support (~> 3.10) rspec-support (3.11.0) - rubocop (0.90.0) + rubocop (1.10.0) parallel (~> 1.10) - parser (>= 2.7.1.1) + parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.7) + regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 0.3.0, < 1.0) + rubocop-ast (>= 1.2.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (0.8.0) - parser (>= 2.7.1.5) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.21.0) + parser (>= 3.1.1.0) rubocop-rails (2.4.2) rack (>= 1.1) rubocop (>= 0.72.0) @@ -349,7 +348,7 @@ GEM execjs (>= 0.3.0, < 3) thor (1.2.1) thread_safe (0.3.6) - tilt (2.0.11) + tilt (2.0.10) tins (1.31.1) sync turbolinks (5.2.1) @@ -362,7 +361,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.8.2) - unicode-display_width (1.8.0) + unicode-display_width (2.2.0) web-console (4.2.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) @@ -378,7 +377,7 @@ GEM zeitwerk (2.6.0) PLATFORMS - ruby + x86_64-linux DEPENDENCIES activerecord-session_store @@ -404,6 +403,7 @@ DEPENDENCIES oauth (~> 0.5.1) oauthenticator (~> 1.3) pg (>= 0.4.4) + psych (< 4) puma (>= 4.3.5) rails (~> 6.0, >= 6.0.5.1) rails_lti2_provider! @@ -413,7 +413,7 @@ DEPENDENCIES repost (~> 0.3.8) rspec rspec-rails - rubocop (~> 0.90.0) + rubocop (~> 1.10.0) rubocop-rails (~> 2.4.0) sass-rails (>= 6.0.0) spring @@ -423,3 +423,4 @@ DEPENDENCIES tzinfo-data web-console (>= 4.1.0) webmock + diff --git a/app/controllers/auth_controller.rb b/app/controllers/auth_controller.rb index deb501d0..4da5c88c 100644 --- a/app/controllers/auth_controller.rb +++ b/app/controllers/auth_controller.rb @@ -31,15 +31,15 @@ class AuthController < ApplicationController def login logger.info('AuthController: login') - state = 'state' + SecureRandom.hex + state = "state#{SecureRandom.hex}" cookies[state] = { value: state, expires: 1.year.from_now, } - nonce = 'nonce' + SecureRandom.hex - Rails.cache.write('lti1p3_' + nonce, nonce: nonce) + nonce = "nonce#{SecureRandom.hex}" + Rails.cache.write("lti1p3_#{nonce}", nonce: nonce) auth_params = { scope: 'openid', @@ -56,7 +56,7 @@ def login auth_params[:lti_message_hint] = params[:lti_message_hint] if params.key?(:lti_message_hint) aparams = URI.encode_www_form(auth_params) - redirect_post(@registration['auth_login_url'] + '?' + aparams, options: { authenticity_token: :auto }) + redirect_post("#{@registration['auth_login_url']}?#{aparams}", options: { authenticity_token: :auto }) end private diff --git a/app/controllers/concerns/apps_validator.rb b/app/controllers/concerns/apps_validator.rb index ff364e6c..71f8003b 100644 --- a/app/controllers/concerns/apps_validator.rb +++ b/app/controllers/concerns/apps_validator.rb @@ -63,14 +63,14 @@ def lti_icon(app_name) begin app = lti_app(app_name) uri = URI.parse(app['redirect_uri'].sub('https', 'http')) - site = "#{uri.scheme}://#{uri.host}#{uri.port != 80 ? ':' + uri.port.to_s : ''}/" + site = "#{uri.scheme}://#{uri.host}#{uri.port != 80 ? ":#{uri.port}" : ''}/" path = uri.path.split('/') - path_base = (path[0].chomp(' ') == '' ? path[1] : path[0]).gsub('/', '') + '/' + path_base = "#{(path[0].chomp(' ') == '' ? path[1] : path[0]).gsub('/', '')}/" rescue StandardError # TODO: handle exception logger.error("App #{app_name} is not registered.") return end - "#{site}#{path_base + app_name + '/assets/icon.svg'}" + "#{site}#{"#{path_base}#{app_name}/assets/icon.svg"}" end end diff --git a/app/controllers/concerns/deep_link_service.rb b/app/controllers/concerns/deep_link_service.rb index b4ca6a99..3a5d0c06 100644 --- a/app/controllers/concerns/deep_link_service.rb +++ b/app/controllers/concerns/deep_link_service.rb @@ -37,7 +37,7 @@ def deep_link_jwt_response(registration, jwt_header, jwt_body, resources) 'aud' => [registration['issuer']], 'exp' => Time.now.to_i + 600, 'iat' => Time.now.to_i, - 'nonce' => 'nonce' + SecureRandom.hex, + 'nonce' => "nonce#{SecureRandom.hex}", 'https://purl.imsglobal.org/spec/lti/claim/deployment_id' => jwt_body['https://purl.imsglobal.org/spec/lti/claim/deployment_id'], 'https://purl.imsglobal.org/spec/lti/claim/message_type' => 'LtiDeepLinkingResponse', 'https://purl.imsglobal.org/spec/lti/claim/version' => '1.3.0', diff --git a/app/controllers/concerns/open_id_authenticator.rb b/app/controllers/concerns/open_id_authenticator.rb index 78a4851c..9796ac0e 100644 --- a/app/controllers/concerns/open_id_authenticator.rb +++ b/app/controllers/concerns/open_id_authenticator.rb @@ -63,7 +63,7 @@ def validate_jwt_format end def validate_nonce(jwt_body) - raise CustomError, :invalid_nonce unless jwt_body['nonce'] == Rails.cache.read('lti1p3_' + jwt_body['nonce'])[:nonce] + raise CustomError, :invalid_nonce unless jwt_body['nonce'] == Rails.cache.read("lti1p3_#{jwt_body['nonce']}")[:nonce] end def validate_registration(jwt_body) @@ -74,7 +74,7 @@ def validate_registration(jwt_body) end def validate_jwt_signature(reg, jwt_header) - public_key_set = JSON.parse(URI.open(reg['key_set_url']).read) + public_key_set = JSON.parse(URI.parse(reg['key_set_url']).read).open jwk_json = public_key_set['keys'].find do |key| key['kid'] == jwt_header['kid'] end @@ -169,9 +169,10 @@ def old_message_format(jwt_body) end end - if jwt_body['https://purl.imsglobal.org/spec/lti/claim/message_type'] == 'LtiResourceLinkRequest' + case jwt_body['https://purl.imsglobal.org/spec/lti/claim/message_type'] + when 'LtiResourceLinkRequest' p[:lti_message_type] = 'basic-lti-launch-request' - elsif jwt_body['https://purl.imsglobal.org/spec/lti/claim/message_type'] == 'LtiDeepLinkingRequest' + when 'LtiDeepLinkingRequest' p[:lti_message_type] = 'ContentItemSelectionRequest' end p diff --git a/app/controllers/concerns/platform_grades_service.rb b/app/controllers/concerns/platform_grades_service.rb index 902adabe..a8948b4e 100644 --- a/app/controllers/concerns/platform_grades_service.rb +++ b/app/controllers/concerns/platform_grades_service.rb @@ -76,8 +76,9 @@ def resource_lineitem(registration, jwt) line_items = JSON.parse(response.body) line_items.each do |line_item| - return line_item + return line_item if something?(line_item) end + raise NotFoundError end # get grades associated with current registration diff --git a/app/controllers/concerns/platform_service_connector.rb b/app/controllers/concerns/platform_service_connector.rb index 19bc26b1..c8c3d117 100644 --- a/app/controllers/concerns/platform_service_connector.rb +++ b/app/controllers/concerns/platform_service_connector.rb @@ -29,7 +29,7 @@ def access_token(registration, scopes) aud: auth_url, iat: Time.new.to_i - 5, exp: Time.new.to_i + 60, - jti: 'lti-service-token' + SecureRandom.hex, + jti: "lti-service-token#{SecureRandom.hex}", } priv = File.read(registration['tool_private_key']) @@ -69,7 +69,7 @@ def make_service_request(registration, scopes, method, url, body = nil, content_ request = Net::HTTP::Get.new(uri.request_uri) end - request.add_field('Authorization', 'Bearer ' + token) + request.add_field('Authorization', "Bearer #{token}") request['Accept'] = accept # request.add_field 'Accept', accept diff --git a/app/controllers/concerns/temporary_store.rb b/app/controllers/concerns/temporary_store.rb index f2e821f0..fd1747c8 100644 --- a/app/controllers/concerns/temporary_store.rb +++ b/app/controllers/concerns/temporary_store.rb @@ -44,7 +44,7 @@ def store_perm_file(prefix, content) file end - def read_temp_file(file_path, delete = true) + def read_temp_file(file_path, delete: true) begin file = File.open(file_path, 'r') rescue StandardError diff --git a/app/controllers/message_controller.rb b/app/controllers/message_controller.rb index 8db029c1..e206bf01 100644 --- a/app/controllers/message_controller.rb +++ b/app/controllers/message_controller.rb @@ -41,23 +41,24 @@ class MessageController < ApplicationController # fails lti_authentication in rails lti2 provider gem rescue_from RailsLti2Provider::LtiLaunch::Unauthorized do |ex| - @error = 'Authentication failed with: ' + case ex.error - when :invalid_key - 'The LTI key used is invalid' - when :invalid_signature - 'The OAuth Signature was Invalid' - when :invalid_nonce - 'The nonce has already been used' - when :request_too_old - 'The request is too old' - else - 'Unknown Error' - end + output = case ex.error + when :invalid_key + 'The LTI key used is invalid' + when :invalid_signature + 'The OAuth Signature was Invalid' + when :invalid_nonce + 'The nonce has already been used' + when :request_too_old + 'The request is too old' + else + 'Unknown Error' + end + @error = "Authentication failed with: #{output}" @message = IMS::LTI::Models::Messages::Message.generate(request.request_parameters) @header = SimpleOAuth::Header.new(:post, request.url, @message.post_params, consumer_key: @message.oauth_consumer_key, consumer_secret: lti_secret(@message.oauth_consumer_key), callback: 'about:blank') if request.request_parameters.key?('launch_presentation_return_url') - launch_presentation_return_url = request.request_parameters['launch_presentation_return_url'] + '<i_errormsg=' + @error + launch_presentation_return_url = "#{request.request_parameters['launch_presentation_return_url']}<i_errormsg=#{@error}" redirect_post(launch_presentation_return_url, options: { authenticity_token: :auto }) else render(:basic_lti_launch_request, status: :ok) diff --git a/app/controllers/registration_controller.rb b/app/controllers/registration_controller.rb index a60b8fcb..38abfbd7 100644 --- a/app/controllers/registration_controller.rb +++ b/app/controllers/registration_controller.rb @@ -26,7 +26,7 @@ class RegistrationController < ApplicationController include TemporaryStore def list - if ENV['DEVELOPER_MODE_ENABLED'] != 'true' + if Rails.configuration.developer_mode_enabled != 'true' render(file: Rails.root.join('public/404'), layout: false, status: :not_found) return end @@ -40,7 +40,7 @@ def list # production - use rails task def new @app = ENV['DEFAULT_LTI_TOOL'] - @app ||= 'default' if ENV['DEVELOPER_MODE_ENABLED'] == 'true' + @app ||= 'default' if Rails.configuration.developer_mode_enabled == 'true' @apps = lti_apps set_temp_keys set_starter_info @@ -69,7 +69,7 @@ def submit if params.key?('private_key_path') && params.key?('public_key_path') key_dir = Digest::MD5.hexdigest(params[:iss] + params[:client_id]) Dir.mkdir('.ssh/') unless Dir.exist?('.ssh/') - Dir.mkdir('.ssh/' + key_dir) unless Dir.exist?('.ssh/' + key_dir) + Dir.mkdir(".ssh/#{key_dir}") unless Dir.exist?(".ssh/#{key_dir}") priv_key = read_temp_file(params[:private_key_path]) pub_key = read_temp_file(params[:public_key_path]) @@ -149,6 +149,6 @@ def set_temp_keys def set_starter_info basic_launch_url = openid_launch_url(app: @app) deep_link_url = deep_link_request_launch_url(app: @app) - @redirect_uri = basic_launch_url + "\n" + deep_link_url + @redirect_uri = "#{basic_launch_url}\n#{deep_link_url}" end end diff --git a/app/controllers/tool_profile_controller.rb b/app/controllers/tool_profile_controller.rb index 5b4a54ae..ea35045f 100644 --- a/app/controllers/tool_profile_controller.rb +++ b/app/controllers/tool_profile_controller.rb @@ -28,20 +28,21 @@ class ToolProfileController < ApplicationController skip_before_action :verify_authenticity_token rescue_from CustomError do |ex| - @error = 'Authorization failed with: ' + case ex.error - when :missing_app - 'The App ID is not included' - when :not_found - 'The App is not registered' - else - 'Unknown Error' - end + output = case ex.error + when :missing_app + 'The App ID is not included' + when :not_found + 'The App is not registered' + else + 'Unknown Error' + end + @error = "Authorization failed with: #{output}" logger.info(@error) end # show xml builder for customization in tool consumer url def xml_builder - if ENV['DEVELOPER_MODE_ENABLED'] != 'true' && params[:app] == 'default' + if Rails.configuration.developer_mode_enabled != 'true' && params[:app] == 'default' render(file: Rails.root.join('public/404'), layout: false, status: :not_found) return end @@ -65,7 +66,6 @@ def json_config jwk = OpenSSL::PKey::RSA.new(read_temp_file(@keys[:public_key_path], false)).to_jwk jwk['alg'] = 'RS256' unless jwk.key?('alg') jwk['use'] = 'sig' unless jwk.key?('use') - jwk = jwk @json_config['public_jwk'] = jwk @@ -82,7 +82,7 @@ def json_config end def xml_config - if ENV['DEVELOPER_MODE_ENABLED'] != 'true' && params[:app] == 'default' + if Rails.configuration.developer_mode_enabled != 'true' && params[:app] == 'default' render(file: Rails.root.join('public/404'), layout: false, status: :not_found) return end diff --git a/app/services/temporary_storage.rb b/app/services/temporary_storage.rb index 8339ec71..49de19c0 100644 --- a/app/services/temporary_storage.rb +++ b/app/services/temporary_storage.rb @@ -6,7 +6,7 @@ def store(prefix, content) store_perm_file(prefix, content) end - def read(file, deletion = true) + def read(file, deletion: true) read_temp_file(file, deletion) end diff --git a/config/application.rb b/config/application.rb index 2bfb4b8a..d5d4b1e7 100755 --- a/config/application.rb +++ b/config/application.rb @@ -35,5 +35,13 @@ class Application < Rails::Application config.build_number = ENV['BUILD_NUMBER'] || 'v1' config.developer_mode_enabled = (ENV['DEVELOPER_MODE_ENABLED'] == 'true') + + config.relative_url_root = "/#{ENV['RELATIVE_URL_ROOT'] || 'lti'}" + config.assets.prefix = "#{config.relative_url_root}/assets" + + # Allow this to work in an iframe on another domain + config.action_dispatch.default_headers = { + 'X-Frame-Options' => 'ALLOWALL', + } end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 18792387..e4dc9c01 100755 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -70,11 +70,6 @@ # Suppress logger output for asset requests. config.assets.quiet = true - # Allow this to work in an iframe on another domain - config.action_dispatch.default_headers = { - 'X-Frame-Options' => 'ALLOWALL', - } - config.hosts = nil config.web_console.whiny_requests = false @@ -87,6 +82,4 @@ # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. config.file_watcher = ActiveSupport::EventedFileUpdateChecker - - config.assets.prefix = "#{ENV['RELATIVE_URL_ROOT'] ? '/' + ENV['RELATIVE_URL_ROOT'] : '/lti'}/assets" end diff --git a/config/environments/production.rb b/config/environments/production.rb index 2940bd65..998f1f50 100755 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -96,8 +96,8 @@ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') # Disable output buffering when STDOUT isn't a tty (e.g. Docker images, systemd services) - STDOUT.sync = true - logger = ActiveSupport::Logger.new(STDOUT) + $stdout.sync = true + logger = ActiveSupport::Logger.new($stdout) if ENV['RAILS_LOG_REMOTE_NAME'] && ENV['RAILS_LOG_REMOTE_PORT'] require 'remote_syslog_logger' @@ -130,14 +130,6 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - - # Allow this to work in an iframe on another domain - config.action_dispatch.default_headers = { - 'X-Frame-Options' => 'ALLOWALL', - } - - config.assets.prefix = "#{ENV['RELATIVE_URL_ROOT'] ? '/' + ENV['RELATIVE_URL_ROOT'] : '/lti'}/assets" - config.lograge.enabled = true config.lograge.ignore_actions = ['HealthCheckController#all'] end diff --git a/config/puma.rb b/config/puma.rb index c47f0006..513810f9 100755 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,37 +1,34 @@ # frozen_string_literal: true # BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. - # Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). - # This program is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free Software # Foundation; either version 3.0 of the License, or (at your option) any later # version. - +# # BigBlueButton 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 Lesser General Public License for more details. - # You should have received a copy of the GNU Lesser General Public License along # with BigBlueButton; if not, see . # Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers a minimum and maximum. +# The `threads` method setting takes two numbers: a minimum and maximum. # Any libraries that use thread pools should be configured to match # the maximum value specified for Puma. Default is set to 5 threads for minimum # and maximum, this matches the default thread size of Active Record. # -threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }.to_i +threads_count = ENV.fetch('RAILS_MAX_THREADS', 5) threads(threads_count, threads_count) # Specifies the `port` that Puma will listen on to receive requests, default is 3000. # -port(ENV.fetch('PORT') { 3000 }) +port(ENV.fetch('PORT', 3000)) # Specifies the `environment` that Puma will run in. # -environment(ENV.fetch('RAILS_ENV') { 'development' }) +environment(ENV.fetch('RAILS_ENV', 'development')) # Specifies the number of `workers` to boot in clustered mode. # Workers are forked webserver processes. If using threads and workers together @@ -39,7 +36,7 @@ # Workers do not work on JRuby or Windows (both of which do not support # processes). # -workers(ENV.fetch('WEB_CONCURRENCY') { 2 }) +workers(ENV.fetch('WEB_CONCURRENCY', 2)) # Use the `preload_app!` method when specifying a `workers` number. # This directive tells Puma to first boot the application and load code diff --git a/config/routes.rb b/config/routes.rb index 27cee85f..4b6b6f59 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -49,7 +49,7 @@ use_doorkeeper do # Including 'skip_controllers :application' disables the controller for managing external applications # [http://example.com/lti/oauth/applications] - skip_controllers :applications unless ENV['DEVELOPER_MODE_ENABLED'] == 'true' + skip_controllers :applications unless Rails.configuration.developer_mode_enabled == 'true' end get '/', to: 'application#index', as: 'lti_home' diff --git a/db/schema.rb b/db/schema.rb index 1f2dc486..10cdbb82 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -57,21 +57,21 @@ t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true end - create_table "rails_lti2_provider_lti_launches", id: :serial, force: :cascade do |t| + create_table "rails_lti2_provider_lti_launches", force: :cascade do |t| t.bigint "tool_id" t.string "nonce" t.text "message" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false end - create_table "rails_lti2_provider_registrations", id: :serial, force: :cascade do |t| + create_table "rails_lti2_provider_registrations", force: :cascade do |t| t.string "uuid" t.text "registration_request_params" t.text "tool_proxy_json" t.string "workflow_state" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false t.bigint "tool_id" t.text "correlation_id" t.index ["correlation_id"], name: "index_rails_lti2_provider_registrations_on_correlation_id", unique: true @@ -84,14 +84,15 @@ t.index ["uid"], name: "index_tenant_uid", unique: true end - create_table "rails_lti2_provider_tools", id: :serial, force: :cascade do |t| + create_table "rails_lti2_provider_tools", force: :cascade do |t| t.string "uuid" t.text "shared_secret" t.text "tool_settings" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false t.string "lti_version" t.integer "tenant_id" + t.index ["id", "tenant_id"], name: "index_tool_id_tenant_id", unique: true t.index ["tenant_id"], name: "index_tenant_id" t.index ["uuid"], name: "index_uuid", unique: true end diff --git a/lib/tasks/db_keys.rake b/lib/tasks/db_keys.rake index c67ed0e7..9051ce49 100644 --- a/lib/tasks/db_keys.rake +++ b/lib/tasks/db_keys.rake @@ -22,7 +22,7 @@ namespace :db do exit(1) end RailsLti2Provider::Tool.create!(uuid: args[:key], shared_secret: secret, lti_version: 'LTI-1p0', tool_settings: 'none', tenant: tenant) - puts("Added '#{args[:key]}=#{secret}'#{' for tenant ' + tenant.uid unless tenant.uid.empty?}") + puts("Added '#{args[:key]}=#{secret}'#{" for tenant #{tenant.uid}" unless tenant.uid.empty?}") rescue StandardError => e puts(e.backtrace) exit(1) @@ -45,7 +45,7 @@ namespace :db do exit(1) end tool.update!(shared_secret: secret, tenant: tenant) - puts("Updated '#{args[:key]}=#{secret}'#{' for tenant ' + tenant.uid unless tenant.uid.empty?}") + puts("Updated '#{args[:key]}=#{secret}'#{" for tenant #{tenant.uid}" unless tenant.uid.empty?}") rescue StandardError => e puts(e.backtrace) exit(1) @@ -67,7 +67,7 @@ namespace :db do exit(1) end tool.delete - puts("Deleted '#{args[:key]}'#{' for tenant ' + tenant.uid unless tenant.uid.empty?}") + puts("Deleted '#{args[:key]}'#{" for tenant #{tenant.uid}" unless tenant.uid.empty?}") rescue StandardError => e puts(e.backtrace) exit(1) diff --git a/lib/tasks/db_registration.rake b/lib/tasks/db_registration.rake index 50fe1e79..d50ea016 100644 --- a/lib/tasks/db_registration.rake +++ b/lib/tasks/db_registration.rake @@ -9,22 +9,22 @@ namespace :db do abort('Type must be one of [key, jwk]') unless %w[key jwk].include?(args[:type]) - STDOUT.puts('What is the issuer?') - issuer = STDIN.gets.strip + $stdout.puts('What is the issuer?') + issuer = $stdin.gets.strip abort('The issuer must be valid.') if issuer.blank? - STDOUT.puts('What is the client id?') - client_id = STDIN.gets.strip + $stdout.puts('What is the client id?') + client_id = $stdin.gets.strip - STDOUT.puts('What is the key set url?') - key_set_url = STDIN.gets.strip + $stdout.puts('What is the key set url?') + key_set_url = $stdin.gets.strip - STDOUT.puts('What is the auth token url?') - auth_token_url = STDIN.gets.strip + $stdout.puts('What is the auth token url?') + auth_token_url = $stdin.gets.strip - STDOUT.puts('What is the auth login url?') - auth_login_url = STDIN.gets.strip + $stdout.puts('What is the auth login url?') + auth_login_url = $stdin.gets.strip private_key = OpenSSL::PKey::RSA.generate(4096) public_key = private_key.public_key @@ -35,7 +35,7 @@ namespace :db do key_dir = Digest::MD5.hexdigest(issuer + client_id) Dir.mkdir('.ssh/') unless Dir.exist?('.ssh/') - Dir.mkdir('.ssh/' + key_dir) unless Dir.exist?('.ssh/' + key_dir) + Dir.mkdir(".ssh/#{key_dir}") unless Dir.exist?(".ssh/#{key_dir}") File.open(Rails.root.join(".ssh/#{key_dir}/priv_key"), 'w') do |f| f.puts(private_key.to_s) @@ -73,10 +73,10 @@ namespace :db do task :delete, [] => :environment do |_t, _args| Rake::Task['environment'].invoke ActiveRecord::Base.connection - STDOUT.puts('What is the issuer for the registration you wish to delete?') - issuer = STDIN.gets.strip - STDOUT.puts('What is the client ID for the registration?') - client_id = STDIN.gets.strip + $stdout.puts('What is the issuer for the registration you wish to delete?') + issuer = $stdin.gets.strip + $stdout.puts('What is the client ID for the registration?') + client_id = $stdin.gets.strip options = {} options['client_id'] = client_id if client_id.present? @@ -98,10 +98,10 @@ namespace :db do abort('Type must be one of [key, jwk]') unless %w[key jwk].include?(args[:type]) - STDOUT.puts('What is the issuer for the registration?') - issuer = STDIN.gets.strip - STDOUT.puts('What is the client ID for the registration?') - client_id = STDIN.gets.strip + $stdout.puts('What is the issuer for the registration?') + issuer = $stdin.gets.strip + $stdout.puts('What is the client ID for the registration?') + client_id = $stdin.gets.strip options = {} options['client_id'] = client_id if client_id.present? @@ -118,7 +118,7 @@ namespace :db do key_dir = Digest::MD5.hexdigest(issuer + client_id) Dir.mkdir('.ssh/') unless Dir.exist?('.ssh/') - Dir.mkdir('.ssh/' + key_dir) unless Dir.exist?('.ssh/' + key_dir) + Dir.mkdir(".ssh/#{key_dir}") unless Dir.exist?(".ssh/#{key_dir}") # File.open(File.join(Rails.root, '.ssh', key_dir, 'priv_key'), 'w') do |f| # f.puts(private_key.to_s) @@ -150,8 +150,8 @@ namespace :db do Rake::Task['environment'].invoke ActiveRecord::Base.connection - STDOUT.puts('What is the app you want to register with?') - requested_app = STDIN.gets.strip + $stdout.puts('What is the app you want to register with?') + requested_app = $stdin.gets.strip app = Doorkeeper::Application.find_by(name: requested_app) if app.nil? puts("App '#{requested_app}' does not exist, no urls can be given.") @@ -178,19 +178,19 @@ namespace :db do Rails.cache.write(temp_key_token, public_key_path: public_key_file.path, private_key_path: private_key_file.path, timestamp: Time.now.to_i) end - STDOUT.puts("Tool URL: \n#{openid_launch_url(app: app.name)}") - STDOUT.puts("\n") - STDOUT.puts("Deep Link URL: \n#{deep_link_request_launch_url(app: app.name)}") - STDOUT.puts("\n") - STDOUT.puts("Initiate login URL URL: \n#{openid_login_url(app: app.name)}") - STDOUT.puts("\n") - STDOUT.puts("Redirection URL(s): \n#{openid_launch_url(app: app.name)}" + "\n" + deep_link_request_launch_url(app: app.name).to_s) - STDOUT.puts("\n") - STDOUT.puts("Public Key: \n #{public_key}") - STDOUT.puts("\n") - STDOUT.puts("JWK: \n #{jwk}") - STDOUT.puts("\n") - STDOUT.puts("JSON Configuration URL: \n #{json_config_url(app: app.name, temp_key_token: temp_key_token)}") + $stdout.puts("Tool URL: \n#{openid_launch_url(app: app.name)}") + $stdout.puts("\n") + $stdout.puts("Deep Link URL: \n#{deep_link_request_launch_url(app: app.name)}") + $stdout.puts("\n") + $stdout.puts("Initiate login URL URL: \n#{openid_login_url(app: app.name)}") + $stdout.puts("\n") + $stdout.puts(format("Redirection URL(s):, \n#{openid_launch_url(app: app.name)}", "\n", deep_link_request_launch_url(app: app.name).to_s)) + $stdout.puts("\n") + $stdout.puts("Public Key: \n #{public_key}") + $stdout.puts("\n") + $stdout.puts("JWK: \n #{jwk}") + $stdout.puts("\n") + $stdout.puts("JSON Configuration URL: \n #{json_config_url(app: app.name, temp_key_token: temp_key_token)}") end desc 'Deletes the registration keys inside the temporary bbb-lti folder' diff --git a/spec/controllers/tool_profile_controller_spec.rb b/spec/controllers/tool_profile_controller_spec.rb index cdd9cb61..710f5861 100644 --- a/spec/controllers/tool_profile_controller_spec.rb +++ b/spec/controllers/tool_profile_controller_spec.rb @@ -21,7 +21,7 @@ RSpec.describe(ToolProfileController, type: :controller) do describe 'GET :app/xml_config' do it 'gives an xml page when developer mode enabled' do - ENV['DEVELOPER_MODE_ENABLED'] = 'true' + Rails.configuration.developer_mode_enabled = 'true' get :xml_config, params: { app: 'default' } expect(response).to(be_successful) diff --git a/test/controllers/tool_profile_controller_test.rb b/test/controllers/tool_profile_controller_test.rb index 6ef74665..80467ea9 100644 --- a/test/controllers/tool_profile_controller_test.rb +++ b/test/controllers/tool_profile_controller_test.rb @@ -21,7 +21,7 @@ class ToolProfileControllerTest < ActionDispatch::IntegrationTest test 'responds with xml_config for default with no parameters when developer mode is true' do - ENV['DEVELOPER_MODE_ENABLED'] = 'true' + Rails.configuration.developer_mode_enabled = 'true' get xml_config_path('default') # Response must be successful @@ -33,7 +33,7 @@ class ToolProfileControllerTest < ActionDispatch::IntegrationTest end test 'XML builder gives xml properties that are selected for cartridge link' do ENV['DEVELOPER_MODE_ENABLED'] = 'true' - get xml_config_path('default') + '?selection_height=500&selection_width=500' + get "#{xml_config_path('default')}?selection_height=500&selection_width=500" page = Nokogiri::HTML.parse(@response.body) assert(page.xpath('//extensions/property')) end