Skip to content

Commit

Permalink
Merge pull request #127 from packbackbooks/v6.0-beta
Browse files Browse the repository at this point in the history
v6.0 beta
  • Loading branch information
dbhynds authored Feb 14, 2024
2 parents b09f311 + df9b2da commit beabf63
Showing 84 changed files with 2,696 additions and 2,163 deletions.
10 changes: 5 additions & 5 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -92,16 +92,16 @@ function lint_php {
return 0 # There's nothing to lint.
fi

phpcsfixer="vendor/bin/php-cs-fixer"
pint="vendor/bin/pint"

if ! [ -x "$phpcsfixer" ]; then
echo -e "${C_RED}PHP-CS-Fixer is not installed. Install it with \`composer install\`.${NO_FORMAT}" && return 1
if ! [ -x "$pint" ]; then
echo -e "${C_RED}Pint is not installed. Install it with \`composer install\`.${NO_FORMAT}" && return 1
fi

php_files_arg=$(echo "$php_files" | tr '\n' ' ')

echo -e "${C_CYAN}Linting PHP-CS-Fixer...${NO_FORMAT}"
$phpcsfixer fix -q || return 1
echo -e "${C_CYAN}Linting Pint...${NO_FORMAT}"
$pint || return 1

git add $php_files_arg
}
25 changes: 22 additions & 3 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
name: Tests & style checks
name: Tests & Style Checks
on:
# Trigger on any PR being opened, or on a merge to master (to update the badge)
# Trigger on any PR being opened
pull_request:
# Or weekly and on a merge to master (to update the badge)
push:
branches:
- master
schedule:
- cron: 0 0 * * 0
jobs:
lint:
name: Lint
@@ -21,7 +24,7 @@ jobs:
strategy:
matrix:
php:
- "7.4"
- "8.0"
- "latest"
steps:
- uses: "actions/checkout@v3"
@@ -34,3 +37,19 @@ jobs:
composer-options: "${{ matrix.composer-options }}"
- name: Run tests
run: composer test

coverage:
name: Code Coverage
runs-on: ubuntu-latest
steps:
- uses: "actions/checkout@v3"
- uses: "shivammathur/setup-php@v2"
with:
php-version: latest
coverage: xdebug
- uses: "ramsey/composer-install@v2"
- uses: paambaati/codeclimate-action@v5.0.0
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageCommand: composer test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
.phpunit.result.cache
.php_cs.cache
.php-cs-fixer.cache
.pint.cache
.vscode

build
@@ -14,4 +15,5 @@ tests/_support/_generated/*
vendor

# ignore the coverage folders
**/.phpunit.cache
**/coverage
21 changes: 0 additions & 21 deletions .php-cs-fixer.php

This file was deleted.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# LTI 1.3 Tool Library

![Test status](https://github.com/packbackbooks/lti-1-3-php-library/actions/workflows/run_tests.yml/badge.svg?branch=master)
![Test status](https://github.com/packbackbooks/lti-1-3-php-library/actions/workflows/run_tests.yml/badge.svg?branch=master) [![Maintainability](https://api.codeclimate.com/v1/badges/16055e83ea04ad95a2f9/maintainability)](https://codeclimate.com/github/packbackbooks/lti-1-3-php-library/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/16055e83ea04ad95a2f9/test_coverage)](https://codeclimate.com/github/packbackbooks/lti-1-3-php-library/test_coverage)

A library used for building IMS-certified LTI 1.3 tool providers in PHP.

@@ -34,7 +34,7 @@ This library uses three methods for storing and accessing data: cache, cookie, a
- `Packback\Lti1p3\Interfaces\ICookie`
- `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.
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).

### Create a JWKS endpoint

9 changes: 5 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -2,10 +2,11 @@

## Supported Versions

| Version | Supported |
| ------- | ------------------ |
| 5.0.x | :white_check_mark: |
| < 5.0 | :x: |
| Version | Supported |
| ------- | --------------------------------- |
| 6.0.x | :white_check_mark: Active support |
| 5.7.x | :wrench: Security fixes only |
| < 5.7 | :x: End of life |

## Reporting a Vulnerability

100 changes: 100 additions & 0 deletions UPGRADES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,103 @@
## 5.x to 6.0

### HIGH LIKELIHOOD OF IMPACT: Changes to `LtiMessageLaunch`

When handling a new launch, the new `initialize()` method should be used instead of the previous `validate()` method. The validate method no longer accepts arguments, and requires that the request be set on the message launch object first (which happens in `initialize()`). This fixes some separation-of-concern issues with the `validate()` method, and allows for seamless integration of LTI 1.1 to 1.3 migrations if enabled.

```php
// instead of doing this:
$message->validate($request);

// you should do this:
$message->inilialize($request);
```

### HIGH LIKELIHOOD OF IMPACT: Changed how the OIDC Login URL is retrieved, deprecated the `Redirect` object

When redirecting to the OIDC Login URL, the `Packback\Lti1p3\LtiOidcLogin::getOidcLoginUrl()` method should be used to retrieve the URL. Your application should use this to build the redirect response in whatever way is appropriate for your framework. This replaces `Packback\Lti1p3\LtiOidcLogin::doOidcLoginRedirect()`, which returned a `Redirect` object. See: https://github.com/packbackbooks/lti-1-3-php-library/pull/116

```php
// instead of doing this:
$redirect = $oidLogin->doOidcLoginRedirect($launchUrl, $request);
return redirect($redirect->getRedirectUrl());

// you should do this:
return redirect($oidLogin->getRedirectUrl($launchUrl, $request));
```

### HIGH LIKELIHOOD OF IMPACT - Strict typing added

All arguments and returns are now strictly typed. This includes interfaces that require custom implementations. Notable changes:

```php
Packback\Lti1p3\Interfaces\ICookie
setCookie(string $name, string $value, int $exp = 3600, array $options = []): void;

Packback\Lti1p3\Interfaces\IDatabase
findRegistrationByIssuer(string $iss, ?string $clientId = null): ?ILtiRegistration;
findDeployment(string $iss, string $deploymentId, ?string $clientId = null): ?ILtiDeployment;

Packback\Lti1p3\Interfaces\IMigrationDatabase
migrateFromLti1p1(LtiMessageLaunch $launch): ?ILtiDeployment;
```

### Dropped support for PHP 7 and PHP-JWT 5

This library now requires PHP 8 and firebase/php-jwt 6.

### `Packback\Lti1p3\DeepLinkResource*` objects moved to their own namespace

Objects named `DeepLinkResource*` have been moved to their own namespace: `Packback\Lti1p3\DeepLinkResources`. The following classes have been moved:

- `Packback\Lti1p3\DeepLinkResourceDateTimeInterval` is now `Packback\Lti1p3\DeepLinkResources\DateTimeInterval`
- `Packback\Lti1p3\DeepLinkResourceIcon` is now `Packback\Lti1p3\DeepLinkResources\Icon`
- `Packback\Lti1p3\DeepLinkResourceIframe` is now `Packback\Lti1p3\DeepLinkResources\Iframe`
- `Packback\Lti1p3\DeepLinkResource` is now `Packback\Lti1p3\DeepLinkResources\Resource`
- `Packback\Lti1p3\DeepLinkResourceWindow` is now `Packback\Lti1p3\DeepLinkResources\Window`

### `Packback\Lti1p3\DeepLinkResources\Iframe` constructor arguments changed order

To make the interface consistent with other deep link resources, `src` is now the first argument in the constructor:

```php
class Iframe
{
public function __construct(
private ?string $src = null,
private ?int $width = null,
private ?int $height = null
) {
}
}
```

### Removed `ImsStorage` classes

Everything in the `Packback\Lti1p3\ImsStorage` namespace has been removed, specifically the `Packback\Lti1p3\ImsStorage\ImsCache` and `Packback\Lti1p3\ImsStorage\ImsCookie`. If you were using these classes, you will need to implement your own custom storage services. See the [Laravel Implementation Guide](https://github.com/packbackbooks/lti-1-3-php-library/wiki/Laravel-Implementation-Guide#sample-data-store-implementations) for an example.

### Removed deprecated methods and classes

The following classes have been removed:

* `Packback\Lti1p3\ImsStorage\ImsCache`
* `Packback\Lti1p3\ImsStorage\ImsCookie`
* `Packback\Lti1p3\Redirect`

The following methods have been removed:

* `Packback\Lti1p3\JwksEndpoint::outputJwks()` - use `getPublicJwks()` to build your own output
* `Packback\Lti1p3\LtiDeepLink::outputResponseForm()` - use `getResponseJwt()` to build your own output
* `Packback\Lti1p3\LtiDeepLinkResources\Resource::getTarget()` - consider using `getIframe()` or `getWindow()` instead
* `Packback\Lti1p3\LtiDeepLinkResources\Resource::setTarget()` - consider using `setIframe()` or `setWindow()` instead
* `Packback\Lti1p3\Redirect::doHybridRedirect()`
* `Packback\Lti1p3\Redirect::getRedirectUrl()`

### Changes to method signatures

* When instantiating `LtiMessageLaunch`, `LtiOidcLogin`, and `LtiServiceConnector` objects, all arguments are required now (instead of some being optional).
* `Lti1p1Key` methods `setKey()` and `setSecret()` accept strings instead of arrays.
* `LtiServiceConnector::setDebuggingMode()` now returns self instead of void.

## 5.6 to 5.7

No breaking changes were introduced. However, going forward when processing a `LtiOidcLogin`, it is recommended to use the new `getRedirectUrl()` method:
14 changes: 9 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
@@ -21,15 +21,16 @@
}
],
"require": {
"firebase/php-jwt": "^5.5|^6.0",
"firebase/php-jwt": "^6.6",
"guzzlehttp/guzzle": "^7.0",
"phpseclib/phpseclib": "^3.0"
},
"require-dev": {
"jubeki/laravel-code-style": "^1.0|^2.0",
"mockery/mockery": "^1.4",
"nesbot/carbon": "^2.43",
"phpunit/phpunit": "^9.5"
"laravel/pint": "^1.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.0|^10.0"
},
"autoload": {
"psr-4": {
@@ -43,7 +44,10 @@
},
"scripts": {
"test": "phpunit",
"lint": "php-cs-fixer fix -v --dry-run",
"lint-fix": "php-cs-fixer fix -v"
"lint": [
"pint --test",
"phpstan analyse"
],
"lint-fix": "pint -v"
}
}
31 changes: 31 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
parameters:
level: 5
paths:
- src
- tests

ignoreErrors:
-
message: "#^Call to an undefined method Packback\\\\Lti1p3\\\\Interfaces\\\\IDatabase\\:\\:[a-zA-Z0-9]+\\(\\)\\.$#"
count: 3
path: src/LtiMessageLaunch.php

-
message: "#Call to an undefined method Mockery\\\\#"
paths:
- tests/*

-
message: "# Mockery\\\\(Legacy)*MockInterface given\\.$#"
paths:
- tests/*

-
message: "# \\(Mockery\\\\MockInterface\\) does not accept Mockery\\\\LegacyMockInterface\\.$#"
paths:
- tests/*

-
message: "#^Result of static method Packback\\\\Lti1p3\\\\MessageValidators\\\\[A-Za-z]+MessageValidator\\:\\:validate\\(\\) \\(void\\) is used\\.$#"
path: tests/MessageValidators/*

10 changes: 6 additions & 4 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" backupStaticAttributes="false" colors="true" verbose="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<coverage>
<include>
<directory suffix=".php">src/</directory>
</include>
<report>
<clover outputFile="build/logs/clover.xml"/>
<html outputDirectory="build/coverage"/>
@@ -18,4 +15,9 @@
<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>
<source>
<include>
<directory suffix=".php">src/</directory>
</include>
</source>
</phpunit>
13 changes: 13 additions & 0 deletions pint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"preset": "laravel",
"cache-file": ".pint.cache",
"rules": {
"not_operator_with_successor_space": false,
"class_attributes_separation": {
"elements": {
"const": "only_if_meta",
"property": "only_if_meta"
}
}
}
}
15 changes: 15 additions & 0 deletions src/Concerns/Arrayable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Packback\Lti1p3\Concerns;

use Packback\Lti1p3\Helpers\Helpers;

trait Arrayable
{
abstract public function getArray(): array;

public function toArray(): array
{
return Helpers::filterOutNulls($this->getArray());
}
}
13 changes: 13 additions & 0 deletions src/Concerns/JsonStringable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Packback\Lti1p3\Concerns;

trait JsonStringable
{
use Arrayable;

public function __toString(): string
{
return json_encode($this->toArray());
}
}
Loading
Oops, something went wrong.

0 comments on commit beabf63

Please sign in to comment.