ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
ilLTIToolProvider Class Reference

LTI provider for LTI launch. More...

+ Inheritance diagram for ilLTIToolProvider:
+ Collaboration diagram for ilLTIToolProvider:

Public Member Functions

 __construct (DataConnector $dataConnector)
 ilLTIToolProvider constructor. More...
 
 handleRequest ()
 Process an incoming request. More...
 

Data Fields

 $debugMode = true
 

Protected Member Functions

 onLaunch ()
 Process a valid launch request. More...
 
 onContentItem ()
 Process a valid content-item request. More...
 
 onRegister ()
 Process a valid tool proxy registration request. More...
 
 onError ()
 Process a response to an invalid request. More...
 

Protected Attributes

 $logger = null
 

Private Member Functions

 doCallback ($method=null)
 Call any callback function for the requested action. More...
 
 result ()
 Perform the result of an action. More...
 
 authenticate ()
 Check the authenticity of the LTI launch request. More...
 
 checkForShare ()
 Check if a share arrangement is in place. More...
 
 checkValue ($value, $values, $reason)
 Validate a parameter value from an array of permitted values. More...
 

Static Private Attributes

static $LTI_VERSIONS = array(self::LTI_VERSION1, self::LTI_VERSION2)
 Permitted LTI versions for messages. More...
 
static $MESSAGE_TYPES
 List of supported message types and associated class methods. More...
 
static $METHOD_NAMES
 List of supported message types and associated class methods. More...
 
static $LTI_CONSUMER_SETTING_NAMES = array('custom_tc_profile_url', 'custom_system_setting_url')
 Names of LTI parameters to be retained in the consumer settings property. More...
 
static $LTI_CONTEXT_SETTING_NAMES
 Names of LTI parameters to be retained in the context settings property. More...
 
static $LTI_RESOURCE_LINK_SETTING_NAMES
 Names of LTI parameters to be retained in the resource link settings property. More...
 
static $CUSTOM_SUBSTITUTION_VARIABLES
 Names of LTI custom parameter substitution variables (or capabilities) and their associated default message parameter names. More...
 

Detailed Description

Constructor & Destructor Documentation

◆ __construct()

ilLTIToolProvider::__construct ( DataConnector  $dataConnector)

ilLTIToolProvider constructor.

Parameters
DataConnector$dataConnector

Definition at line 122 of file class.ilLTIToolProvider.php.

References $DIC.

123  {
124  global $DIC;
125 
126  $this->logger = $DIC->logger()->lti();
127  parent::__construct($dataConnector);
128  }
global $DIC
Definition: saml.php:7

Member Function Documentation

◆ authenticate()

ilLTIToolProvider::authenticate ( )
private

Check the authenticity of the LTI launch request.

The consumer, resource link and user objects will be initialised if the request is valid.

Returns
boolean True if the request has been successfully validated.

foreach ($this->constraints as $name => $constraint) { if ($constraint['required']) { if (!in_array($name, $capabilities) && !in_array($name, array_flip($capabilities))) { $missing[$name] = true; } } } if (!empty($missing)) { ksort($missing); $this->reason = 'Required capability not offered - \'' . implode('\', \'', array_keys($missing)) . '\''; $this->ok = false; }

Definition at line 302 of file class.ilLTIToolProvider.php.

References $_POST, $consumer, $email, $format, $http, $message, $name, $ok, $res, $server, $service, $store, $title, $version, array, checkValue(), date, time, and user().

Referenced by handleRequest().

303  {
304 
305 // Get the consumer
306  $doSaveConsumer = false;
307  // Check all required launch parameters
308  $this->ok = isset($_POST['lti_message_type']) && array_key_exists($_POST['lti_message_type'], self::$MESSAGE_TYPES);
309  if (!$this->ok) {
310  $this->reason = 'Invalid or missing lti_message_type parameter.';
311  }
312  if ($this->ok) {
313  $this->ok = isset($_POST['lti_version']) && in_array($_POST['lti_version'], self::$LTI_VERSIONS);
314  if (!$this->ok) {
315  $this->reason = 'Invalid or missing lti_version parameter.';
316  }
317  }
318  if ($this->ok) {
319  if ($_POST['lti_message_type'] === 'basic-lti-launch-request') {
320  $this->ok = isset($_POST['resource_link_id']) && (strlen(trim($_POST['resource_link_id'])) > 0);
321  if (!$this->ok) {
322  $this->reason = 'Missing resource link ID.';
323  }
324  } elseif ($_POST['lti_message_type'] === 'ContentItemSelectionRequest') {
325  if (isset($_POST['accept_media_types']) && (strlen(trim($_POST['accept_media_types'])) > 0)) {
326  $mediaTypes = array_filter(explode(',', str_replace(' ', '', $_POST['accept_media_types'])), 'strlen');
327  $mediaTypes = array_unique($mediaTypes);
328  $this->ok = count($mediaTypes) > 0;
329  if (!$this->ok) {
330  $this->reason = 'No accept_media_types found.';
331  } else {
332  $this->mediaTypes = $mediaTypes;
333  }
334  } else {
335  $this->ok = false;
336  }
337  if ($this->ok && isset($_POST['accept_presentation_document_targets']) && (strlen(trim($_POST['accept_presentation_document_targets'])) > 0)) {
338  $documentTargets = array_filter(explode(',', str_replace(' ', '', $_POST['accept_presentation_document_targets'])), 'strlen');
339  $documentTargets = array_unique($documentTargets);
340  $this->ok = count($documentTargets) > 0;
341  if (!$this->ok) {
342  $this->reason = 'Missing or empty accept_presentation_document_targets parameter.';
343  } else {
344  foreach ($documentTargets as $documentTarget) {
345  $this->ok = $this->checkValue(
346  $documentTarget,
347  array('embed', 'frame', 'iframe', 'window', 'popup', 'overlay', 'none'),
348  'Invalid value in accept_presentation_document_targets parameter: %s.'
349  );
350  if (!$this->ok) {
351  break;
352  }
353  }
354  if ($this->ok) {
355  $this->documentTargets = $documentTargets;
356  }
357  }
358  } else {
359  $this->ok = false;
360  }
361  if ($this->ok) {
362  $this->ok = isset($_POST['content_item_return_url']) && (strlen(trim($_POST['content_item_return_url'])) > 0);
363  if (!$this->ok) {
364  $this->reason = 'Missing content_item_return_url parameter.';
365  }
366  }
367  } elseif ($_POST['lti_message_type'] == 'ToolProxyRegistrationRequest') {
368  $this->ok = ((isset($_POST['reg_key']) && (strlen(trim($_POST['reg_key'])) > 0)) &&
369  (isset($_POST['reg_password']) && (strlen(trim($_POST['reg_password'])) > 0)) &&
370  (isset($_POST['tc_profile_url']) && (strlen(trim($_POST['tc_profile_url'])) > 0)) &&
371  (isset($_POST['launch_presentation_return_url']) && (strlen(trim($_POST['launch_presentation_return_url'])) > 0)));
372  if ($this->debugMode && !$this->ok) {
373  $this->reason = 'Missing message parameters.';
374  }
375  }
376  }
377  $now = time();
378 
379  $this->logger->debug('Checking consumer key...');
380 
381  // Check consumer key
382  if ($this->ok && ($_POST['lti_message_type'] != 'ToolProxyRegistrationRequest')) {
383  $this->ok = isset($_POST['oauth_consumer_key']);
384  if (!$this->ok) {
385  $this->reason = 'Missing consumer key.';
386  }
387  if ($this->ok) {
388  // $this->consumer = new ToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
389  $this->consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
390  $this->ok = !is_null($this->consumer->created);
391  if (!$this->ok) {
392  $this->reason = 'Invalid consumer key.';
393  }
394  }
395  if ($this->ok) {
396  $today = date('Y-m-d', $now);
397  if (is_null($this->consumer->lastAccess)) {
398  $doSaveConsumer = true;
399  } else {
400  $last = date('Y-m-d', $this->consumer->lastAccess);
401  $doSaveConsumer = $doSaveConsumer || ($last !== $today);
402  }
403  $this->consumer->last_access = $now;
404  try {
405  $store = new OAuthDataStore($this);
406  $server = new OAuth\OAuthServer($store);
407  $method = new OAuth\OAuthSignatureMethod_HMAC_SHA1();
408  $server->add_signature_method($method);
409  $request = OAuth\OAuthRequest::from_request();
410  $res = $server->verify_request($request);
411  } catch (\Exception $e) {
412  $this->ok = false;
413  if (empty($this->reason)) {
414  if ($this->debugMode) {
415  $consumer = new OAuth\OAuthConsumer($this->consumer->getKey(), $this->consumer->secret);
416  $signature = $request->build_signature($method, $consumer, false);
417  $this->reason = $e->getMessage();
418  if (empty($this->reason)) {
419  $this->reason = 'OAuth exception';
420  }
421  $this->details[] = 'Timestamp: ' . time();
422  $this->details[] = "Signature: {$signature}";
423  $this->details[] = "Base string: {$request->base_string}]";
424  } else {
425  $this->reason = 'OAuth signature check failed - perhaps an incorrect secret or timestamp.';
426  }
427  }
428  }
429  }
430  // $this->ok = true; //ACHTUNG Problem Signature bei M.
431  if ($this->ok) {
432  $today = date('Y-m-d', $now);
433  if (is_null($this->consumer->lastAccess)) {
434  $doSaveConsumer = true;
435  } else {
436  $last = date('Y-m-d', $this->consumer->lastAccess);
437  $doSaveConsumer = $doSaveConsumer || ($last !== $today);
438  }
439  $this->consumer->last_access = $now;
440  if ($this->consumer->protected) {
441  if (!is_null($this->consumer->consumerGuid)) {
442  $this->ok = empty($_POST['tool_consumer_instance_guid']) ||
443  ($this->consumer->consumerGuid === $_POST['tool_consumer_instance_guid']);
444  if (!$this->ok) {
445  $this->reason = 'Request is from an invalid tool consumer.';
446  }
447  } else {
448  $this->ok = isset($_POST['tool_consumer_instance_guid']);
449  if (!$this->ok) {
450  $this->reason = 'A tool consumer GUID must be included in the launch request.';
451  }
452  }
453  }
454  if ($this->ok) {
455  $this->ok = $this->consumer->enabled;
456  if (!$this->ok) {
457  $this->reason = 'Tool consumer has not been enabled by the tool provider.';
458  }
459  }
460  if ($this->ok) {
461  $this->ok = is_null($this->consumer->enableFrom) || ($this->consumer->enableFrom <= $now);
462  if ($this->ok) {
463  $this->ok = is_null($this->consumer->enableUntil) || ($this->consumer->enableUntil > $now);
464  if (!$this->ok) {
465  $this->reason = 'Tool consumer access has expired.';
466  }
467  } else {
468  $this->reason = 'Tool consumer access is not yet available.';
469  }
470  }
471  }
472  // Validate other message parameter values
473  if ($this->ok) {
474  if ($_POST['lti_message_type'] === 'ContentItemSelectionRequest') {
475  if (isset($_POST['accept_unsigned'])) {
476  $this->ok = $this->checkValue($_POST['accept_unsigned'], array('true', 'false'), 'Invalid value for accept_unsigned parameter: %s.');
477  }
478  if ($this->ok && isset($_POST['accept_multiple'])) {
479  $this->ok = $this->checkValue($_POST['accept_multiple'], array('true', 'false'), 'Invalid value for accept_multiple parameter: %s.');
480  }
481  if ($this->ok && isset($_POST['accept_copy_advice'])) {
482  $this->ok = $this->checkValue($_POST['accept_copy_advice'], array('true', 'false'), 'Invalid value for accept_copy_advice parameter: %s.');
483  }
484  if ($this->ok && isset($_POST['auto_create'])) {
485  $this->ok = $this->checkValue($_POST['auto_create'], array('true', 'false'), 'Invalid value for auto_create parameter: %s.');
486  }
487  if ($this->ok && isset($_POST['can_confirm'])) {
488  $this->ok = $this->checkValue($_POST['can_confirm'], array('true', 'false'), 'Invalid value for can_confirm parameter: %s.');
489  }
490  } elseif (isset($_POST['launch_presentation_document_target'])) {
491  $this->ok = $this->checkValue(
492  $_POST['launch_presentation_document_target'],
493  array('embed', 'frame', 'iframe', 'window', 'popup', 'overlay'),
494  'Invalid value for launch_presentation_document_target parameter: %s.'
495  );
496  }
497  }
498  }
499 
500  if ($this->ok && ($_POST['lti_message_type'] === 'ToolProxyRegistrationRequest')) {
501  $this->ok = $_POST['lti_version'] == self::LTI_VERSION2;
502  if (!$this->ok) {
503  $this->reason = 'Invalid lti_version parameter';
504  }
505  if ($this->ok) {
506  $http = new HTTPMessage($_POST['tc_profile_url'], 'GET', null, 'Accept: application/vnd.ims.lti.v2.toolconsumerprofile+json');
507  $this->ok = $http->send();
508  if (!$this->ok) {
509  $this->reason = 'Tool consumer profile not accessible.';
510  } else {
511  $tcProfile = json_decode($http->response);
512  $this->ok = !is_null($tcProfile);
513  if (!$this->ok) {
514  $this->reason = 'Invalid JSON in tool consumer profile.';
515  }
516  }
517  }
518  // Check for required capabilities
519  if ($this->ok) {
520  // $this->consumer = new ToolConsumer($_POST['reg_key'], $this->dataConnector);
521  $this->consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
522  $this->consumer->profile = $tcProfile;
523  $capabilities = $this->consumer->profile->capability_offered;
524  $missing = array();
525  foreach ($this->resourceHandlers as $resourceHandler) {
526  foreach ($resourceHandler->requiredMessages as $message) {
527  if (!in_array($message->type, $capabilities)) {
528  $missing[$message->type] = true;
529  }
530  }
531  }
532  // smeyer: 21 Nov 2018 constraints are not supported in the moment and private in the base class.
547  }
548  // Check for required services
549  if ($this->ok) {
550  foreach ($this->requiredServices as $service) {
551  foreach ($service->formats as $format) {
552  if (!$this->findService($format, $service->actions)) {
553  if ($this->ok) {
554  $this->reason = 'Required service(s) not offered - ';
555  $this->ok = false;
556  } else {
557  $this->reason .= ', ';
558  }
559  $this->reason .= "'{$format}' [" . implode(', ', $service->actions) . ']';
560  }
561  }
562  }
563  }
564  if ($this->ok) {
565  if ($_POST['lti_message_type'] === 'ToolProxyRegistrationRequest') {
566  $this->consumer->profile = $tcProfile;
567  $this->consumer->secret = $_POST['reg_password'];
568  $this->consumer->ltiVersion = $_POST['lti_version'];
569  $this->consumer->name = $tcProfile->product_instance->service_owner->service_owner_name->default_value;
570  $this->consumer->consumerName = $this->consumer->name;
571  $this->consumer->consumerVersion = "{$tcProfile->product_instance->product_info->product_family->code}-{$tcProfile->product_instance->product_info->product_version}";
572  $this->consumer->consumerGuid = $tcProfile->product_instance->guid;
573  $this->consumer->enabled = true;
574  $this->consumer->protected = true;
575  $doSaveConsumer = true;
576  }
577  }
578  } elseif ($this->ok && !empty($_POST['custom_tc_profile_url']) && empty($this->consumer->profile)) {
579  $http = new HTTPMessage($_POST['custom_tc_profile_url'], 'GET', null, 'Accept: application/vnd.ims.lti.v2.toolconsumerprofile+json');
580  if ($http->send()) {
581  $tcProfile = json_decode($http->response);
582  if (!is_null($tcProfile)) {
583  $this->consumer->profile = $tcProfile;
584  $doSaveConsumer = true;
585  }
586  }
587  }
588  //ACHTUNG HIER TODO UWE
589  // Validate message parameter constraints
590  // if ($this->ok) {
591  // $invalidParameters = array();
592  // foreach ($this->constraints as $name => $constraint) {
593  // // if (empty($constraint['messages']) || in_array($_POST['lti_message_type'], $constraint['messages'])) {
594  // // $ok = true;
595  // // if ($constraint['required']) {
596  // // if (!isset($_POST[$name]) || (strlen(trim($_POST[$name])) <= 0)) {
597  // // $invalidParameters[] = "{$name} (missing)";
598  // // $ok = false;
599  // // }
600  // // }
601  // // if ($ok && !is_null($constraint['max_length']) && isset($_POST[$name])) {
602  // // if (strlen(trim($_POST[$name])) > $constraint['max_length']) {
603  // // $invalidParameters[] = "{$name} (too long)";
604  // // }
605  // // }
606  // // }
607  // }
608  // if (count($invalidParameters) > 0) {
609  // $this->ok = false;
610  // if (empty($this->reason)) {
611  // $this->reason = 'Invalid parameter(s): ' . implode(', ', $invalidParameters) . '.';
612  // }
613  // }
614  // }
615 
616  $this->logger->debug('Still ok: ' . ($this->ok ? '1' : '0'));
617  if (!$this->ok) {
618  $this->logger->debug('Reason: ' . $this->reason);
619  }
620 
621  if ($this->ok) {
622 
623 // Set the request context
624  if (isset($_POST['context_id'])) {
625  $this->context = Context::fromConsumer($this->consumer, trim($_POST['context_id']));
626  $title = '';
627  if (isset($_POST['context_title'])) {
628  $title = trim($_POST['context_title']);
629  }
630  if (empty($title)) {
631  $title = "Course {$this->context->getId()}";
632  }
633  $this->context->title = $title;
634  }
635 
636  // Set the request resource link
637  if (isset($_POST['resource_link_id'])) {
638  $contentItemId = '';
639  if (isset($_POST['custom_content_item_id'])) {
640  $contentItemId = $_POST['custom_content_item_id'];
641  }
642  $this->resourceLink = ResourceLink::fromConsumer($this->consumer, trim($_POST['resource_link_id']), $contentItemId);
643  if (!empty($this->context)) {
644  $this->resourceLink->setContextId($this->context->getRecordId());
645  }
646  $title = '';
647  if (isset($_POST['resource_link_title'])) {
648  $title = trim($_POST['resource_link_title']);
649  }
650  if (empty($title)) {
651  $title = "Resource {$this->resourceLink->getId()}";
652  }
653  $this->resourceLink->title = $title;
654  // Delete any existing custom parameters
655  foreach ($this->consumer->getSettings() as $name => $value) {
656  if (strpos($name, 'custom_') === 0) {
657  $this->consumer->setSetting($name);
658  $doSaveConsumer = true;
659  }
660  }
661  if (!empty($this->context)) {
662  foreach ($this->context->getSettings() as $name => $value) {
663  if (strpos($name, 'custom_') === 0) {
664  $this->context->setSetting($name);
665  }
666  }
667  }
668  foreach ($this->resourceLink->getSettings() as $name => $value) {
669  if (strpos($name, 'custom_') === 0) {
670  $this->resourceLink->setSetting($name);
671  }
672  }
673  // Save LTI parameters
674  foreach (self::$LTI_CONSUMER_SETTING_NAMES as $name) {
675  if (isset($_POST[$name])) {
676  $this->consumer->setSetting($name, $_POST[$name]);
677  } else {
678  $this->consumer->setSetting($name);
679  }
680  }
681  if (!empty($this->context)) {
682  foreach (self::$LTI_CONTEXT_SETTING_NAMES as $name) {
683  if (isset($_POST[$name])) {
684  $this->context->setSetting($name, $_POST[$name]);
685  } else {
686  $this->context->setSetting($name);
687  }
688  }
689  }
690  foreach (self::$LTI_RESOURCE_LINK_SETTING_NAMES as $name) {
691  if (isset($_POST[$name])) {
692  $this->resourceLink->setSetting($name, $_POST[$name]);
693  } else {
694  $this->resourceLink->setSetting($name);
695  }
696  }
697  // Save other custom parameters
698  foreach ($_POST as $name => $value) {
699  if ((strpos($name, 'custom_') === 0) &&
700  !in_array($name, array_merge(self::$LTI_CONSUMER_SETTING_NAMES, self::$LTI_CONTEXT_SETTING_NAMES, self::$LTI_RESOURCE_LINK_SETTING_NAMES))) {
701  $this->resourceLink->setSetting($name, $value);
702  }
703  }
704  }
705 
706  // Set the user instance
707  $userId = '';
708  if (isset($_POST['user_id'])) {
709  $userId = trim($_POST['user_id']);
710  }
711 
712  $this->user = User::fromResourceLink($this->resourceLink, $userId);
713 
714  // Set the user name
715  $firstname = (isset($_POST['lis_person_name_given'])) ? $_POST['lis_person_name_given'] : '';
716  $lastname = (isset($_POST['lis_person_name_family'])) ? $_POST['lis_person_name_family'] : '';
717  $fullname = (isset($_POST['lis_person_name_full'])) ? $_POST['lis_person_name_full'] : '';
718  $this->user->setNames($firstname, $lastname, $fullname);
719 
720  // Set the user email
721  $email = (isset($_POST['lis_person_contact_email_primary'])) ? $_POST['lis_person_contact_email_primary'] : '';
722  $this->user->setEmail($email, $this->defaultEmail);
723 
724  // Set the user image URI
725  if (isset($_POST['user_image'])) {
726  $this->user->image = $_POST['user_image'];
727  }
728 
729  // Set the user roles
730  if (isset($_POST['roles'])) {
731  $this->user->roles = self::parseRoles($_POST['roles']);
732  }
733 
734  // Initialise the consumer and check for changes
735  $this->consumer->defaultEmail = $this->defaultEmail;
736  if ($this->consumer->ltiVersion !== $_POST['lti_version']) {
737  $this->consumer->ltiVersion = $_POST['lti_version'];
738  $doSaveConsumer = true;
739  }
740  if (isset($_POST['tool_consumer_instance_name'])) {
741  if ($this->consumer->consumerName !== $_POST['tool_consumer_instance_name']) {
742  $this->consumer->consumerName = $_POST['tool_consumer_instance_name'];
743  $doSaveConsumer = true;
744  }
745  }
746  if (isset($_POST['tool_consumer_info_product_family_code'])) {
747  $version = $_POST['tool_consumer_info_product_family_code'];
748  if (isset($_POST['tool_consumer_info_version'])) {
749  $version .= "-{$_POST['tool_consumer_info_version']}";
750  }
751  // do not delete any existing consumer version if none is passed
752  if ($this->consumer->consumerVersion !== $version) {
753  $this->consumer->consumerVersion = $version;
754  $doSaveConsumer = true;
755  }
756  } elseif (isset($_POST['ext_lms']) && ($this->consumer->consumerName !== $_POST['ext_lms'])) {
757  $this->consumer->consumerVersion = $_POST['ext_lms'];
758  $doSaveConsumer = true;
759  }
760  if (isset($_POST['tool_consumer_instance_guid'])) {
761  if (is_null($this->consumer->consumerGuid)) {
762  $this->consumer->consumerGuid = $_POST['tool_consumer_instance_guid'];
763  $doSaveConsumer = true;
764  } elseif (!$this->consumer->protected) {
765  $doSaveConsumer = ($this->consumer->consumerGuid !== $_POST['tool_consumer_instance_guid']);
766  if ($doSaveConsumer) {
767  $this->consumer->consumerGuid = $_POST['tool_consumer_instance_guid'];
768  }
769  }
770  }
771  if (isset($_POST['launch_presentation_css_url'])) {
772  if ($this->consumer->cssPath !== $_POST['launch_presentation_css_url']) {
773  $this->consumer->cssPath = $_POST['launch_presentation_css_url'];
774  $doSaveConsumer = true;
775  }
776  } elseif (isset($_POST['ext_launch_presentation_css_url']) &&
777  ($this->consumer->cssPath !== $_POST['ext_launch_presentation_css_url'])) {
778  $this->consumer->cssPath = $_POST['ext_launch_presentation_css_url'];
779  $doSaveConsumer = true;
780  } elseif (!empty($this->consumer->cssPath)) {
781  $this->consumer->cssPath = null;
782  $doSaveConsumer = true;
783  }
784  }
785 
786  // Persist changes to consumer
787  if ($doSaveConsumer) {
788  $this->consumer->save();
789  }
790  if ($this->ok && isset($this->context)) {
791  $this->context->save();//ACHTUNG TODO UWE
792  }
793 
794  $this->logger->dump(get_class($this->context));
795 
796 
797  if ($this->ok && isset($this->resourceLink)) {
798 
799 // Check if a share arrangement is in place for this resource link
800  // $this->ok = $this->checkForShare();//ACHTUNG TODO UWE
801  // Persist changes to resource link
802  $this->resourceLink->save();
803 
804  // Save the user instance
805  if (isset($_POST['lis_result_sourcedid'])) {
806  if ($this->user->ltiResultSourcedId !== $_POST['lis_result_sourcedid']) {
807  $this->user->ltiResultSourcedId = $_POST['lis_result_sourcedid'];
808  $this->user->save();
809  }
810  } elseif (!empty($this->user->ltiResultSourcedId)) {
811  $this->user->ltiResultSourcedId = '';
812  $this->user->save();
813  }
814  }
815  // die ($this->reason.'---'.$this->ok);//ACHTUNG WEG!
816  return $this->ok;
817  }
if($orgName !==null) if($spconfig->hasValue('contacts')) $email
Definition: metadata.php:193
$format
Definition: metadata.php:141
Class to represent an OAuth Data Store.
checkValue($value, $values, $reason)
Validate a parameter value from an array of permitted values.
LTI provider for LTI launch.
$service
Definition: login.php:15
if(! $oauthconfig->getBoolean('getUserInfo.enable', FALSE)) $store
Definition: getUserInfo.php:11
user()
Definition: user.php:4
if($format !==null) $name
Definition: metadata.php:146
catch(Exception $e) $message
foreach($_POST as $key=> $value) $res
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$http
Definition: raiseError.php:7
$consumer
Definition: demo.php:30
Create styles array
The data for the language used.
$server
Definition: getUserInfo.php:12
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
$_POST["username"]
Class to represent an HTTP message.
Definition: HTTPMessage.php:14
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkForShare()

ilLTIToolProvider::checkForShare ( )
private

Check if a share arrangement is in place.

Returns
boolean True if no error is reported

Definition at line 824 of file class.ilLTIToolProvider.php.

References $_POST, $consumer, $id, $key, $ok, time, and user().

825  {
826  $ok = true;
827  $doSaveResourceLink = true;
828 
829  $id = $this->resourceLink->primaryResourceLinkId;
830 
831  $shareRequest = isset($_POST['custom_share_key']) && !empty($_POST['custom_share_key']);
832  if ($shareRequest) {
833  if (!$this->allowSharing) {
834  $ok = false;
835  $this->reason = 'Your sharing request has been refused because sharing is not being permitted.';
836  } else {
837  // Check if this is a new share key
838  $shareKey = new ResourceLinkShareKey($this->resourceLink, $_POST['custom_share_key']);
839  if (!is_null($shareKey->primaryConsumerKey) && !is_null($shareKey->primaryResourceLinkId)) {
840  // Update resource link with sharing primary resource link details
841  $key = $shareKey->primaryConsumerKey;
842  $id = $shareKey->primaryResourceLinkId;
843  $ok = ($key !== $this->consumer->getKey()) || ($id != $this->resourceLink->getId());
844  if ($ok) {
845  $this->resourceLink->primaryConsumerKey = $key;
846  $this->resourceLink->primaryResourceLinkId = $id;
847  $this->resourceLink->shareApproved = $shareKey->autoApprove;
848  $ok = $this->resourceLink->save();
849  if ($ok) {
850  $doSaveResourceLink = false;
851  $this->user->getResourceLink()->primaryConsumerKey = $key;
852  $this->user->getResourceLink()->primaryResourceLinkId = $id;
853  $this->user->getResourceLink()->shareApproved = $shareKey->autoApprove;
854  $this->user->getResourceLink()->updated = time();
855  // Remove share key
856  $shareKey->delete();
857  } else {
858  $this->reason = 'An error occurred initialising your share arrangement.';
859  }
860  } else {
861  $this->reason = 'It is not possible to share your resource link with yourself.';
862  }
863  }
864  if ($ok) {
865  $ok = !is_null($key);
866  if (!$ok) {
867  $this->reason = 'You have requested to share a resource link but none is available.';
868  } else {
869  $ok = (!is_null($this->user->getResourceLink()->shareApproved) && $this->user->getResourceLink()->shareApproved);
870  if (!$ok) {
871  $this->reason = 'Your share request is waiting to be approved.';
872  }
873  }
874  }
875  }
876  } else {
877  // Check no share is in place
878  $ok = is_null($id);
879  if (!$ok) {
880  $this->reason = 'You have not requested to share a resource link but an arrangement is currently in place.';
881  }
882  }
883  // Look up primary resource link
884  if ($ok && !is_null($id)) {
885  // $consumer = new ToolConsumer($key, $this->dataConnector);
886  $consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
887  $ok = !is_null($consumer->created);
888  if ($ok) {
889  $resourceLink = ResourceLink::fromConsumer($consumer, $id);
890  $ok = !is_null($resourceLink->created);
891  }
892  if ($ok) {
893  if ($doSaveResourceLink) {
894  $this->resourceLink->save();
895  }
896  $this->resourceLink = $resourceLink;
897  } else {
898  $this->reason = 'Unable to load resource link being shared.';
899  }
900  }
901 
902  return $ok;
903  }
LTI provider for LTI launch.
if(!array_key_exists('StateId', $_REQUEST)) $id
user()
Definition: user.php:4
Class to represent a tool consumer resource link share key.
$consumer
Definition: demo.php:30
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
$key
Definition: croninfo.php:18
$_POST["username"]
+ Here is the call graph for this function:

◆ checkValue()

ilLTIToolProvider::checkValue (   $value,
  $values,
  $reason 
)
private

Validate a parameter value from an array of permitted values.

Returns
boolean True if value is valid

Definition at line 909 of file class.ilLTIToolProvider.php.

References $ok.

Referenced by authenticate().

910  {
911  $ok = in_array($value, $values);
912  if (!$ok && !empty($reason)) {
913  $this->reason = sprintf($reason, $value);
914  }
915 
916  return $ok;
917  }
+ Here is the caller graph for this function:

◆ doCallback()

ilLTIToolProvider::doCallback (   $method = null)
private

Call any callback function for the requested action.

This function may set the redirect_url and output properties.

Returns
boolean True if no error reported

Definition at line 216 of file class.ilLTIToolProvider.php.

References $_POST, and $result.

Referenced by handleRequest().

217  {
218  $callback = $method;
219  if (is_null($callback)) {
220  $callback = self::$METHOD_NAMES[$_POST['lti_message_type']];
221  }
222  if (method_exists($this, $callback)) {
223  $result = $this->$callback(); // ACHTUNG HIER PROBLEM UK
224  } elseif (is_null($method) && $this->ok) {
225  $this->ok = false;
226  $this->reason = "Message type not supported: {$_POST['lti_message_type']}";
227  }
228  if ($this->ok && ($_POST['lti_message_type'] == 'ToolProxyRegistrationRequest')) {
229  $this->consumer->save();
230  }
231  }
$result
$_POST["username"]
+ Here is the caller graph for this function:

◆ handleRequest()

ilLTIToolProvider::handleRequest ( )

Process an incoming request.

Definition at line 134 of file class.ilLTIToolProvider.php.

References $ok, authenticate(), doCallback(), and result().

135  {
136  if ($this->ok) {
137  if ($this->authenticate()) {
138  $this->doCallback();
139  }
140  }
141  // if return url is given, this redirects in case of errors
142  $this->result();
143  return $this->ok;
144  }
authenticate()
Check the authenticity of the LTI launch request.
result()
Perform the result of an action.
doCallback($method=null)
Call any callback function for the requested action.
+ Here is the call graph for this function:

◆ onContentItem()

ilLTIToolProvider::onContentItem ( )
protected

Process a valid content-item request.

Returns
boolean True if no error

Definition at line 176 of file class.ilLTIToolProvider.php.

References onError().

177  {
178  $this->onError();
179  }
onError()
Process a response to an invalid request.
+ Here is the call graph for this function:

◆ onError()

ilLTIToolProvider::onError ( )
protected

Process a response to an invalid request.

Returns
boolean True if no further error processing required

Definition at line 196 of file class.ilLTIToolProvider.php.

References $ok.

Referenced by onContentItem(), onRegister(), and result().

197  {
198  // only return error status
199  return $this->ok;
200 
201  //$this->doCallback('onError');
202  // return parent::onError(); //Stefan M.
203  }
+ Here is the caller graph for this function:

◆ onLaunch()

ilLTIToolProvider::onLaunch ( )
protected

Process a valid launch request.

Returns
boolean True if no error

Definition at line 155 of file class.ilLTIToolProvider.php.

References user().

156  {
157  // save/update current user
158  if ($this->user instanceof User) {
159  $this->user->save();
160  }
161 
162  if ($this->context instanceof Context) {
163  $this->context->save();
164  }
165 
166  if ($this->resourceLink instanceof ResourceLink) {
167  $this->resourceLink->save();
168  }
169  }
user()
Definition: user.php:4
Class to represent a tool consumer context.
Definition: Context.php:17
Class to represent a tool consumer user.
Definition: User.php:15
+ Here is the call graph for this function:

◆ onRegister()

ilLTIToolProvider::onRegister ( )
protected

Process a valid tool proxy registration request.

Returns
boolean True if no error

Definition at line 186 of file class.ilLTIToolProvider.php.

References onError().

187  {
188  $this->onError();
189  }
onError()
Process a response to an invalid request.
+ Here is the call graph for this function:

◆ result()

ilLTIToolProvider::result ( )
private

Perform the result of an action.

This function may redirect the user to another URL rather than returning a value.

Returns
string Output to be displayed (redirection, or display HTML or message)

Definition at line 240 of file class.ilLTIToolProvider.php.

References $_POST, $ok, $output, $version, array, exit, header, and onError().

Referenced by handleRequest().

241  {
242  $ok = false;
243  if (!$this->ok) {
244  $ok = $this->onError();
245  }
246  if (!$ok) {
247  if (!$this->ok) {
248  // If not valid, return an error message to the tool consumer if a return URL is provided
249  if (!empty($this->returnUrl)) {
250  $errorUrl = $this->returnUrl;
251  if (strpos($errorUrl, '?') === false) {
252  $errorUrl .= '?';
253  } else {
254  $errorUrl .= '&';
255  }
256  if ($this->debugMode && !is_null($this->reason)) {
257  $errorUrl .= 'lti_errormsg=' . urlencode("Debug error: $this->reason");
258  } else {
259  $errorUrl .= 'lti_errormsg=' . urlencode($this->message);
260  if (!is_null($this->reason)) {
261  $errorUrl .= '&lti_errorlog=' . urlencode("Debug error: $this->reason");
262  }
263  }
264  if (!is_null($this->consumer) && isset($_POST['lti_message_type']) && ($_POST['lti_message_type'] === 'ContentItemSelectionRequest')) {
265  $formParams = array();
266  if (isset($_POST['data'])) {
267  $formParams['data'] = $_POST['data'];
268  }
269  $version = (isset($_POST['lti_version'])) ? $_POST['lti_version'] : self::LTI_VERSION1;
270  $formParams = $this->consumer->signParameters($errorUrl, 'ContentItemSelection', $version, $formParams);
271  $page = self::sendForm($errorUrl, $formParams);
272  echo $page;
273  } else {
274  header("Location: {$errorUrl}");
275  }
276  exit; //ACHTUNG HIER PROBLEM UK
277  } else {
278  if (!is_null($this->errorOutput)) {
279  echo $this->errorOutput;
280  } elseif ($this->debugMode && !empty($this->reason)) {
281  echo "Debug error: {$this->reason}";
282  } else {
283  echo "Error: {$this->message}";
284  }
285  }
286  } elseif (!is_null($this->redirectUrl)) {
287  header("Location: {$this->redirectUrl}");
288  exit;
289  } elseif (!is_null($this->output)) {
290  echo $this->output;
291  }
292  }
293  }
onError()
Process a response to an invalid request.
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
Add a drawing to the header
Definition: 04printing.php:69
Create styles array
The data for the language used.
$_POST["username"]
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $CUSTOM_SUBSTITUTION_VARIABLES

array ilLTIToolProvider::$CUSTOM_SUBSTITUTION_VARIABLES
staticprivate

Names of LTI custom parameter substitution variables (or capabilities) and their associated default message parameter names.

Definition at line 83 of file class.ilLTIToolProvider.php.

◆ $debugMode

ilLTIToolProvider::$debugMode = true

Definition at line 34 of file class.ilLTIToolProvider.php.

◆ $logger

ilLTIToolProvider::$logger = null
protected

Definition at line 31 of file class.ilLTIToolProvider.php.

◆ $LTI_CONSUMER_SETTING_NAMES

array ilLTIToolProvider::$LTI_CONSUMER_SETTING_NAMES = array('custom_tc_profile_url', 'custom_system_setting_url')
staticprivate

Names of LTI parameters to be retained in the consumer settings property.

Definition at line 58 of file class.ilLTIToolProvider.php.

◆ $LTI_CONTEXT_SETTING_NAMES

array ilLTIToolProvider::$LTI_CONTEXT_SETTING_NAMES
staticprivate
Initial value:
= array('custom_context_setting_url',
'custom_lineitems_url', 'custom_results_url',
'custom_context_memberships_url')

Names of LTI parameters to be retained in the context settings property.

Definition at line 64 of file class.ilLTIToolProvider.php.

◆ $LTI_RESOURCE_LINK_SETTING_NAMES

array ilLTIToolProvider::$LTI_RESOURCE_LINK_SETTING_NAMES
staticprivate
Initial value:
= array('lis_result_sourcedid', 'lis_outcome_service_url',
'ext_ims_lis_basic_outcome_url', 'ext_ims_lis_resultvalue_sourcedids',
'ext_ims_lis_memberships_id', 'ext_ims_lis_memberships_url',
'ext_ims_lti_tool_setting', 'ext_ims_lti_tool_setting_id', 'ext_ims_lti_tool_setting_url',
'custom_link_setting_url',
'custom_lineitem_url', 'custom_result_url')

Names of LTI parameters to be retained in the resource link settings property.

Definition at line 72 of file class.ilLTIToolProvider.php.

◆ $LTI_VERSIONS

ilLTIToolProvider::$LTI_VERSIONS = array(self::LTI_VERSION1, self::LTI_VERSION2)
staticprivate

Permitted LTI versions for messages.

Definition at line 38 of file class.ilLTIToolProvider.php.

◆ $MESSAGE_TYPES

ilLTIToolProvider::$MESSAGE_TYPES
staticprivate
Initial value:
= array('basic-lti-launch-request' => 'onLaunch',
'ContentItemSelectionRequest' => 'onContentItem',
'ToolProxyRegistrationRequest' => 'register')

List of supported message types and associated class methods.

Definition at line 42 of file class.ilLTIToolProvider.php.

◆ $METHOD_NAMES

array ilLTIToolProvider::$METHOD_NAMES
staticprivate
Initial value:
= array('basic-lti-launch-request' => 'onLaunch',
'ContentItemSelectionRequest' => 'onContentItem',
'ToolProxyRegistrationRequest' => 'onRegister')

List of supported message types and associated class methods.

Definition at line 50 of file class.ilLTIToolProvider.php.


The documentation for this class was generated from the following file: