aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/classes/LTI13a/PlatformManager.php22
-rw-r--r--lib/classes/LTI13a/Registration.php43
-rw-r--r--lib/classes/LTI13a/RegistrationManager.php21
-rw-r--r--lib/models/LtiDeployment.php34
-rw-r--r--lib/models/LtiGrade.php3
-rw-r--r--lib/models/LtiResourceLink.php51
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];
+ }
}