class IMS::LTI::Models::Messages::Message
Constants
- CUSTOM_PREFIX
- EXTENSION_PREFIX
- LAUNCH_TARGET_IFRAME
- LAUNCH_TARGET_WINDOW
- MESSAGE_TYPE
- OAUTH_KEYS
Attributes
custom_params[R]
ext_params[R]
jwt[RW]
launch_url[RW]
message_authenticator[R]
unknown_params[R]
Public Class Methods
add_deprecated_params(param, *params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 36 def add_deprecated_params(param, *params) add_params('@deprecated_params', param, *params) end
add_optional_params(param, *params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 28 def add_optional_params(param, *params) add_params('@optional_params', param, *params) end
add_recommended_params(param, *params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 20 def add_recommended_params(param, *params) add_params('@recommended_params', param, *params) end
add_required_params(param, *params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 12 def add_required_params(param, *params) add_params('@required_params', param, *params) end
convert_param_values_to_crlf_endings(hash)
click to toggle source
For signature generation – see usage in signed_post_params
# File lib/ims/lti/models/messages/message.rb, line 51 def convert_param_values_to_crlf_endings(hash) hash.transform_values do |val| if val.is_a?(String) # Convert to all newlines first, for consistency, just in case there # is some weird mix of newlines & carriage returns in input val.encode(universal_newline: true).encode(crlf_newline: true) else val end end end
deprecated_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 32 def deprecated_params supers_params('@deprecated_params') | (@deprecated_params || []) end
descendants()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 46 def descendants @descendants || Set.new end
generate(launch_params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 102 def self.generate(launch_params) params = launch_params.key?('jwt') ? parse_jwt(jwt: launch_params['jwt']) : launch_params klass = self.descendants.select {|d| d::MESSAGE_TYPE == params['lti_message_type']}.first message = klass ? klass.new(params) : Message.new(params) message.jwt = launch_params['jwt'] if launch_params.key?('jwt') message end
inherited(klass)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 40 def inherited(klass) @descendants ||= Set.new @descendants << klass superclass.inherited(klass) unless (self == Message) end
new(attrs = {}, custom_params = {}, ext_params = {})
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 121 def initialize(attrs = {}, custom_params = {}, ext_params = {}) @custom_params = custom_params @ext_params = ext_params @unknown_params = {} attrs.each do |k, v| str_key = k.to_s if str_key.start_with?(EXTENSION_PREFIX) @ext_params[str_key] = v elsif str_key.start_with?(CUSTOM_PREFIX) @custom_params[str_key] = v elsif !v.nil? && self.respond_to?(k.to_sym) send(("#{k}=").to_sym, v) else warn "Unknown parameter #{k}" @unknown_params[str_key] = v end end end
optional_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 24 def optional_params supers_params('@optional_params') | (@optional_params || []) end
parse_jwt(jwt:)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 110 def self.parse_jwt(jwt:) decoded_jwt = JSON::JWT.decode(jwt, :skip_verification) params = decoded_jwt['org.imsglobal.lti.message'] || {} custom = params.delete(:custom) custom.each {|k,v| params["custom_#{k}"] = v } params['consumer_key'] = decoded_jwt[:sub] ext = params.delete(:ext) ext.each {|k,v| params["ext_#{k}"] = v } params end
recommended_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 16 def recommended_params supers_params('@recommended_params') | (@recommended_params || []) end
required_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 8 def required_params supers_params('@required_params') | (@required_params || []) end
Private Class Methods
add_params(instance_variable, param, *params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 65 def add_params(instance_variable, param, *params) instance_var = self.instance_variable_get(instance_variable) || [] instance_var |= params.unshift(param) self.instance_variable_set(instance_variable, instance_var) attr_accessor(params.shift, *params) end
parameters()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 72 def parameters required_params + recommended_params + optional_params + deprecated_params end
supers_params(instance_variable)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 76 def supers_params(instance_variable) if name == "IMS::LTI::Models::Messages::Message" [] else (superclass.instance_variable_get(instance_variable) || []) | superclass.send(:supers_params, instance_variable) end end
Public Instance Methods
add_custom_params(params)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 143 def add_custom_params(params) params.each {|k, v| k.to_s.start_with?('custom_') ? @custom_params[k.to_s] = v : @custom_params["custom_#{k.to_s}"] = v} end
deprecated_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 189 def deprecated_params collect_attributes(self.class.deprecated_params) end
get_custom_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 147 def get_custom_params @custom_params.inject({}) {|hash, (k, v)| hash[k.gsub(/\Acustom_/, '')] = v; hash} end
get_ext_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 151 def get_ext_params @ext_params.inject({}) {|hash, (k, v)| hash[k.gsub(/\Aext_/, '')] = v; hash} end
jwt_params(private_key:, originating_domain:, algorithm: :HS256)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 159 def jwt_params(private_key:, originating_domain:, algorithm: :HS256) { 'jwt' => to_jwt(private_key: private_key, originating_domain: originating_domain, algorithm: algorithm) } end
method_missing(meth, *args, &block)
click to toggle source
Calls superclass method
# File lib/ims/lti/models/messages/message.rb, line 197 def method_missing(meth, *args, &block) if match = /^(custom|ext)_([^=$]*)/.match(meth) param_type, key = match.captures param_hash = instance_variable_get("@#{param_type}_params".to_sym) meth =~ /=$/ ? param_hash[match.to_s] = args[0] : param_hash[match.to_s] else super end end
oauth_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 193 def oauth_params collect_attributes(OAUTH_KEYS) end
optional_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 185 def optional_params collect_attributes(self.class.optional_params) end
parameters()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 173 def parameters collect_attributes(self.class.send("parameters")) end
post_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 155 def post_params unknown_params.merge(@custom_params).merge(@ext_params).merge(parameters) end
recommended_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 181 def recommended_params collect_attributes(self.class.recommended_params) end
required_params()
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 177 def required_params collect_attributes(self.class.required_params) end
signed_post_params(secret)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 163 def signed_post_params(secret) # The params will be used in an HTML form, and browsers will always use # newlines+carriage return line endings for submitted form data. The # signature needs to match, and signature generation does not add carriage # returns, so we ensure CRLF endings here. message_params = self.class.convert_param_values_to_crlf_endings(oauth_params.merge(post_params)) @message_authenticator = IMS::LTI::Services::MessageAuthenticator.new(launch_url, message_params, secret) @message_authenticator.signed_params end
to_jwt(private_key:, originating_domain:, algorithm: :HS256)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 207 def to_jwt(private_key:, originating_domain:, algorithm: :HS256) now = Time.now exp = now + 60 * 5 ims = unknown_params.merge(parameters) ims[:custom] = get_custom_params ims[:ext] = get_ext_params claim = { iss: originating_domain, sub: consumer_key, aud: launch_url, iat: now, exp: exp, jti: SecureRandom.uuid, "org.imsglobal.lti.message" => ims } jwt = JSON::JWT.new(claim).sign(private_key, algorithm) jwt.to_s end
Private Instance Methods
collect_attributes(attributes)
click to toggle source
# File lib/ims/lti/models/messages/message.rb, line 230 def collect_attributes(attributes) attributes.inject({}) do |h, param| value = instance_variable_get("@#{param}") h[param.to_s] = value if value h end end