Skip to content

Commit

Permalink
Merge pull request #99 from packbackbooks/mgmt-132-migrations
Browse files Browse the repository at this point in the history
MGMT-132: Supporting migrations
  • Loading branch information
dbhynds authored Dec 4, 2023
2 parents f6a7fd8 + 186e1f5 commit 1860139
Show file tree
Hide file tree
Showing 19 changed files with 802 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
.phpunit.result.cache
.php_cs.cache
.php-cs-fixer.cache
.vscode

build
composer.lock
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ This library uses three methods for storing and accessing data: cache, cookie, a

- `Packback\Lti1p3\Interfaces\ICache`
- `Packback\Lti1p3\Interfaces\ICookie`
- `Packback\Lti1p3\Interfaces\IDatabase`
- `Packback\Lti1p3\Interfaces\IDatabase` or optionally `Packback\Lti1p3\Interfaces\IMigrationDatabase`

View the [Laravel Implementation Guide](https://github.com/packbackbooks/lti-1-3-php-library/wiki/Laravel-Implementation-Guide) to see examples (or copy/paste the code outright). Cache and Cookie storage have legacy implementations at `Packback\Lti1p3\ImsStorage\` if you do not wish to implement your own. However, you must implement your own database.

Expand Down
4 changes: 4 additions & 0 deletions UPGRADES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.5 to 5.6

No breaking changes were introduced. However, going forward when processing a `LtiMessageLaunch`, it is recommended to do `$message->initialize($request);` instead of the previous `$message->validate($request);` to support potential migrations.

## 4.0 to 5.0

### Changes to `ICache` methods
Expand Down
3 changes: 3 additions & 0 deletions src/ImsStorage/ImsCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use Packback\Lti1p3\Interfaces\ICache;

/**
* @todo Deprecate this in the next major version
*/
class ImsCache implements ICache
{
private $cache;
Expand Down
3 changes: 3 additions & 0 deletions src/ImsStorage/ImsCookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use Packback\Lti1p3\Interfaces\ICookie;

/**
* @todo Deprecate this in the next major version
*/
class ImsCookie implements ICookie
{
public function getCookie(string $name): ?string
Expand Down
35 changes: 35 additions & 0 deletions src/Interfaces/IMigrationDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Packback\Lti1p3\Interfaces;

use Packback\Lti1p3\LtiDeployment;
use Packback\Lti1p3\LtiMessageLaunch;

/**
* This is an optional interface if an LTI 1.3 tool supports migrations
* from LTI 1.1 compatible installations.
*
* To use this, just have whatever class you create that implements IDatabase
* also implement this interface.
*/
interface IMigrationDatabase extends IDatabase
{
/**
* Using the LtiMessageLaunch return an array of matching LTI 1.1 keys
*
* @return array<\Packback\Lti1p3\Lti1p1Key>
*/
public function findLti1p1Keys(LtiMessageLaunch $launch): array;

/**
* Given an LtiMessageLaunch, return true if this tool should migrate from 1.1 to 1.3
*/
public function shouldMigrate(LtiMessageLaunch $launch): bool;

/**
* This method should create a 1.3 deployment in your DB based on the LtiMessageLaunch.
* Previous to this, we validated the oauth_consumer_key_sign to ensure this migration
* can safely occur.
*/
public function migrateFromLti1p1(LtiMessageLaunch $launch): ?LtiDeployment;
}
3 changes: 3 additions & 0 deletions src/JwksEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public function getPublicJwks()
return ['keys' => $jwks];
}

/**
* @todo: Deprecate this in the next major version
*/
public function outputJwks()
{
echo json_encode($this->getPublicJwks());
Expand Down
68 changes: 68 additions & 0 deletions src/Lti1p1Key.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Packback\Lti1p3;

/**
* Used for migrations from LTI 1.1 to LTI 1.3
*
* @see IMigrationDatabase
*/
class Lti1p1Key
{
private $key;
private $secret;

public function __construct(array $key = null)
{
$this->key = $key['key'] ?? null;
$this->secret = $key['secret'] ?? null;
}

public function getKey()
{
return $this->key;
}

public function setKey(array $key)
{
$this->key = $key;

return $this;
}

public function getSecret()
{
return $this->secret;
}

public function setSecret(array $secret)
{
$this->secret = $secret;

return $this;
}

/**
* Create a signature using the key and secret
*
* @see https://www.imsglobal.org/spec/lti/v1p3/migr#oauth_consumer_key_sign
*/
public function sign(string $deploymentId, string $iss, string $clientId, string $exp, string $nonce): string
{
$signatureComponents = [
$this->getKey(),
$deploymentId,
$iss,
$clientId,
$exp,
$nonce,
];

$baseString = implode('&', $signatureComponents);
$utf8String = mb_convert_encoding($baseString, 'utf8', mb_detect_encoding($baseString));
$hash = hash_hmac('sha256', $utf8String, $this->getSecret(), true);

return base64_encode($hash);
}

}
7 changes: 4 additions & 3 deletions src/LtiConstants.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ class LtiConstants

// Optional message claims
public const CONTEXT = 'https://purl.imsglobal.org/spec/lti/claim/context';
public const TOOL_PLATFORM = 'https://purl.imsglobal.org/spec/lti/claim/tool_platform';
public const ROLE_SCOPE_MENTOR = 'https://purlimsglobal.org/spec/lti/claim/role_scope_mentor';
public const CUSTOM = 'https://purl.imsglobal.org/spec/lti/claim/custom';
public const LAUNCH_PRESENTATION = 'https://purl.imsglobal.org/spec/lti/claim/launch_presentation';
public const LIS = 'https://purl.imsglobal.org/spec/lti/claim/lis';
public const CUSTOM = 'https://purl.imsglobal.org/spec/lti/claim/custom';
public const LTI1P1 = 'https://purl.imsglobal.org/spec/lti/claim/lti1p1';
public const ROLE_SCOPE_MENTOR = 'https://purlimsglobal.org/spec/lti/claim/role_scope_mentor';
public const TOOL_PLATFORM = 'https://purl.imsglobal.org/spec/lti/claim/tool_platform';

// LTI DL
public const DL_CONTENT_ITEMS = 'https://purl.imsglobal.org/spec/lti-dl/claim/content_items';
Expand Down
1 change: 1 addition & 0 deletions src/LtiDeepLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function getResponseJwt($resources)
*
* @todo Consider wrapping the content inside a well-formed HTML document,
* and returning it instead of directly writing to standard output
* @todo Deprecate this in the next major version
*/
public function outputResponseForm($resources)
{
Expand Down
2 changes: 2 additions & 0 deletions src/LtiGrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ public function getCanvasExtension()
* is unexpected data. And, the type of LMS cannot simply be inferred by their URL.
*
* @see https://documentation.instructure.com/doc/api/score.html
*
* @todo: Deprecate this in the next major version
*/
public function setCanvasExtension($value)
{
Expand Down
Loading

0 comments on commit 1860139

Please sign in to comment.