diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/classes/LTI13a/PlatformManager.php | 22 | ||||
| -rw-r--r-- | lib/classes/LTI13a/Registration.php | 43 | ||||
| -rw-r--r-- | lib/classes/LTI13a/RegistrationManager.php | 21 | ||||
| -rw-r--r-- | lib/models/LtiDeployment.php | 34 | ||||
| -rw-r--r-- | lib/models/LtiGrade.php | 3 | ||||
| -rw-r--r-- | lib/models/LtiResourceLink.php | 51 |
6 files changed, 124 insertions, 50 deletions
diff --git a/lib/classes/LTI13a/PlatformManager.php b/lib/classes/LTI13a/PlatformManager.php index 10c7cb1..9017267 100644 --- a/lib/classes/LTI13a/PlatformManager.php +++ b/lib/classes/LTI13a/PlatformManager.php @@ -31,17 +31,20 @@ class PlatformManager * Generates an object containing the settings for using this Stud.IP * as a platform that connects to an LTI tool via Deep Linking. * - * @param string $tool_id An optional LTI tool ID that is used to construct + * @param string $link_id The Stud.IP LTI Resource Link ID that is used to construct * the platform return URL. * + * @param string $course_id An optional Stud.IP course for which to get + * the deep linking configuration. + * * @return DeepLinkingSettings The settings for deep linking. */ - public static function getDeepLinkingConfiguration(string $tool_id = '') : DeepLinkingSettings + public static function getDeepLinkingConfiguration(string $link_id, string $course_id = '') : DeepLinkingSettings { $c = \Config::get(); return new DeepLinkingSettings( - self::getDeepLinkingReturnUrl($tool_id), + self::getDeepLinkingReturnUrl($link_id, $course_id), [LtiResourceLinkInterface::TYPE], ['window', 'iframe'], 'text/html', @@ -85,13 +88,20 @@ class PlatformManager /** * Generates the URL for returning from the tool in an LTI deep linking process. * - * @param string $tool_id The optional LTI Tool-ID to append to the URL. + * @param string $link_id The Stud.IP LTI Resource Link ID to append to the URL. + * + * @param string $course_id An optional Stud.IP course for which to generate + * the deep linking return URL. * * @return string The URL for returning from an LTI deep linking process. */ - public static function getDeepLinkingReturnUrl(string $tool_id = '') : string + public static function getDeepLinkingReturnUrl(string $link_id, string $course_id = '') : string { - return \URLHelper::getURL('dispatch.php/course/lti/save_link/' . $tool_id, null, true); + $params = ['link_id' => $link_id]; + if ($course_id) { + $params['cid'] = $course_id; + } + return \URLHelper::getURL('dispatch.php/course/lti/save_link/' . $link_id, $params, true); } /** diff --git a/lib/classes/LTI13a/Registration.php b/lib/classes/LTI13a/Registration.php index c4b898f..5498ace 100644 --- a/lib/classes/LTI13a/Registration.php +++ b/lib/classes/LTI13a/Registration.php @@ -2,6 +2,7 @@ namespace Studip\LTI13a; +use OAT\Library\Lti1p3Core\Exception\LtiException; use OAT\Library\Lti1p3Core\Registration\RegistrationInterface; use OAT\Library\Lti1p3Core\Tool\ToolInterface; use OAT\Library\Lti1p3Core\Platform\PlatformInterface; @@ -10,7 +11,8 @@ use OAT\Library\Lti1p3Core\Security\Key\KeyChainInterface; class Registration implements RegistrationInterface { public function __construct( - protected ?\LtiTool $tool + protected ?\LtiTool $tool, + protected ?\LtiResourceLink $link = null ) { } @@ -24,13 +26,27 @@ class Registration implements RegistrationInterface return $this->tool; } + public function setLtiResourceLink(\LtiResourceLink $link) + { + $this->link = $link; + } + + public function getLtiResourceLink() : ?\LtiResourceLink + { + return $this->link; + } + #[\Override] public function getIdentifier(): string { if (!$this->tool) { return ''; } - return $this->tool->id; + if ($this->link) { + return $this->tool->id . '_' . $this->link->id; + } else { + return $this->tool->id; + } } #[\Override] @@ -63,7 +79,11 @@ class Registration implements RegistrationInterface if (!$this->tool) { return []; } - return \DBManager::get()->fetchFirst("SELECT `id` FROM `lti_deployments` WHERE `tool_id` = ?", [$this->tool->id]); + if ($this->link) { + return [$this->link->deployment_id]; + } else { + return \DBManager::get()->fetchFirst("SELECT `id` FROM `lti_deployments` WHERE `tool_id` = ?", [$this->tool->id]); + } } #[\Override] @@ -72,10 +92,14 @@ class Registration implements RegistrationInterface if (!$this->tool) { return false; } - return \LtiDeployment::countBySql( - "`tool_id` = :tool_id AND `id` = :deployment_id", - ['tool_id' => $this->tool->id, 'deployment_id' => $deploymentId] - ) > 0; + if ($this->link) { + return $this->link->deployment_id == $deploymentId; + } else { + return \LtiDeployment::countBySql( + "`tool_id` = :tool_id AND `id` = :deployment_id", + ['tool_id' => $this->tool->id, 'deployment_id' => $deploymentId] + ) > 0; + } } #[\Override] @@ -98,12 +122,13 @@ class Registration implements RegistrationInterface #[\Override] public function getToolKeyChain(): ?KeyChainInterface { - if (!$this->tool) { + if (!$this->tool || $this->tool->jwks_url) { return null; } + $keyring = $this->tool->getKeyring(); if (!$keyring) { - $keyring = $this->tool->getKeyring(true); + throw new LtiException('Failed to load public key for tool ' . $this->tool->id); } return $keyring->toKeyChain(); } diff --git a/lib/classes/LTI13a/RegistrationManager.php b/lib/classes/LTI13a/RegistrationManager.php index 922cb58..05bcc2e 100644 --- a/lib/classes/LTI13a/RegistrationManager.php +++ b/lib/classes/LTI13a/RegistrationManager.php @@ -7,15 +7,29 @@ use OAT\Library\Lti1p3Core\Registration\RegistrationInterface; class RegistrationManager implements RegistrationRepositoryInterface { + protected ?\LtiResourceLink $link = null; + + public function setResourceLink(\LtiResourceLink $link) + { + $this->link = $link; + } + #[\Override] public function find(string $identifier): ?RegistrationInterface { //The identifier is the ID of a tool. $tool = \LtiTool::find($identifier); + $link = null; + if (!$tool) { + //Attempt to find the tool and a resource link. + $id_parts = explode('_', $identifier); + $tool = \LtiTool::find($id_parts[0]); + $link = \LtiResourceLink::find($id_parts[1]); + } if (!$tool) { return null; } - return new Registration($tool); + return new Registration($tool, $link); } /** @@ -42,7 +56,7 @@ class RegistrationManager implements RegistrationRepositoryInterface } $tool = \LtiTool::find($clientId); if ($tool) { - return new Registration($tool); + return new Registration($tool, $this->link); } return null; } @@ -51,7 +65,8 @@ class RegistrationManager implements RegistrationRepositoryInterface public function findByPlatformIssuer(string $issuer, string $clientId = null): ?RegistrationInterface { //Only handle requests for registrations of this Stud.IP: - if ($issuer !== \Config::get()->STUDIP_INSTALLATION_ID) { + $platform_config = \Studip\LTI13a\PlatformManager::getPlatformConfiguration(); + if ($issuer !== $platform_config->getAudience()) { //Invalid issuer. return null; } diff --git a/lib/models/LtiDeployment.php b/lib/models/LtiDeployment.php index e59e738..86f18a0 100644 --- a/lib/models/LtiDeployment.php +++ b/lib/models/LtiDeployment.php @@ -12,15 +12,10 @@ * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2 * * @property int $id database column - * @property string $title database column - * @property string $description database column * @property int $tool_id database column - * @property string $launch_url database column * @property int $mkdate database column * @property int $chdate database column - * @property JSONArrayObject|null $options database column * @property SimpleORMapCollection<LtiGrade> $grades has_many LtiGrade - * @property Course $course belongs_to Course * @property LtiTool $tool belongs_to LtiTool */ @@ -33,8 +28,6 @@ class LtiDeployment extends SimpleORMap { $config['db_table'] = 'lti_deployments'; - $config['serialized_fields']['options'] = JSONArrayObject::class; - $config['belongs_to']['tool'] = [ 'class_name' => LtiTool::class, 'foreign_key' => 'tool_id' @@ -61,6 +54,8 @@ class LtiDeployment extends SimpleORMap /** * Get the launch_url of this entry. + * + * @deprecated */ public function getLaunchURL() { @@ -72,6 +67,8 @@ class LtiDeployment extends SimpleORMap /** * Get the consumer_key of this entry. + * + * @deprecated */ public function getConsumerKey() { @@ -80,6 +77,8 @@ class LtiDeployment extends SimpleORMap /** * Get the consumer_secret of this entry. + * + * @deprecated */ public function getConsumerSecret() { @@ -88,6 +87,8 @@ class LtiDeployment extends SimpleORMap /** * Get the oauth_signature_method of this entry. + * + * @deprecated */ public function getOauthSignatureMethod() { @@ -96,6 +97,8 @@ class LtiDeployment extends SimpleORMap /** * Get the custom_parameters of this entry. + * + * @deprecated */ public function getCustomParameters() { @@ -107,23 +110,6 @@ class LtiDeployment extends SimpleORMap return $parameters; } - public function getCustomLtiParameterArray() : array - { - $parameter_str = $this->getCustomParameters(); - if (empty($parameter_str)) { - return []; - } - $parameters = explode("\n", $parameter_str); - $array = []; - foreach ($parameters as $parameter) { - $key_value_parts = explode('=', $parameter, 2); - if (count($key_value_parts) === 2) { - $array[trim($key_value_parts[0])] = trim($key_value_parts[1]); - } - } - return ['https://purl.imsglobal.org/spec/lti/claim/custom' => $array]; - } - /** * Get the send_lis_person attribute of this entry. */ diff --git a/lib/models/LtiGrade.php b/lib/models/LtiGrade.php index a7a5dbc..b037f30 100644 --- a/lib/models/LtiGrade.php +++ b/lib/models/LtiGrade.php @@ -18,6 +18,9 @@ * @property int $chdate database column * @property LtiDeployment $link belongs_to LtiDeployment * @property User $user belongs_to User + * + * NOTE: LtiGrade is only for the LTI 1.0/1.1 interface. + * The LTI 1.3A interface uses the grade book tables for storing grades. */ class LtiGrade extends SimpleORMap diff --git a/lib/models/LtiResourceLink.php b/lib/models/LtiResourceLink.php index 785c350..0ea15aa 100644 --- a/lib/models/LtiResourceLink.php +++ b/lib/models/LtiResourceLink.php @@ -23,7 +23,11 @@ use OAT\Library\Lti1p3Core\Util\Collection\CollectionInterface; * @property int $id database column * @property int $deployment_id database column * @property string $course_id database column + * @property string $title database column + * @property string $description database column * @property int $position database column + * @property string $launch_url database column + * @property JSONArrayObject|null $options database column * @property int $mkdate database column * @property int $chdate database column * @property ?LtiDeployment $deployment related object @@ -35,6 +39,8 @@ class LtiResourceLink extends \SimpleORMap implements LtiResourceLinkInterface { $config['db_table'] = 'lti_resource_links'; + $config['serialized_fields']['options'] = JSONArrayObject::class; + $config['belongs_to']['course'] = [ 'class_name' => Course::class, 'foreign_key' => 'course_id' @@ -89,14 +95,19 @@ class LtiResourceLink extends \SimpleORMap implements LtiResourceLinkInterface return self::findOneBySQL('course_id = ? AND position = ?', [$course_id, $position]); } + public function getLaunchURL() + { + if (!empty($this->deployment->tool) && empty($this->deployment->tool->allow_custom_url) && empty($this->deployment->tool->deep_linking) || empty($this->launch_url)) { + return $this->deployment->tool->launch_url; + } + return $this->launch_url; + } + //OAT library LtiResourceLinkInterface and ResourceInterface implementation: public function getUrl(): ?string { - if ($this->deployment) { - return $this->deployment->getLaunchURL(); - } - return null; + return $this->getLaunchURL(); } public function getIcon(): ?array @@ -154,10 +165,7 @@ class LtiResourceLink extends \SimpleORMap implements LtiResourceLinkInterface public function getTitle(): ?string { - if ($this->deployment) { - return $this->deployment->title; - } - return null; + return $this->title ?? $this->deployment->tool->name ?? null; } public function getText(): ?string @@ -184,4 +192,31 @@ class LtiResourceLink extends \SimpleORMap implements LtiResourceLinkInterface ) ); } + + public function getCustomParameters() + { + $parameters = ''; + if (!empty($this->deployment->tool)) { + $parameters = $this->deployment->tool->custom_parameters; + } + $parameters .= $this->options['custom_parameters'] ?? ''; + return $parameters; + } + + public function getCustomLtiParameterArray() : array + { + $parameter_str = $this->getCustomParameters(); + if (empty($parameter_str)) { + return []; + } + $parameters = explode("\n", $parameter_str); + $array = []; + foreach ($parameters as $parameter) { + $key_value_parts = explode('=', $parameter, 2); + if (count($key_value_parts) === 2) { + $array[trim($key_value_parts[0])] = trim($key_value_parts[1]); + } + } + return ['https://purl.imsglobal.org/spec/lti/claim/custom' => $array]; + } } |
