From 318a0e6e692e0418b8243e2f9fac5e59129982c5 Mon Sep 17 00:00:00 2001 From: Moritz Strohm Date: Wed, 3 Jul 2024 11:49:36 +0200 Subject: moved LTI 1.3a files for compatibility with the new autoloader --- lib/classes/LTI13a/GradeManager.php | 19 +++++ lib/classes/LTI13a/Identity.class.php | 93 +++++++++++++++++++++++ lib/classes/LTI13a/KeyChainFactory.php | 30 ++++++++ lib/classes/LTI13a/KeyManager.php | 31 ++++++++ lib/classes/LTI13a/LineItemRepository.php | 65 ++++++++++++++++ lib/classes/LTI13a/NonceGenerator.php | 35 +++++++++ lib/classes/LTI13a/PlatformManager.php | 106 ++++++++++++++++++++++++++ lib/classes/LTI13a/Registration.php | 112 ++++++++++++++++++++++++++++ lib/classes/LTI13a/RegistrationManager.php | 63 ++++++++++++++++ lib/classes/LTI13a/ResultRepository.php | 46 ++++++++++++ lib/classes/LTI13a/ScoreRepository.php | 30 ++++++++ lib/classes/LTI13a/ToolManager.php | 55 ++++++++++++++ lib/classes/LTI13a/UserAuthenticator.php | 41 ++++++++++ lib/classes/lti1.3a/GradeManager.php | 19 ----- lib/classes/lti1.3a/Identity.class.php | 93 ----------------------- lib/classes/lti1.3a/KeyChainFactory.php | 30 -------- lib/classes/lti1.3a/KeyManager.php | 31 -------- lib/classes/lti1.3a/LineItemRepository.php | 65 ---------------- lib/classes/lti1.3a/NonceGenerator.php | 35 --------- lib/classes/lti1.3a/PlatformManager.php | 106 -------------------------- lib/classes/lti1.3a/Registration.php | 112 ---------------------------- lib/classes/lti1.3a/RegistrationManager.php | 63 ---------------- lib/classes/lti1.3a/ResultRepository.php | 46 ------------ lib/classes/lti1.3a/ScoreRepository.php | 30 -------- lib/classes/lti1.3a/ToolManager.php | 55 -------------- lib/classes/lti1.3a/UserAuthenticator.php | 41 ---------- 26 files changed, 726 insertions(+), 726 deletions(-) create mode 100644 lib/classes/LTI13a/GradeManager.php create mode 100644 lib/classes/LTI13a/Identity.class.php create mode 100644 lib/classes/LTI13a/KeyChainFactory.php create mode 100644 lib/classes/LTI13a/KeyManager.php create mode 100644 lib/classes/LTI13a/LineItemRepository.php create mode 100644 lib/classes/LTI13a/NonceGenerator.php create mode 100644 lib/classes/LTI13a/PlatformManager.php create mode 100644 lib/classes/LTI13a/Registration.php create mode 100644 lib/classes/LTI13a/RegistrationManager.php create mode 100644 lib/classes/LTI13a/ResultRepository.php create mode 100644 lib/classes/LTI13a/ScoreRepository.php create mode 100644 lib/classes/LTI13a/ToolManager.php create mode 100644 lib/classes/LTI13a/UserAuthenticator.php delete mode 100644 lib/classes/lti1.3a/GradeManager.php delete mode 100644 lib/classes/lti1.3a/Identity.class.php delete mode 100644 lib/classes/lti1.3a/KeyChainFactory.php delete mode 100644 lib/classes/lti1.3a/KeyManager.php delete mode 100644 lib/classes/lti1.3a/LineItemRepository.php delete mode 100644 lib/classes/lti1.3a/NonceGenerator.php delete mode 100644 lib/classes/lti1.3a/PlatformManager.php delete mode 100644 lib/classes/lti1.3a/Registration.php delete mode 100644 lib/classes/lti1.3a/RegistrationManager.php delete mode 100644 lib/classes/lti1.3a/ResultRepository.php delete mode 100644 lib/classes/lti1.3a/ScoreRepository.php delete mode 100644 lib/classes/lti1.3a/ToolManager.php delete mode 100644 lib/classes/lti1.3a/UserAuthenticator.php diff --git a/lib/classes/LTI13a/GradeManager.php b/lib/classes/LTI13a/GradeManager.php new file mode 100644 index 0000000..245011c --- /dev/null +++ b/lib/classes/LTI13a/GradeManager.php @@ -0,0 +1,19 @@ +user = $user; + + $privacy_settings = \LtiDeploymentPrivacySettings::findOneBySQL( + '`deployment_id` = :deployment_id AND `user_id` = :user_id', + ['deployment_id' => $deployment->id, 'user_id' => $user->id] + ); + if ($privacy_settings) { + $this->allowed_optional_fields = explode(',', $privacy_settings->allowed_optional_fields); + } + } + + #[\Override] public function getIdentifier(): string + { + return $this->user->id; + } + + #[\Override] public function getName(): ?string + { + return $this->user->getFullName(); + } + + #[\Override] public function getEmail(): ?string + { + return $this->user->email; + } + + #[\Override] public function getGivenName(): ?string + { + return $this->user->vorname; + } + + #[\Override] public function getFamilyName(): ?string + { + return $this->user->nachname; + } + + #[\Override] public function getMiddleName(): ?string + { + return ''; + } + + #[\Override] public function getLocale(): ?string + { + if (!in_array('lang', $this->allowed_optional_fields)) { + return ''; + } + return $this->user->preferred_language; + } + + #[\Override] public function getPicture(): ?string + { + if (!in_array('avatar_url', $this->allowed_optional_fields)) { + return ''; + } + return \Avatar::getAvatar($this->user->id)->getURL(\Avatar::MEDIUM); + } + + #[\Override] public function getAdditionalProperties(): CollectionInterface + { + return []; + } + + #[\Override] public function normalize(): array + { + return [ + MessagePayloadInterface::CLAIM_SUB => $this->getIdentifier(), + MessagePayloadInterface::CLAIM_USER_NAME => $this->getName(), + MessagePayloadInterface::CLAIM_USER_EMAIL => $this->getEmail(), + MessagePayloadInterface::CLAIM_USER_GIVEN_NAME => $this->getGivenName(), + MessagePayloadInterface::CLAIM_USER_FAMILY_NAME => $this->getFamilyName(), + MessagePayloadInterface::CLAIM_USER_MIDDLE_NAME => $this->getMiddleName(), + MessagePayloadInterface::CLAIM_USER_LOCALE => $this->getLocale(), + MessagePayloadInterface::CLAIM_USER_PICTURE => $this->getPicture() + ]; + } +} diff --git a/lib/classes/LTI13a/KeyChainFactory.php b/lib/classes/LTI13a/KeyChainFactory.php new file mode 100644 index 0000000..da13fb9 --- /dev/null +++ b/lib/classes/LTI13a/KeyChainFactory.php @@ -0,0 +1,30 @@ + $identifier]); + if ($keyring) { + return $keyring->toKeyChain(); + } + } + throw new \StudipException('Unable to create a keyring.'); + } +} diff --git a/lib/classes/LTI13a/KeyManager.php b/lib/classes/LTI13a/KeyManager.php new file mode 100644 index 0000000..f27002a --- /dev/null +++ b/lib/classes/LTI13a/KeyManager.php @@ -0,0 +1,31 @@ +toKeyChain(); + } + return null; + } + + /** + * @inheritDoc + */ + #[\Override] public function findByKeySetName(string $keySetName): array + { + $keyring = \Keyring::findOneByRange_id($keySetName); + if ($keyring) { + return [$keyring->toKeyChain()]; + } + return []; + } +} diff --git a/lib/classes/LTI13a/LineItemRepository.php b/lib/classes/LTI13a/LineItemRepository.php new file mode 100644 index 0000000..6826fc0 --- /dev/null +++ b/lib/classes/LTI13a/LineItemRepository.php @@ -0,0 +1,65 @@ +toLineItem(); + } + return null; + } + + public function findCollection(?string $resourceIdentifier = null, ?string $resourceLinkIdentifier = null, ?string $tag = null, ?int $limit = null, ?int $offset = null): LineItemCollectionInterface + { + $sql = ''; + $sql_params = []; + if ($resourceIdentifier) { + $sql .= "`tool` = :tool "; + $sql_params['tool'] = sprintf('lti-%s', $resourceIdentifier); + } + + //TODO: resourceLinkIdentifier, tag + + if ($limit) { + if (empty($sql)) { + $sql .= "TRUE "; + } + $sql .= "LIMIT :limit "; + $sql_params['limit'] = $limit; + } + if ($offset) { + $sql .= "OFFSET :offset"; + $sql_params['offset'] = $offset; + } + $definitions = \Grading\Definition::findBySql($sql, $sql_params); + $result = new LineItemCollection(); + foreach ($definitions as $definition) { + $result->add($definition->toLineItem()); + } + return $result; + } + + public function save(LineItemInterface $lineItem): LineItemInterface + { + \Grading\Definition::createFromLineItem($lineItem); + return $lineItem; + } + + public function delete(string $lineItemIdentifier): void + { + $definition = \Grading\Definition::find($lineItemIdentifier); + if ($definition) { + $definition->delete(); + } + } +} diff --git a/lib/classes/LTI13a/NonceGenerator.php b/lib/classes/LTI13a/NonceGenerator.php new file mode 100644 index 0000000..349c969 --- /dev/null +++ b/lib/classes/LTI13a/NonceGenerator.php @@ -0,0 +1,35 @@ +pass_nonce_from_request = $pass_nonce_from_request; + } + + #[\Override] public function generate(?int $ttl = null): NonceInterface + { + $expiration = new \DateTime(); + $expiration = $expiration->add(new \DateInterval('PT5M')); + if ($this->pass_nonce_from_request) { + return new Nonce( + \Request::get('nonce'), + $expiration + ); + } else { + $nonce = md5(random_bytes(16) . 'lti13a_nonce'); + //TODO: save nonce. + return new Nonce( + $nonce, + $expiration + ); + } + } +} diff --git a/lib/classes/LTI13a/PlatformManager.php b/lib/classes/LTI13a/PlatformManager.php new file mode 100644 index 0000000..23b46c9 --- /dev/null +++ b/lib/classes/LTI13a/PlatformManager.php @@ -0,0 +1,106 @@ +STUDIP_INSTALLATION_ID, + $c->UNI_NAME_CLEAN, + $GLOBALS['ABSOLUTE_URI_STUDIP'], + \URLHelper::getURL('dispatch.php/lti/auth/oidc_init', null, true), + \URLHelper::getURL('dispatch.php/lti/auth/oauth2_token', null, true) + ); + } + + /** + * 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 + * the platform return URL. + * + * @return DeepLinkingSettings The settings for deep linking. + */ + public static function getDeepLinkingConfiguration(string $tool_id = '') : DeepLinkingSettings + { + $c = \Config::get(); + + return new DeepLinkingSettings( + self::getDeepLinkingReturnUrl($tool_id), + [ + LtiResourceLinkInterface::TYPE + ], + ['window', 'iframe'], + 'text/html', + true, + false, + $c->UNI_NAME_CLEAN, + '' + ); + } + + /** + * Returns the keyring for the platform. + * + * @return \Keyring|null The keyring for the platform or null if no such keyring exists. + */ + public static function getPlatformKeyring() : ?\Keyring + { + return \Keyring::findOneBySQL("`range_type` = 'global' AND `range_id` = 'lti13a_platform'"); + } + + public static function generatePlatformKeyring() : \Keyring + { + return \Keyring::generate('lti13a_platform', 'global'); + } + + public static function getLtiRoleClaimForStudipRole(string $role) : string + { + if (in_array($role, ['tutor', 'dozent', 'admin', 'root'])) { + //Lecturer/admin + return 'http://purl.imsglobal.org/vocab/lis/v2/membership#Mentor'; + } elseif (in_array($role, ['user', 'autor'])) { + //Learner + return 'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner'; + } + //Invalid role: + return ''; + } + + /** + * 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. + * + * @return string The URL for returning from an LTI deep linking process. + */ + public static function getDeepLinkingReturnUrl(string $tool_id = '') : string + { + return \URLHelper::getURL('dispatch.php/course/lti/save_link/' . $tool_id, null, true); + } + + /** + * Returns the URL from which the JSON web key set (JWKS) can be retrieved. + * + * @return string The JWKS URL. + */ + public static function getJwksUrl() : string + { + return \URLHelper::getURL('lti/auth/jwks'); + } +} diff --git a/lib/classes/LTI13a/Registration.php b/lib/classes/LTI13a/Registration.php new file mode 100644 index 0000000..df0a9b9 --- /dev/null +++ b/lib/classes/LTI13a/Registration.php @@ -0,0 +1,112 @@ +lti_link = $lti_link; + } + + public function setLtiDeployment(\LtiDeployment $lti_link) + { + $this->lti_link = $lti_link; + } + + public function getLtiDeployment() : ?\LtiDeployment + { + return $this->lti_link; + } + + #[\Override] public function getIdentifier(): string + { + if (!$this->lti_link) { + return ''; + } + return $this->lti_link->id; + } + + #[\Override] public function getClientId(): string + { + return \Config::get()->STUDIP_INSTALLATION_ID; + } + + #[\Override] public function getPlatform(): PlatformInterface + { + return \Studip\LTI13a\PlatformManager::getPlatformConfiguration(); + } + + #[\Override] public function getTool(): ToolInterface + { + if (!$this->lti_link || !$this->lti_link->tool) { + throw new \StudipException('No LTI tool link present.'); + } + return $this->lti_link->tool->getToolData(); + } + + #[\Override] public function getDeploymentIds(): array + { + if (!$this->lti_link) { + return []; + } + return [$this->lti_link->id]; + } + + #[\Override] public function hasDeploymentId(string $deploymentId): bool + { + if (!$this->lti_link) { + return false; + } + return $this->lti_link->id == $deploymentId; + } + + #[\Override] public function getDefaultDeploymentId(): ?string + { + if (!$this->lti_link) { + return null; + }; + if ($this->lti_link->isNew() && !$this->lti_link->id) { + $this->lti_link->getNewId(); + } + return $this->lti_link->id; + } + + #[\Override] public function getPlatformKeyChain(): ?KeyChainInterface + { + $platform_keyring = \Studip\LTI13a\PlatformManager::getPlatformKeyring(); + if (!$platform_keyring) { + $platform_keyring = \Studip\LTI13a\PlatformManager::generatePlatformKeyring(); + } + return $platform_keyring->toKeyChain(); + } + + #[\Override] public function getToolKeyChain(): ?KeyChainInterface + { + if (!$this->lti_link || !$this->lti_link->tool) { + return null; + } + $keyring = $this->lti_link->tool->getKeyring(); + if (!$keyring) { + $keyring = $this->lti_link->tool->getKeyring(true); + } + return $keyring->toKeyChain(); + } + + #[\Override] public function getPlatformJwksUrl(): ?string + { + return PlatformManager::getJwksUrl(); + } + + #[\Override] public function getToolJwksUrl(): ?string + { + return $this->lti_link->tool->jwks_url ?? null; + } +} diff --git a/lib/classes/LTI13a/RegistrationManager.php b/lib/classes/LTI13a/RegistrationManager.php new file mode 100644 index 0000000..5e75275 --- /dev/null +++ b/lib/classes/LTI13a/RegistrationManager.php @@ -0,0 +1,63 @@ + $lineItemIdentifier]; + if ($limit) { + $sql .= 'LIMIT :limit '; + $sql_params['limit'] = $limit; + } + if ($offset) { + $sql .= 'OFFSET :offset '; + $sql_params['offset'] = $offset; + } + + $grades = \Grading\Instance::findBySQL($sql, $sql_params); + $results = new ResultCollection(); + foreach ($grades as $grade) { + $results->add($grade->toResult()); + } + return $results; + } + + public function findByLineItemIdentifierAndUserIdentifier(string $lineItemIdentifier, string $userIdentifier): ?ResultInterface + { + $grade = \Grading\Instance::findOneBySQL( + '`definition_id` = :definition_id` AND `user_id` = :user_id', + ['definition_id' => $lineItemIdentifier, 'user_id' => $userIdentifier] + ); + if ($grade) { + return $grade->toResult(); + } + return null; + } +} diff --git a/lib/classes/LTI13a/ScoreRepository.php b/lib/classes/LTI13a/ScoreRepository.php new file mode 100644 index 0000000..24f67b9 --- /dev/null +++ b/lib/classes/LTI13a/ScoreRepository.php @@ -0,0 +1,30 @@ +getUserIdentifier(); + $definition_id = $score->getLineItemIdentifier(); + + $grade = \Grading\Instance::findBySQL( + '`definition_id` = :definition_id AND `user_id` = :user_id', + ['definition_id' => $definition_id, 'user_id' => $user_id] + ); + if (!$grade) { + $grade = new \Grading\Instance(); + $grade->definition_id = $definition_id; + $grade->user_id = $user_id; + } + $grade->rawgrade = $score->getScoreGiven(); + $grade->feedback = $score->getComment(); + $grade->store(); + return $score; + } +} diff --git a/lib/classes/LTI13a/ToolManager.php b/lib/classes/LTI13a/ToolManager.php new file mode 100644 index 0000000..bf5529d --- /dev/null +++ b/lib/classes/LTI13a/ToolManager.php @@ -0,0 +1,55 @@ +getIdentifier(), + $tool->getName(), + $tool->getAudience(), + $tool->getOidcInitiationUrl(), + $tool->getLaunchUrl(), + $tool->getDeepLinkingUrl() + ); + } + + public function getToolRegistration(string $tool_id) :?Registration + { + $platform_config = PlatformManager::getPlatformConfiguration(); + $tool_config = self::getToolConfiguration($tool_id); + if (!$platform_config || !$tool_config) { + return null; + } + + $platform_keyring = \Keyring::findOneBySQL("`range_type` = 'global' AND `range_id` = 'lti13a_platform'"); + $tool_keyring = \Keyring::findOneBySQL( + "`range_type` = 'lti-tool' AND 'range_id = :tool_id", + ['tool_id' => $tool_id] + ); + + return new Registration( + sprintf( + '%s_%s', + $platform_config->getIdentifier(), + $tool_config->getIdentifier() + ), + $GLOBALS['user']->id, + $platform_config, + $tool_config, + [], //TODO + $platform_keyring ? $platform_keyring->toKeyChain() : null, + $tool_keyring ? $tool_keyring->toKeyChain() : null + ); + } +} diff --git a/lib/classes/LTI13a/UserAuthenticator.php b/lib/classes/LTI13a/UserAuthenticator.php new file mode 100644 index 0000000..6c06bbd --- /dev/null +++ b/lib/classes/LTI13a/UserAuthenticator.php @@ -0,0 +1,41 @@ +logger = $logger; + } + + #[\Override] public function authenticate(RegistrationInterface $registration, string $loginHint): UserAuthenticationResultInterface + { + $user = \User::find($loginHint); + + $identity = null; + $deployment = null; + if ($registration instanceof \Studip\LTI13a\Registration) { + $deployment = $registration->getLtiDeployment(); + } else { + $deployment = \LtiDeployment::find($registration->getIdentifier()); + } + if ($user instanceof \User && $deployment instanceof \LtiDeployment) { + $identity = new Identity($user, $deployment); + } + if ($this->logger) { + //$this->logger->debug($user instanceof \User); + //$this->logger->debug($loginHint); + $this->logger->debug(var_export($identity->normalize(), true)); + } + + return new UserAuthenticationResult($user instanceof \User, $identity); + } +} diff --git a/lib/classes/lti1.3a/GradeManager.php b/lib/classes/lti1.3a/GradeManager.php deleted file mode 100644 index 245011c..0000000 --- a/lib/classes/lti1.3a/GradeManager.php +++ /dev/null @@ -1,19 +0,0 @@ -user = $user; - - $privacy_settings = \LtiDeploymentPrivacySettings::findOneBySQL( - '`deployment_id` = :deployment_id AND `user_id` = :user_id', - ['deployment_id' => $deployment->id, 'user_id' => $user->id] - ); - if ($privacy_settings) { - $this->allowed_optional_fields = explode(',', $privacy_settings->allowed_optional_fields); - } - } - - #[\Override] public function getIdentifier(): string - { - return $this->user->id; - } - - #[\Override] public function getName(): ?string - { - return $this->user->getFullName(); - } - - #[\Override] public function getEmail(): ?string - { - return $this->user->email; - } - - #[\Override] public function getGivenName(): ?string - { - return $this->user->vorname; - } - - #[\Override] public function getFamilyName(): ?string - { - return $this->user->nachname; - } - - #[\Override] public function getMiddleName(): ?string - { - return ''; - } - - #[\Override] public function getLocale(): ?string - { - if (!in_array('lang', $this->allowed_optional_fields)) { - return ''; - } - return $this->user->preferred_language; - } - - #[\Override] public function getPicture(): ?string - { - if (!in_array('avatar_url', $this->allowed_optional_fields)) { - return ''; - } - return \Avatar::getAvatar($this->user->id)->getURL(\Avatar::MEDIUM); - } - - #[\Override] public function getAdditionalProperties(): CollectionInterface - { - return []; - } - - #[\Override] public function normalize(): array - { - return [ - MessagePayloadInterface::CLAIM_SUB => $this->getIdentifier(), - MessagePayloadInterface::CLAIM_USER_NAME => $this->getName(), - MessagePayloadInterface::CLAIM_USER_EMAIL => $this->getEmail(), - MessagePayloadInterface::CLAIM_USER_GIVEN_NAME => $this->getGivenName(), - MessagePayloadInterface::CLAIM_USER_FAMILY_NAME => $this->getFamilyName(), - MessagePayloadInterface::CLAIM_USER_MIDDLE_NAME => $this->getMiddleName(), - MessagePayloadInterface::CLAIM_USER_LOCALE => $this->getLocale(), - MessagePayloadInterface::CLAIM_USER_PICTURE => $this->getPicture() - ]; - } -} diff --git a/lib/classes/lti1.3a/KeyChainFactory.php b/lib/classes/lti1.3a/KeyChainFactory.php deleted file mode 100644 index da13fb9..0000000 --- a/lib/classes/lti1.3a/KeyChainFactory.php +++ /dev/null @@ -1,30 +0,0 @@ - $identifier]); - if ($keyring) { - return $keyring->toKeyChain(); - } - } - throw new \StudipException('Unable to create a keyring.'); - } -} diff --git a/lib/classes/lti1.3a/KeyManager.php b/lib/classes/lti1.3a/KeyManager.php deleted file mode 100644 index f27002a..0000000 --- a/lib/classes/lti1.3a/KeyManager.php +++ /dev/null @@ -1,31 +0,0 @@ -toKeyChain(); - } - return null; - } - - /** - * @inheritDoc - */ - #[\Override] public function findByKeySetName(string $keySetName): array - { - $keyring = \Keyring::findOneByRange_id($keySetName); - if ($keyring) { - return [$keyring->toKeyChain()]; - } - return []; - } -} diff --git a/lib/classes/lti1.3a/LineItemRepository.php b/lib/classes/lti1.3a/LineItemRepository.php deleted file mode 100644 index 6826fc0..0000000 --- a/lib/classes/lti1.3a/LineItemRepository.php +++ /dev/null @@ -1,65 +0,0 @@ -toLineItem(); - } - return null; - } - - public function findCollection(?string $resourceIdentifier = null, ?string $resourceLinkIdentifier = null, ?string $tag = null, ?int $limit = null, ?int $offset = null): LineItemCollectionInterface - { - $sql = ''; - $sql_params = []; - if ($resourceIdentifier) { - $sql .= "`tool` = :tool "; - $sql_params['tool'] = sprintf('lti-%s', $resourceIdentifier); - } - - //TODO: resourceLinkIdentifier, tag - - if ($limit) { - if (empty($sql)) { - $sql .= "TRUE "; - } - $sql .= "LIMIT :limit "; - $sql_params['limit'] = $limit; - } - if ($offset) { - $sql .= "OFFSET :offset"; - $sql_params['offset'] = $offset; - } - $definitions = \Grading\Definition::findBySql($sql, $sql_params); - $result = new LineItemCollection(); - foreach ($definitions as $definition) { - $result->add($definition->toLineItem()); - } - return $result; - } - - public function save(LineItemInterface $lineItem): LineItemInterface - { - \Grading\Definition::createFromLineItem($lineItem); - return $lineItem; - } - - public function delete(string $lineItemIdentifier): void - { - $definition = \Grading\Definition::find($lineItemIdentifier); - if ($definition) { - $definition->delete(); - } - } -} diff --git a/lib/classes/lti1.3a/NonceGenerator.php b/lib/classes/lti1.3a/NonceGenerator.php deleted file mode 100644 index 349c969..0000000 --- a/lib/classes/lti1.3a/NonceGenerator.php +++ /dev/null @@ -1,35 +0,0 @@ -pass_nonce_from_request = $pass_nonce_from_request; - } - - #[\Override] public function generate(?int $ttl = null): NonceInterface - { - $expiration = new \DateTime(); - $expiration = $expiration->add(new \DateInterval('PT5M')); - if ($this->pass_nonce_from_request) { - return new Nonce( - \Request::get('nonce'), - $expiration - ); - } else { - $nonce = md5(random_bytes(16) . 'lti13a_nonce'); - //TODO: save nonce. - return new Nonce( - $nonce, - $expiration - ); - } - } -} diff --git a/lib/classes/lti1.3a/PlatformManager.php b/lib/classes/lti1.3a/PlatformManager.php deleted file mode 100644 index 23b46c9..0000000 --- a/lib/classes/lti1.3a/PlatformManager.php +++ /dev/null @@ -1,106 +0,0 @@ -STUDIP_INSTALLATION_ID, - $c->UNI_NAME_CLEAN, - $GLOBALS['ABSOLUTE_URI_STUDIP'], - \URLHelper::getURL('dispatch.php/lti/auth/oidc_init', null, true), - \URLHelper::getURL('dispatch.php/lti/auth/oauth2_token', null, true) - ); - } - - /** - * 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 - * the platform return URL. - * - * @return DeepLinkingSettings The settings for deep linking. - */ - public static function getDeepLinkingConfiguration(string $tool_id = '') : DeepLinkingSettings - { - $c = \Config::get(); - - return new DeepLinkingSettings( - self::getDeepLinkingReturnUrl($tool_id), - [ - LtiResourceLinkInterface::TYPE - ], - ['window', 'iframe'], - 'text/html', - true, - false, - $c->UNI_NAME_CLEAN, - '' - ); - } - - /** - * Returns the keyring for the platform. - * - * @return \Keyring|null The keyring for the platform or null if no such keyring exists. - */ - public static function getPlatformKeyring() : ?\Keyring - { - return \Keyring::findOneBySQL("`range_type` = 'global' AND `range_id` = 'lti13a_platform'"); - } - - public static function generatePlatformKeyring() : \Keyring - { - return \Keyring::generate('lti13a_platform', 'global'); - } - - public static function getLtiRoleClaimForStudipRole(string $role) : string - { - if (in_array($role, ['tutor', 'dozent', 'admin', 'root'])) { - //Lecturer/admin - return 'http://purl.imsglobal.org/vocab/lis/v2/membership#Mentor'; - } elseif (in_array($role, ['user', 'autor'])) { - //Learner - return 'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner'; - } - //Invalid role: - return ''; - } - - /** - * 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. - * - * @return string The URL for returning from an LTI deep linking process. - */ - public static function getDeepLinkingReturnUrl(string $tool_id = '') : string - { - return \URLHelper::getURL('dispatch.php/course/lti/save_link/' . $tool_id, null, true); - } - - /** - * Returns the URL from which the JSON web key set (JWKS) can be retrieved. - * - * @return string The JWKS URL. - */ - public static function getJwksUrl() : string - { - return \URLHelper::getURL('lti/auth/jwks'); - } -} diff --git a/lib/classes/lti1.3a/Registration.php b/lib/classes/lti1.3a/Registration.php deleted file mode 100644 index df0a9b9..0000000 --- a/lib/classes/lti1.3a/Registration.php +++ /dev/null @@ -1,112 +0,0 @@ -lti_link = $lti_link; - } - - public function setLtiDeployment(\LtiDeployment $lti_link) - { - $this->lti_link = $lti_link; - } - - public function getLtiDeployment() : ?\LtiDeployment - { - return $this->lti_link; - } - - #[\Override] public function getIdentifier(): string - { - if (!$this->lti_link) { - return ''; - } - return $this->lti_link->id; - } - - #[\Override] public function getClientId(): string - { - return \Config::get()->STUDIP_INSTALLATION_ID; - } - - #[\Override] public function getPlatform(): PlatformInterface - { - return \Studip\LTI13a\PlatformManager::getPlatformConfiguration(); - } - - #[\Override] public function getTool(): ToolInterface - { - if (!$this->lti_link || !$this->lti_link->tool) { - throw new \StudipException('No LTI tool link present.'); - } - return $this->lti_link->tool->getToolData(); - } - - #[\Override] public function getDeploymentIds(): array - { - if (!$this->lti_link) { - return []; - } - return [$this->lti_link->id]; - } - - #[\Override] public function hasDeploymentId(string $deploymentId): bool - { - if (!$this->lti_link) { - return false; - } - return $this->lti_link->id == $deploymentId; - } - - #[\Override] public function getDefaultDeploymentId(): ?string - { - if (!$this->lti_link) { - return null; - }; - if ($this->lti_link->isNew() && !$this->lti_link->id) { - $this->lti_link->getNewId(); - } - return $this->lti_link->id; - } - - #[\Override] public function getPlatformKeyChain(): ?KeyChainInterface - { - $platform_keyring = \Studip\LTI13a\PlatformManager::getPlatformKeyring(); - if (!$platform_keyring) { - $platform_keyring = \Studip\LTI13a\PlatformManager::generatePlatformKeyring(); - } - return $platform_keyring->toKeyChain(); - } - - #[\Override] public function getToolKeyChain(): ?KeyChainInterface - { - if (!$this->lti_link || !$this->lti_link->tool) { - return null; - } - $keyring = $this->lti_link->tool->getKeyring(); - if (!$keyring) { - $keyring = $this->lti_link->tool->getKeyring(true); - } - return $keyring->toKeyChain(); - } - - #[\Override] public function getPlatformJwksUrl(): ?string - { - return PlatformManager::getJwksUrl(); - } - - #[\Override] public function getToolJwksUrl(): ?string - { - return $this->lti_link->tool->jwks_url ?? null; - } -} diff --git a/lib/classes/lti1.3a/RegistrationManager.php b/lib/classes/lti1.3a/RegistrationManager.php deleted file mode 100644 index 5e75275..0000000 --- a/lib/classes/lti1.3a/RegistrationManager.php +++ /dev/null @@ -1,63 +0,0 @@ - $lineItemIdentifier]; - if ($limit) { - $sql .= 'LIMIT :limit '; - $sql_params['limit'] = $limit; - } - if ($offset) { - $sql .= 'OFFSET :offset '; - $sql_params['offset'] = $offset; - } - - $grades = \Grading\Instance::findBySQL($sql, $sql_params); - $results = new ResultCollection(); - foreach ($grades as $grade) { - $results->add($grade->toResult()); - } - return $results; - } - - public function findByLineItemIdentifierAndUserIdentifier(string $lineItemIdentifier, string $userIdentifier): ?ResultInterface - { - $grade = \Grading\Instance::findOneBySQL( - '`definition_id` = :definition_id` AND `user_id` = :user_id', - ['definition_id' => $lineItemIdentifier, 'user_id' => $userIdentifier] - ); - if ($grade) { - return $grade->toResult(); - } - return null; - } -} diff --git a/lib/classes/lti1.3a/ScoreRepository.php b/lib/classes/lti1.3a/ScoreRepository.php deleted file mode 100644 index 24f67b9..0000000 --- a/lib/classes/lti1.3a/ScoreRepository.php +++ /dev/null @@ -1,30 +0,0 @@ -getUserIdentifier(); - $definition_id = $score->getLineItemIdentifier(); - - $grade = \Grading\Instance::findBySQL( - '`definition_id` = :definition_id AND `user_id` = :user_id', - ['definition_id' => $definition_id, 'user_id' => $user_id] - ); - if (!$grade) { - $grade = new \Grading\Instance(); - $grade->definition_id = $definition_id; - $grade->user_id = $user_id; - } - $grade->rawgrade = $score->getScoreGiven(); - $grade->feedback = $score->getComment(); - $grade->store(); - return $score; - } -} diff --git a/lib/classes/lti1.3a/ToolManager.php b/lib/classes/lti1.3a/ToolManager.php deleted file mode 100644 index bf5529d..0000000 --- a/lib/classes/lti1.3a/ToolManager.php +++ /dev/null @@ -1,55 +0,0 @@ -getIdentifier(), - $tool->getName(), - $tool->getAudience(), - $tool->getOidcInitiationUrl(), - $tool->getLaunchUrl(), - $tool->getDeepLinkingUrl() - ); - } - - public function getToolRegistration(string $tool_id) :?Registration - { - $platform_config = PlatformManager::getPlatformConfiguration(); - $tool_config = self::getToolConfiguration($tool_id); - if (!$platform_config || !$tool_config) { - return null; - } - - $platform_keyring = \Keyring::findOneBySQL("`range_type` = 'global' AND `range_id` = 'lti13a_platform'"); - $tool_keyring = \Keyring::findOneBySQL( - "`range_type` = 'lti-tool' AND 'range_id = :tool_id", - ['tool_id' => $tool_id] - ); - - return new Registration( - sprintf( - '%s_%s', - $platform_config->getIdentifier(), - $tool_config->getIdentifier() - ), - $GLOBALS['user']->id, - $platform_config, - $tool_config, - [], //TODO - $platform_keyring ? $platform_keyring->toKeyChain() : null, - $tool_keyring ? $tool_keyring->toKeyChain() : null - ); - } -} diff --git a/lib/classes/lti1.3a/UserAuthenticator.php b/lib/classes/lti1.3a/UserAuthenticator.php deleted file mode 100644 index 6c06bbd..0000000 --- a/lib/classes/lti1.3a/UserAuthenticator.php +++ /dev/null @@ -1,41 +0,0 @@ -logger = $logger; - } - - #[\Override] public function authenticate(RegistrationInterface $registration, string $loginHint): UserAuthenticationResultInterface - { - $user = \User::find($loginHint); - - $identity = null; - $deployment = null; - if ($registration instanceof \Studip\LTI13a\Registration) { - $deployment = $registration->getLtiDeployment(); - } else { - $deployment = \LtiDeployment::find($registration->getIdentifier()); - } - if ($user instanceof \User && $deployment instanceof \LtiDeployment) { - $identity = new Identity($user, $deployment); - } - if ($this->logger) { - //$this->logger->debug($user instanceof \User); - //$this->logger->debug($loginHint); - $this->logger->debug(var_export($identity->normalize(), true)); - } - - return new UserAuthenticationResult($user instanceof \User, $identity); - } -} -- cgit v1.0