mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-76926 libraries: upgrade lib/lti1p3 to patched v5.2.6
This commit is contained in:
parent
5e1df25566
commit
efae8d36d5
@ -4,13 +4,11 @@ A library used for building IMS-certified LTI 1.3 tool providers in PHP.
|
||||
|
||||
This library is a fork of the [packbackbooks/lti-1-3-php-library](https://github.com/packbackbooks/lti-1-3-php-library), patched specifically for use in [Moodle](https://github.com/moodle/moodle).
|
||||
|
||||
It is currently based on version [5.2.1 of the packbackbooks/lti-1-3-php-library](https://github.com/packbackbooks/lti-1-3-php-library/releases/tag/v5.2.1) library.
|
||||
It is currently based on version [5.2.6 of the packbackbooks/lti-1-3-php-library](https://github.com/packbackbooks/lti-1-3-php-library/releases/tag/v5.2.6) library.
|
||||
|
||||
The following changes are included so that the library may be used with Moodle:
|
||||
|
||||
* Replace the phpseclib dependency with openssl equivalent call in public key generation code.
|
||||
* Replace the Guzzle dependency with generic HTTP client interfaces for client, response, exception.
|
||||
* Small fix to http_build_query() calls, which now explicitly include the '&' arg separator param, for compatibility with applications that override PHP's arg_separator.output value via an ini_set() call, like Moodle does.
|
||||
|
||||
Please see the original [README](https://github.com/packbackbooks/lti-1-3-php-library/blob/master/README.md) for more information about the upstream library.
|
||||
|
||||
|
@ -4,9 +4,6 @@ namespace Packback\Lti1p3\Helpers;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public static function checkIfNullValue($value): bool
|
||||
{
|
||||
return !is_null($value);
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
Interface IHttpClient
|
||||
{
|
||||
public function request(string $method, string $url, array $options) : IHttpResponse;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
interface IHttpException extends \Throwable
|
||||
{
|
||||
public function getResponse(): IHttpResponse;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
interface IHttpResponse
|
||||
{
|
||||
public function getBody();
|
||||
public function getHeaders(): array;
|
||||
public function getStatusCode(): int;
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
/** @internal */
|
||||
interface ILtiRegistration
|
||||
{
|
||||
public function getIssuer();
|
||||
|
@ -2,13 +2,15 @@
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
|
||||
interface ILtiServiceConnector
|
||||
{
|
||||
public function getAccessToken(ILtiRegistration $registration, array $scopes);
|
||||
|
||||
public function makeRequest(IServiceRequest $request);
|
||||
|
||||
public function getResponseBody(IHttpResponse $response): ?array;
|
||||
public function getResponseBody(Response $request): ?array;
|
||||
|
||||
public function makeServiceRequest(
|
||||
ILtiRegistration $registration,
|
||||
|
@ -2,9 +2,12 @@
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
/** @internal */
|
||||
interface IMessageValidator
|
||||
{
|
||||
public function validate(array $jwtBody);
|
||||
public static function getMessageType(): string;
|
||||
|
||||
public function canValidate(array $jwtBody);
|
||||
public static function canValidate(array $jwtBody): bool;
|
||||
|
||||
public static function validate(array $jwtBody): void;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Packback\Lti1p3\Interfaces;
|
||||
|
||||
/** @internal */
|
||||
interface IServiceRequest
|
||||
{
|
||||
public function getMethod(): string;
|
||||
|
@ -15,8 +15,8 @@ abstract class LtiAbstractService
|
||||
public function __construct(
|
||||
ILtiServiceConnector $serviceConnector,
|
||||
ILtiRegistration $registration,
|
||||
array $serviceData)
|
||||
{
|
||||
array $serviceData
|
||||
) {
|
||||
$this->serviceConnector = $serviceConnector;
|
||||
$this->registration = $registration;
|
||||
$this->serviceData = $serviceData;
|
||||
|
@ -91,4 +91,9 @@ class LtiConstants
|
||||
public const COURSE_OFFERING = 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseOffering';
|
||||
public const COURSE_SECTION = 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseSection';
|
||||
public const COURSE_GROUP = 'http://purl.imsglobal.org/vocab/lis/v2/course#Group';
|
||||
|
||||
// Message Types
|
||||
public const MESSAGE_TYPE_DEEPLINK = 'LtiDeepLinkingRequest';
|
||||
public const MESSAGE_TYPE_RESOURCE = 'LtiResourceLinkRequest';
|
||||
public const MESSAGE_TYPE_SUBMISSIONREVIEW = 'LtiSubmissionReviewRequest';
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ class LtiDeepLink
|
||||
LtiConstants::DEPLOYMENT_ID => $this->deployment_id,
|
||||
LtiConstants::MESSAGE_TYPE => 'LtiDeepLinkingResponse',
|
||||
LtiConstants::VERSION => LtiConstants::V1_3,
|
||||
LtiConstants::DL_CONTENT_ITEMS => array_map(function ($resource) { return $resource->toArray(); }, $resources),
|
||||
LtiConstants::DL_CONTENT_ITEMS => array_map(function ($resource) {
|
||||
return $resource->toArray();
|
||||
}, $resources),
|
||||
];
|
||||
|
||||
// https://www.imsglobal.org/spec/lti-dl/v2p0/#deep-linking-request-message
|
||||
|
@ -12,6 +12,7 @@ class LtiGrade
|
||||
private $timestamp;
|
||||
private $user_id;
|
||||
private $submission_review;
|
||||
private $canvas_extension;
|
||||
|
||||
public function __construct(array $grade = null)
|
||||
{
|
||||
|
@ -2,13 +2,15 @@
|
||||
|
||||
namespace Packback\Lti1p3;
|
||||
|
||||
use Exception;
|
||||
use Firebase\JWT\ExpiredException;
|
||||
use Firebase\JWT\JWK;
|
||||
use Firebase\JWT\JWT;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use Packback\Lti1p3\Interfaces\ICache;
|
||||
use Packback\Lti1p3\Interfaces\ICookie;
|
||||
use Packback\Lti1p3\Interfaces\IDatabase;
|
||||
use Packback\Lti1p3\Interfaces\IHttpException;
|
||||
use Packback\Lti1p3\Interfaces\ILtiServiceConnector;
|
||||
use Packback\Lti1p3\MessageValidators\DeepLinkMessageValidator;
|
||||
use Packback\Lti1p3\MessageValidators\ResourceMessageValidator;
|
||||
@ -41,7 +43,6 @@ class LtiMessageLaunch
|
||||
public const ERR_MISSING_DEPLOYEMENT_ID = 'No deployment ID was specified';
|
||||
public const ERR_NO_DEPLOYMENT = 'Unable to find deployment.';
|
||||
public const ERR_INVALID_MESSAGE_TYPE = 'Invalid message type';
|
||||
public const ERR_VALIDATOR_CONFLICT = 'Validator conflict.';
|
||||
public const ERR_UNRECOGNIZED_MESSAGE_TYPE = 'Unrecognized message type.';
|
||||
public const ERR_INVALID_MESSAGE = 'Message validation failed.';
|
||||
public const ERR_INVALID_ALG = 'Invalid alg was specified in the JWT header.';
|
||||
@ -69,10 +70,10 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param IDatabase $database instance of the database interface used for looking up registrations and deployments
|
||||
* @param ICache $cache instance of the Cache interface used to loading and storing launches
|
||||
* @param ICookie $cookie instance of the Cookie interface used to set and read cookies
|
||||
* @param ILtiServiceConnector $serviceConnector instance of the LtiServiceConnector used to by LTI services to make API requests
|
||||
* @param IDatabase $database Instance of the database interface used for looking up registrations and deployments
|
||||
* @param ICache $cache Instance of the Cache interface used to loading and storing launches
|
||||
* @param ICookie $cookie Instance of the Cookie interface used to set and read cookies
|
||||
* @param ILtiServiceConnector $serviceConnector Instance of the LtiServiceConnector used to by LTI services to make API requests
|
||||
*/
|
||||
public function __construct(
|
||||
IDatabase $database,
|
||||
@ -104,19 +105,20 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Load an LtiMessageLaunch from a Cache using a launch id.
|
||||
*
|
||||
* @param string $launch_id the launch id of the LtiMessageLaunch object that is being pulled from the cache
|
||||
* @param IDatabase $database instance of the database interface used for looking up registrations and deployments
|
||||
* @param string $launch_id The launch id of the LtiMessageLaunch object that is being pulled from the cache
|
||||
* @param IDatabase $database Instance of the database interface used for looking up registrations and deployments
|
||||
* @param ICache $cache Instance of the Cache interface used to loading and storing launches. If non is provided launch data will be store in $_SESSION.
|
||||
*
|
||||
* @throws LtiException will throw an LtiException if validation fails or launch cannot be found
|
||||
* @throws LtiException Will throw an LtiException if validation fails or launch cannot be found
|
||||
*
|
||||
* @return LtiMessageLaunch a populated and validated LtiMessageLaunch
|
||||
* @return LtiMessageLaunch A populated and validated LtiMessageLaunch
|
||||
*/
|
||||
public static function fromCache($launch_id,
|
||||
public static function fromCache(
|
||||
$launch_id,
|
||||
IDatabase $database,
|
||||
ICache $cache = null,
|
||||
ILtiServiceConnector $serviceConnector = null)
|
||||
{
|
||||
ILtiServiceConnector $serviceConnector = null
|
||||
) {
|
||||
$new = new LtiMessageLaunch($database, $cache, null, $serviceConnector);
|
||||
$new->launch_id = $launch_id;
|
||||
$new->jwt = ['body' => $new->cache->getLaunchData($launch_id)];
|
||||
@ -129,9 +131,9 @@ class LtiMessageLaunch
|
||||
*
|
||||
* @param array|string $request An array of post request parameters. If not set will default to $_POST.
|
||||
*
|
||||
* @throws LtiException will throw an LtiException if validation fails
|
||||
* @throws LtiException Will throw an LtiException if validation fails
|
||||
*
|
||||
* @return LtiMessageLaunch will return $this if validation is successful
|
||||
* @return LtiMessageLaunch Will return $this if validation is successful
|
||||
*/
|
||||
public function validate(array $request = null)
|
||||
{
|
||||
@ -153,7 +155,7 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Returns whether or not the current launch can use the names and roles service.
|
||||
*
|
||||
* @return bool returns a boolean indicating the availability of names and roles
|
||||
* @return bool Returns a boolean indicating the availability of names and roles
|
||||
*/
|
||||
public function hasNrps()
|
||||
{
|
||||
@ -163,20 +165,21 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Fetches an instance of the names and roles service for the current launch.
|
||||
*
|
||||
* @return LtiNamesRolesProvisioningService an instance of the names and roles service that can be used to make calls within the scope of the current launch
|
||||
* @return LtiNamesRolesProvisioningService An instance of the names and roles service that can be used to make calls within the scope of the current launch
|
||||
*/
|
||||
public function getNrps()
|
||||
{
|
||||
return new LtiNamesRolesProvisioningService(
|
||||
$this->serviceConnector,
|
||||
$this->registration,
|
||||
$this->jwt['body'][LtiConstants::NRPS_CLAIM_SERVICE]);
|
||||
$this->jwt['body'][LtiConstants::NRPS_CLAIM_SERVICE]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the current launch can use the groups service.
|
||||
*
|
||||
* @return bool returns a boolean indicating the availability of groups
|
||||
* @return bool Returns a boolean indicating the availability of groups
|
||||
*/
|
||||
public function hasGs()
|
||||
{
|
||||
@ -186,20 +189,21 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Fetches an instance of the groups service for the current launch.
|
||||
*
|
||||
* @return LtiCourseGroupsService an instance of the groups service that can be used to make calls within the scope of the current launch
|
||||
* @return LtiCourseGroupsService An instance of the groups service that can be used to make calls within the scope of the current launch
|
||||
*/
|
||||
public function getGs()
|
||||
{
|
||||
return new LtiCourseGroupsService(
|
||||
$this->serviceConnector,
|
||||
$this->registration,
|
||||
$this->jwt['body'][LtiConstants::GS_CLAIM_SERVICE]);
|
||||
$this->jwt['body'][LtiConstants::GS_CLAIM_SERVICE]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the current launch can use the assignments and grades service.
|
||||
*
|
||||
* @return bool returns a boolean indicating the availability of assignments and grades
|
||||
* @return bool Returns a boolean indicating the availability of assignments and grades
|
||||
*/
|
||||
public function hasAgs()
|
||||
{
|
||||
@ -209,20 +213,21 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Fetches an instance of the assignments and grades service for the current launch.
|
||||
*
|
||||
* @return LtiAssignmentsGradesService an instance of the assignments an grades service that can be used to make calls within the scope of the current launch
|
||||
* @return LtiAssignmentsGradesService An instance of the assignments an grades service that can be used to make calls within the scope of the current launch
|
||||
*/
|
||||
public function getAgs()
|
||||
{
|
||||
return new LtiAssignmentsGradesService(
|
||||
$this->serviceConnector,
|
||||
$this->registration,
|
||||
$this->jwt['body'][LtiConstants::AGS_CLAIM_ENDPOINT]);
|
||||
$this->jwt['body'][LtiConstants::AGS_CLAIM_ENDPOINT]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the current launch is a deep linking launch.
|
||||
*
|
||||
* @return bool returns true if the current launch is a deep linking launch
|
||||
* @return bool Returns true if the current launch is a deep linking launch
|
||||
*/
|
||||
public function isDeepLinkLaunch()
|
||||
{
|
||||
@ -232,20 +237,21 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Fetches a deep link that can be used to construct a deep linking response.
|
||||
*
|
||||
* @return LtiDeepLink an instance of a deep link to construct a deep linking response for the current launch
|
||||
* @return LtiDeepLink An instance of a deep link to construct a deep linking response for the current launch
|
||||
*/
|
||||
public function getDeepLink()
|
||||
{
|
||||
return new LtiDeepLink(
|
||||
$this->registration,
|
||||
$this->jwt['body'][LtiConstants::DEPLOYMENT_ID],
|
||||
$this->jwt['body'][LtiConstants::DL_DEEP_LINK_SETTINGS]);
|
||||
$this->jwt['body'][LtiConstants::DL_DEEP_LINK_SETTINGS]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the current launch is a submission review launch.
|
||||
*
|
||||
* @return bool returns true if the current launch is a submission review launch
|
||||
* @return bool Returns true if the current launch is a submission review launch
|
||||
*/
|
||||
public function isSubmissionReviewLaunch()
|
||||
{
|
||||
@ -255,7 +261,7 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Returns whether or not the current launch is a resource launch.
|
||||
*
|
||||
* @return bool returns true if the current launch is a resource launch
|
||||
* @return bool Returns true if the current launch is a resource launch
|
||||
*/
|
||||
public function isResourceLaunch()
|
||||
{
|
||||
@ -265,7 +271,7 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Fetches the decoded body of the JWT used in the current launch.
|
||||
*
|
||||
* @return array|object returns the decoded json body of the launch as an array
|
||||
* @return array|object Returns the decoded json body of the launch as an array
|
||||
*/
|
||||
public function getLaunchData()
|
||||
{
|
||||
@ -275,7 +281,7 @@ class LtiMessageLaunch
|
||||
/**
|
||||
* Get the unique launch id for the current launch.
|
||||
*
|
||||
* @return string a unique identifier used to re-reference the current launch in subsequent requests
|
||||
* @return string A unique identifier used to re-reference the current launch in subsequent requests
|
||||
*/
|
||||
public function getLaunchId()
|
||||
{
|
||||
@ -306,7 +312,7 @@ class LtiMessageLaunch
|
||||
// Download key set
|
||||
try {
|
||||
$response = $this->serviceConnector->makeRequest($request);
|
||||
} catch (IHttpException $e) {
|
||||
} catch (TransferException $e) {
|
||||
throw new LtiException(static::ERR_NO_PUBLIC_KEY);
|
||||
}
|
||||
$publicKeySet = $this->serviceConnector->getResponseBody($response);
|
||||
@ -325,7 +331,7 @@ class LtiMessageLaunch
|
||||
$keySet = JWK::parseKeySet([
|
||||
'keys' => [$key],
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -484,36 +490,31 @@ class LtiMessageLaunch
|
||||
throw new LtiException(static::ERR_INVALID_MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Fix this nonsense
|
||||
*/
|
||||
$validator = $this->getMessageValidator($this->jwt['body']);
|
||||
|
||||
// Create instances of all validators
|
||||
$validators = [
|
||||
new DeepLinkMessageValidator(),
|
||||
new ResourceMessageValidator(),
|
||||
new SubmissionReviewMessageValidator(),
|
||||
];
|
||||
|
||||
$message_validator = false;
|
||||
foreach ($validators as $validator) {
|
||||
if ($validator->canValidate($this->jwt['body'])) {
|
||||
if ($message_validator !== false) {
|
||||
// Can't have more than one validator apply at a time.
|
||||
throw new LtiException(static::ERR_VALIDATOR_CONFLICT);
|
||||
}
|
||||
$message_validator = $validator;
|
||||
}
|
||||
}
|
||||
|
||||
if ($message_validator === false) {
|
||||
if (!isset($validator)) {
|
||||
throw new LtiException(static::ERR_UNRECOGNIZED_MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
if (!$message_validator->validate($this->jwt['body'])) {
|
||||
throw new LtiException(static::ERR_INVALID_MESSAGE);
|
||||
}
|
||||
$validator::validate($this->jwt['body']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getMessageValidator(array $jwtBody): ?string
|
||||
{
|
||||
$availableValidators = [
|
||||
DeepLinkMessageValidator::class,
|
||||
ResourceMessageValidator::class,
|
||||
SubmissionReviewMessageValidator::class,
|
||||
];
|
||||
|
||||
// Filter out validators that cannot validate the message
|
||||
$applicableValidators = array_filter($availableValidators, function ($validator) use ($jwtBody) {
|
||||
return $validator::canValidate($jwtBody);
|
||||
});
|
||||
|
||||
// There should be 0-1 validators. This will either return the validator, or null if none apply.
|
||||
return array_shift($applicableValidators);
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ class LtiOidcLogin
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param IDatabase $database instance of the database interface used for looking up registrations and deployments
|
||||
* @param ICache $cache Instance of the Cache interface used to loading and storing launches. If non is provided launch data will be store in $_SESSION.
|
||||
* @param ICookie $cookie Instance of the Cookie interface used to set and read cookies. Will default to using $_COOKIE and setcookie.
|
||||
* @param IDatabase $database Instance of the Database interface used for looking up registrations and deployments
|
||||
* @param ICache $cache instance of the Cache interface used to loading and storing launches
|
||||
* @param ICookie $cookie instance of the Cookie interface used to set and read cookies
|
||||
*/
|
||||
public function __construct(IDatabase $database, ICache $cache = null, ICookie $cookie = null)
|
||||
{
|
||||
|
@ -2,11 +2,12 @@
|
||||
|
||||
namespace Packback\Lti1p3;
|
||||
|
||||
use Exception;
|
||||
use Firebase\JWT\JWT;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use Packback\Lti1p3\Interfaces\ICache;
|
||||
use Packback\Lti1p3\Interfaces\IHttpClient;
|
||||
use Packback\Lti1p3\Interfaces\IHttpException;
|
||||
use Packback\Lti1p3\Interfaces\IHttpResponse;
|
||||
use Packback\Lti1p3\Interfaces\ILtiRegistration;
|
||||
use Packback\Lti1p3\Interfaces\ILtiServiceConnector;
|
||||
use Packback\Lti1p3\Interfaces\IServiceRequest;
|
||||
@ -21,7 +22,7 @@ class LtiServiceConnector implements ILtiServiceConnector
|
||||
|
||||
public function __construct(
|
||||
ICache $cache,
|
||||
IHttpClient $client
|
||||
Client $client
|
||||
) {
|
||||
$this->cache = $cache;
|
||||
$this->client = $client;
|
||||
@ -100,7 +101,7 @@ class LtiServiceConnector implements ILtiServiceConnector
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getResponseHeaders(IHttpResponse $response): ?array
|
||||
public function getResponseHeaders(Response $response): ?array
|
||||
{
|
||||
$responseHeaders = $response->getHeaders();
|
||||
array_walk($responseHeaders, function (&$value) {
|
||||
@ -110,7 +111,7 @@ class LtiServiceConnector implements ILtiServiceConnector
|
||||
return $responseHeaders;
|
||||
}
|
||||
|
||||
public function getResponseBody(IHttpResponse $response): ?array
|
||||
public function getResponseBody(Response $response): ?array
|
||||
{
|
||||
$responseBody = (string) $response->getBody();
|
||||
|
||||
@ -127,7 +128,7 @@ class LtiServiceConnector implements ILtiServiceConnector
|
||||
|
||||
try {
|
||||
$response = $this->makeRequest($request);
|
||||
} catch (IHttpException $e) {
|
||||
} catch (ClientException $e) {
|
||||
$status = $e->getResponse()->getStatusCode();
|
||||
|
||||
// If the error was due to invalid authentication and the request
|
||||
@ -156,7 +157,7 @@ class LtiServiceConnector implements ILtiServiceConnector
|
||||
string $key = null
|
||||
): array {
|
||||
if ($request->getMethod() !== ServiceRequest::METHOD_GET) {
|
||||
throw new \Exception('An invalid method was specified by an LTI service requesting all items.');
|
||||
throw new Exception('An invalid method was specified by an LTI service requesting all items.');
|
||||
}
|
||||
|
||||
$results = [];
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Packback\Lti1p3\MessageValidators;
|
||||
|
||||
use Packback\Lti1p3\Interfaces\IMessageValidator;
|
||||
use Packback\Lti1p3\LtiConstants;
|
||||
use Packback\Lti1p3\LtiException;
|
||||
|
||||
abstract class AbstractMessageValidator implements IMessageValidator
|
||||
{
|
||||
abstract public static function getMessageType(): string;
|
||||
|
||||
public static function canValidate(array $jwtBody): bool
|
||||
{
|
||||
return $jwtBody[LtiConstants::MESSAGE_TYPE] === static::getMessageType();
|
||||
}
|
||||
|
||||
abstract public static function validate(array $jwtBody): void;
|
||||
|
||||
public static function validateGenericMessage(array $jwtBody): void
|
||||
{
|
||||
if (empty($jwtBody['sub'])) {
|
||||
throw new LtiException('Must have a user (sub)');
|
||||
}
|
||||
if (!isset($jwtBody[LtiConstants::VERSION])) {
|
||||
throw new LtiException('Missing LTI Version');
|
||||
}
|
||||
if ($jwtBody[LtiConstants::VERSION] !== LtiConstants::V1_3) {
|
||||
throw new LtiException('Incorrect version, expected 1.3.0');
|
||||
}
|
||||
if (!isset($jwtBody[LtiConstants::ROLES])) {
|
||||
throw new LtiException('Missing Roles Claim');
|
||||
}
|
||||
}
|
||||
}
|
@ -2,28 +2,20 @@
|
||||
|
||||
namespace Packback\Lti1p3\MessageValidators;
|
||||
|
||||
use Packback\Lti1p3\Interfaces\IMessageValidator;
|
||||
use Packback\Lti1p3\LtiConstants;
|
||||
use Packback\Lti1p3\LtiException;
|
||||
|
||||
class DeepLinkMessageValidator implements IMessageValidator
|
||||
class DeepLinkMessageValidator extends AbstractMessageValidator
|
||||
{
|
||||
public function canValidate(array $jwtBody)
|
||||
public static function getMessageType(): string
|
||||
{
|
||||
return $jwtBody[LtiConstants::MESSAGE_TYPE] === 'LtiDeepLinkingRequest';
|
||||
return LtiConstants::MESSAGE_TYPE_DEEPLINK;
|
||||
}
|
||||
|
||||
public function validate(array $jwtBody)
|
||||
public static function validate(array $jwtBody): void
|
||||
{
|
||||
if (empty($jwtBody['sub'])) {
|
||||
throw new LtiException('Must have a user (sub)');
|
||||
}
|
||||
if ($jwtBody[LtiConstants::VERSION] !== LtiConstants::V1_3) {
|
||||
throw new LtiException('Incorrect version, expected 1.3.0');
|
||||
}
|
||||
if (!isset($jwtBody[LtiConstants::ROLES])) {
|
||||
throw new LtiException('Missing Roles Claim');
|
||||
}
|
||||
static::validateGenericMessage($jwtBody);
|
||||
|
||||
if (empty($jwtBody[LtiConstants::DL_DEEP_LINK_SETTINGS])) {
|
||||
throw new LtiException('Missing Deep Linking Settings');
|
||||
}
|
||||
@ -37,7 +29,5 @@ class DeepLinkMessageValidator implements IMessageValidator
|
||||
if (empty($deep_link_settings['accept_presentation_document_targets'])) {
|
||||
throw new LtiException('Must support a presentation type');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2,35 +2,22 @@
|
||||
|
||||
namespace Packback\Lti1p3\MessageValidators;
|
||||
|
||||
use Packback\Lti1p3\Interfaces\IMessageValidator;
|
||||
use Packback\Lti1p3\LtiConstants;
|
||||
use Packback\Lti1p3\LtiException;
|
||||
|
||||
class ResourceMessageValidator implements IMessageValidator
|
||||
class ResourceMessageValidator extends AbstractMessageValidator
|
||||
{
|
||||
public function canValidate(array $jwtBody)
|
||||
public static function getMessageType(): string
|
||||
{
|
||||
return $jwtBody[LtiConstants::MESSAGE_TYPE] === 'LtiResourceLinkRequest';
|
||||
return LtiConstants::MESSAGE_TYPE_RESOURCE;
|
||||
}
|
||||
|
||||
public function validate(array $jwtBody)
|
||||
public static function validate(array $jwtBody): void
|
||||
{
|
||||
if (empty($jwtBody['sub'])) {
|
||||
throw new LtiException('Must have a user (sub)');
|
||||
}
|
||||
if (!isset($jwtBody[LtiConstants::VERSION])) {
|
||||
throw new LtiException('Missing LTI Version');
|
||||
}
|
||||
if ($jwtBody[LtiConstants::VERSION] !== LtiConstants::V1_3) {
|
||||
throw new LtiException('Incorrect version, expected 1.3.0');
|
||||
}
|
||||
if (!isset($jwtBody[LtiConstants::ROLES])) {
|
||||
throw new LtiException('Missing Roles Claim');
|
||||
}
|
||||
static::validateGenericMessage($jwtBody);
|
||||
|
||||
if (empty($jwtBody[LtiConstants::RESOURCE_LINK]['id'])) {
|
||||
throw new LtiException('Missing Resource Link Id');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2,35 +2,25 @@
|
||||
|
||||
namespace Packback\Lti1p3\MessageValidators;
|
||||
|
||||
use Packback\Lti1p3\Interfaces\IMessageValidator;
|
||||
use Packback\Lti1p3\LtiConstants;
|
||||
use Packback\Lti1p3\LtiException;
|
||||
|
||||
class SubmissionReviewMessageValidator implements IMessageValidator
|
||||
class SubmissionReviewMessageValidator extends AbstractMessageValidator
|
||||
{
|
||||
public function canValidate(array $jwtBody)
|
||||
public static function getMessageType(): string
|
||||
{
|
||||
return $jwtBody[LtiConstants::MESSAGE_TYPE] === 'LtiSubmissionReviewRequest';
|
||||
return LtiConstants::MESSAGE_TYPE_SUBMISSIONREVIEW;
|
||||
}
|
||||
|
||||
public function validate(array $jwtBody)
|
||||
public static function validate(array $jwtBody): void
|
||||
{
|
||||
if (empty($jwtBody['sub'])) {
|
||||
throw new LtiException('Must have a user (sub)');
|
||||
}
|
||||
if ($jwtBody[LtiConstants::VERSION] !== LtiConstants::V1_3) {
|
||||
throw new LtiException('Incorrect version, expected 1.3.0');
|
||||
}
|
||||
if (!isset($jwtBody[LtiConstants::ROLES])) {
|
||||
throw new LtiException('Missing Roles Claim');
|
||||
}
|
||||
static::validateGenericMessage($jwtBody);
|
||||
|
||||
if (empty($jwtBody[LtiConstants::RESOURCE_LINK]['id'])) {
|
||||
throw new LtiException('Missing Resource Link Id');
|
||||
}
|
||||
if (empty($jwtBody[LtiConstants::FOR_USER])) {
|
||||
throw new LtiException('Missing For User');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user