From 35523a2fbcf186013cb6473ae6ed9769308be077 Mon Sep 17 00:00:00 2001 From: Jesus Federico Date: Thu, 13 Jun 2024 16:39:24 -0400 Subject: [PATCH] LTI-375: allow custom pattern for legacy_handler per tenant with text pattern for handler (#248) --- app/controllers/message_controller.rb | 36 +++++++++++++++++---------- lib/bbb_lti_broker/helpers.rb | 26 +++++++++++++------ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/app/controllers/message_controller.rb b/app/controllers/message_controller.rb index 6a863e73..5ef662e9 100644 --- a/app/controllers/message_controller.rb +++ b/app/controllers/message_controller.rb @@ -85,7 +85,7 @@ def basic_lti_launch_request_legacy # Inject the handler_legacy to the lti_launch. lti_launch = RailsLti2Provider::LtiLaunch.find_by(nonce: params[:oauth_nonce]) post_params = lti_launch.message.post_params - post_params['custom_handler_legacy'] = handler_legacy + post_params['custom_handler_legacy'] = handler_legacy(handler_legacy_patterns(params['tenant'])) lti_message = IMS::LTI::Models::Messages::Message.generate(post_params) lti_launch.update(message: lti_message.post_params) @@ -168,26 +168,22 @@ def process_openid_message # rules are needed. # - param-xxx, it is a literal value of parameter xxx. # - fqdn-yyy parses the host obtained from processing the value of parameter yyy as a URL. + # - text-zzz is a literal value zzz. # - | is a fallback in case the value found from the first pattern is empty. # # E.g. # konekti: 'param-tool_consumer_instance_guid|fqdn-ext_tc_profile_url,param-context_id,param-resource_link_id' # bbb-lti 'param-resource_link_id,param-oauth_consumer_key' (default) # - def handler_legacy + def handler_legacy(patterns) # Hardcoded patterns to support Konekti launches. - patterns = Rails.configuration.handler_legacy_patterns seed_string = '' patterns.split(',').each do |pattern| seed = '' - if pattern.include?('|') - fallbacks = pattern.split('|') - fallbacks.each do |fallback| - seed = seed_param(fallback) - break unless seed.empty? - end - else - seed = seed_param(pattern) + fallbacks = pattern.split('|') + fallbacks.each do |fallback| + seed = seed_param(fallback) + break unless seed.empty? end seed_string += seed end @@ -198,9 +194,23 @@ def handler_legacy # E.g. param-resource_link_id def seed_param(pattern) elements = pattern.split('-') - return params[elements[1]] if elements[0] == 'param' - return URI.parse(params[elements[1]]).host if elements[0] == 'fqdn' + + case elements[0] + when 'param' + return params[elements[1]] + when 'fqdn' + return URI.parse(params[elements[1]]).host unless params[elements[1]].nil? + when 'text' + return elements[1] + end '' end + + def handler_legacy_patterns(tenant_uid) + tenant = RailsLti2Provider::Tenant.find_by(uid: tenant_uid) + return Rails.configuration.handler_legacy_patterns if tenant.nil? || tenant.settings['handler_legacy_patterns'].blank? + + tenant.settings['handler_legacy_patterns'] + end end diff --git a/lib/bbb_lti_broker/helpers.rb b/lib/bbb_lti_broker/helpers.rb index dc64a708..fed61dee 100644 --- a/lib/bbb_lti_broker/helpers.rb +++ b/lib/bbb_lti_broker/helpers.rb @@ -93,19 +93,31 @@ def user_params(tc_instance_guid, params) # Core parameters may have to be overriden in order to make the applications behave differently # for that, the LTI link in the tool consumer would need to include a custom parameter in the form: # - # custom_resource_link_id=static:"some value" -> resource_link_id="some value" - # custom_resource_link_id=param:contenxt_id -> resource_link_id= - # custom_resource_link_id="another value" -> resource_link_id= + # custom_override_resource_link_id=static:"some value" -> resource_link_id="some value" + # custom_override_resource_link_id=param:contenxt_id -> resource_link_id= + # custom_override_resource_link_id="another value" -> resource_link_id= # def custom_overrides(message) custom_params = message['custom_params'].to_h - custom_params.each do |key, value| - custom_param = key.delete_prefix('custom_') + custom_params.each do |custom_param_name, value| + next unless custom_param_name.start_with?('custom_override_') + + param_name = custom_param_name.delete_prefix('custom_override_') + next unless safe_custom_override_params.include?(param_name) + pattern = value.split(':') - message[custom_param] = pattern[1] if pattern[0] == 'static' - message[custom_param] = message[pattern[1]] if pattern[0] == 'param' + message[param_name] = pattern[1] if pattern[0] == 'static' + message[param_name] = message['custom_params'][pattern[1]] if pattern[0] == 'param' end message end + + # parameters that are safe for custom overriding. + def safe_custom_override_params + # TODO: Only safe params should be allowed to be overriden, there are two approaches for this. + # 1) set them through a tenant setting + # 2) set the overriding rules through tenant settings (safest) + ['user_image'] + end end end