Skip to content

Commit

Permalink
Merge pull request #3 from talis/php55_build
Browse files Browse the repository at this point in the history
Refactor for build and standards, supporting PHP 5.5
  • Loading branch information
rsinger authored Dec 9, 2021
2 parents 1a3c335 + 9f691e3 commit bd9237d
Show file tree
Hide file tree
Showing 51 changed files with 2,051 additions and 152 deletions.
35 changes: 35 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: 2.1

jobs:
linting:
machine:
image: ubuntu-2004:202107-02
steps:
- checkout
- run: docker-compose run composer install
- run: docker-compose run php70 ./vendor/bin/phpcs ./src
test-php55:
machine:
image: ubuntu-2004:202107-02
steps:
- checkout
- run: docker-compose run composer install
- run: docker-compose run phpunit55 tests/unit
test-php70:
machine:
image: ubuntu-2004:202107-02
steps:
- checkout
- run: docker-compose run composer install
- run: docker-compose run phpunit70 tests/unit

workflows:
build_and_test:
jobs:
- linting
- test-php55:
requires:
- linting
- test-php70:
requires:
- linting
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ src/game_example/db/keys/*
src/game_example/db/configs/local.json
.env
.DS_Store
.cache/composer
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Example_Database implements LTI\Database {

The `find_registration_by_issuer` method must return an `LTI\LTI_Registration`.
```php
return LTI\LTI_Registration::new()
return LTI\LTI_Registration::newInstance()
->set_auth_login_url($auth_login_url)
->set_auth_token_url($auth_token_url)
->set_client_id($client_id)
Expand All @@ -61,7 +61,7 @@ return LTI\LTI_Registration::new()

The `find_deployment` method must return an `LTI\LTI_Deployment` if it exists within the database.
```php
return LTI\LTI_Deployment::new()
return LTI\LTI_Deployment::newInstance()
->set_deployment_id($deployment_id);
```

Expand All @@ -75,7 +75,7 @@ LTI\JWKS_Endpoint::from_issuer(new Example_Database(), 'http://example.com')->ou
// From registration
LTI\JWKS_Endpoint::from_registration($registration)->output_jwks();
// From array
LTI\JWKS_Endpoint::new(['a_unique_KID' => file_get_contents('/path/to/private/key.pem')])->output_jwks();
LTI\JWKS_Endpoint::newInstance(['a_unique_KID' => file_get_contents('/path/to/private/key.pem')])->output_jwks();
```

## Handling Requests
Expand All @@ -85,7 +85,7 @@ LTI 1.3 uses a modified version of the OpenId Connect third party initiate login

To handle this request, you must first create a new `LTI\LTI_OIDC_Login` object.
```php
$login = LTI_OIDC_Login::new(new Example_Database());
$login = LTI_OIDC_Login::newInstance(new Example_Database());
```

Now you must configure your login request with a return url (this must be preconfigured and white-listed on the tool).
Expand Down Expand Up @@ -121,7 +121,7 @@ Redirect is now done, we can move onto the launch.
### LTI Message Launches
Now that we have done the OIDC log the platform will launch back to the tool. To handle this request, first we need to create a new `LTI\LTI_Message_Launch` object.
```php
$launch = LTI\LTI_Message_Launch::new(new Example_Database());
$launch = LTI\LTI_Message_Launch::newInstance(new Example_Database());
```

Once we have the message launch, we can validate it. This will check signatures and the presence of a deployment and any required parameters.
Expand Down Expand Up @@ -191,7 +191,7 @@ $dl = $launch->get_deep_link();

Now we are going to need to create `LTI\LTI_Deep_Link_Resource` to return.
```php
$resource = LTI\LTI_Deep_Link_Resource::new()
$resource = LTI\LTI_Deep_Link_Resource::newInstance()
->set_url("https://my.tool/launch")
->set_custom_params(['my_param' => $my_param])
->set_title('My Resource');
Expand Down Expand Up @@ -244,7 +244,7 @@ $ags = $launch->get_ags();

To pass a grade back to the platform, you will need to create an `LTI\LTI_Grade` object and populate it with the necessary information.
```php
$grade = LTI\LTI_Grade::new()
$grade = LTI\LTI_Grade::newInstance()
->set_score_given($grade)
->set_score_maximum(100)
->set_timestamp(date(DateTime::ISO8601))
Expand All @@ -261,7 +261,7 @@ This will put the grade into the default provided lineitem. If no default lineit

If you want to send multiple types of grade back, that can be done by specifying an `LTI\LTI_Lineitem`.
```php
$lineitem = LTI\LTI_Lineitem::new()
$lineitem = LTI\LTI_Lineitem::newInstance()
->set_tag('grade')
->set_score_maximum(100)
->set_label('Grade');
Expand Down
15 changes: 14 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,25 @@
"type": "library",
"require": {
"fproject/php-jwt": "^4.0",
"phpseclib/phpseclib": "^2.0"
"phpseclib/phpseclib": "^2.0",
"paragonie/random_compat": "<9.99"
},
"require-dev": {
"phpunit/phpunit": "4.8.36",
"squizlabs/php_codesniffer": "3.5.8"
},
"autoload": {
"psr-4": {
"IMSGlobal\\LTI\\": "src/lti"
}
},
"autoload-dev": {
"psr-4": { "IMSGlobal\\LTI\\Tests\\": "tests/" }
},
"config": {
"platform": {
"php": "5.5.9"
}
},
"authors": [
{
Expand Down
35 changes: 35 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: '3.7'
services:
composer:
image: composer:latest
environment:
- COMPOSER_CACHE_DIR=/app/.cache/composer
volumes:
- .:/app
restart: never
php55:
image: php:5.5-cli
volumes:
- .:/app
working_dir: /app
restart: never
php70:
image: php:7.0-cli
volumes:
- .:/app
working_dir: /app
restart: never
phpunit55:
image: php:5.5-cli
restart: never
volumes:
- .:/app
working_dir: /app
entrypoint: vendor/bin/phpunit
phpunit70:
image: php:7.0-cli
restart: never
volumes:
- .:/app
working_dir: /app
entrypoint: vendor/bin/phpunit
47 changes: 47 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0"?>
<ruleset name="LTI1p3PHPLibrary">
<config name="ignore_warnings_on_exit" value="1"/>
<arg name="extensions" value="php" />
<exclude-pattern>*/src/lti/LTI_Assignments_Grades_Service.php</exclude-pattern>
<exclude-pattern>*/src/lti/LTI_Course_Groups_Service.php</exclude-pattern>
<!-- Generic -->
<rule ref="Generic.Arrays.DisallowLongArraySyntax" />
<rule ref="Generic.Classes.OpeningBraceSameLine" />
<rule ref="Generic.Commenting.DocComment">
<!-- Allow single-line doc comments. See https://github.com/squizlabs/PHP_CodeSniffer/issues/258. -->
<exclude name="Generic.Commenting.DocComment.ContentAfterOpen" />
<exclude name="Generic.Commenting.DocComment.ContentBeforeClose" />
<exclude name="Generic.Commenting.DocComment.MissingShort" />
</rule>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="120" />
<property name="absoluteLineLimit" value="0" />
<property name="ignoreComments" value="true" />
</properties>
</rule>
<rule ref="Generic.Files.OneClassPerFile" />
<rule ref="Generic.Files.OneInterfacePerFile" />
<rule ref="Generic.Files.OneObjectStructurePerFile" />
<rule ref="Generic.Files.OneTraitPerFile" />
<rule ref="Generic.NamingConventions.UpperCaseConstantName" />
<rule ref="Generic.PHP.NoSilencedErrors" />
<rule ref="Generic.WhiteSpace.DisallowTabIndent" />
<!-- PEAR -->
<rule ref="PEAR.NamingConventions.ValidClassName" />
<!-- Squiz -->
<rule ref="Squiz.Commenting.FunctionComment">
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude name="Squiz.Commenting.FunctionComment.MissingReturn" />
<exclude name="Squiz.Commenting.FunctionComment.ParamCommentNotCapital" />
<exclude name="Squiz.Commenting.FunctionComment.ParamCommentFullStop" />
<exclude name="Squiz.Commenting.FunctionComment.ThrowsNoFullStop" />
<exclude name="Squiz.Commenting.FunctionComment.SpacingAfterParamType" />
<exclude name="Squiz.Commenting.FunctionComment.SpacingAfterParamName" />
<exclude name="Squiz.Commenting.FunctionComment.ScalarTypeHintMissing" />
<exclude name="Squiz.Commenting.InlineComment.DocBlock" />
</rule>
<rule ref="Squiz.Commenting.FunctionComment.Missing">
<type>warning</type>
</rule>
</ruleset>
88 changes: 42 additions & 46 deletions src/lti/Cache.php
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
<?php
namespace IMSGlobal\LTI;

class Cache {

private $cache;

public function get_launch_data($key) {
$this->load_cache();
return $this->cache[$key];
}

public function cache_launch_data($key, $jwt_body) {
$this->cache[$key] = $jwt_body;
$this->save_cache();
return $this;
}

public function cache_nonce($nonce) {
$this->cache['nonce'][$nonce] = true;
$this->save_cache();
return $this;
}

public function check_nonce($nonce) {
$this->load_cache();
if (!isset($this->cache['nonce'][$nonce])) {
return false;
}
return true;
}

private function load_cache() {
$cache = file_get_contents(sys_get_temp_dir() . '/lti_cache.txt');
if (empty($cache)) {
file_put_contents(sys_get_temp_dir() . '/lti_cache.txt', '{}');
$this->cache = [];
}
$this->cache = json_decode($cache, true);
}

private function save_cache() {
file_put_contents(sys_get_temp_dir() . '/lti_cache.txt', json_encode($this->cache));
}
}
?>
<?php

namespace IMSGlobal\LTI;

interface Cache {
/**
* Returns the cached launch data JWT body, if it exists
*
* @param string $key
*
* @return string|null JWT body
*/
public function get_launch_data($key);

/**
* Stores the lauch data JWT body
*
* @param string $key
* @param string $jwt_body
*
* @return $this
*/
public function cache_launch_data($key, $jwt_body);

/**
* Stores the request nonce
*
* @param string $nonce
*
* @return $this
*/
public function cache_nonce($nonce);

/**
* Checks the validity of the nonce
*
* @param string $nonce
*
* @return boolean
*/
public function check_nonce($nonce);
}
47 changes: 43 additions & 4 deletions src/lti/Cookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
namespace IMSGlobal\LTI;

class Cookie {
/**
* Get a cookie, if defined. Will look for the $name prefixed with "LEGACY_" if not found
*
* @param string $name Cookie name
*
* @return mixed|boolean
*/
public function get_cookie($name) {
if (isset($_COOKIE[$name])) {
return $_COOKIE[$name];
Expand All @@ -13,7 +20,17 @@ public function get_cookie($name) {
return false;
}

public function set_cookie($name, $value, $exp = 3600, $options = []) {
/**
* Sets a cookie
*
* @param string $name Cookie name
* @param mixed $value Cookie value
* @param integer $exp Time to live
* @param array $options set_cookie options
*
* @return $this
*/
public function set_cookie($name, $value, $exp = 3600, array $options = []) {
$cookie_options = [
'expires' => time() + $exp
];
Expand All @@ -24,11 +41,33 @@ public function set_cookie($name, $value, $exp = 3600, $options = []) {
'secure' => true
];

setcookie($name, $value, array_merge($cookie_options, $same_site_options, $options));
self::setcookie73($name, $value, array_merge($cookie_options, $same_site_options, $options));

// Set a second fallback cookie in the event that "SameSite" is not supported
setcookie("LEGACY_" . $name, $value, array_merge($cookie_options, $options));
self::setcookie73("LEGACY_" . $name, $value, array_merge($cookie_options, $options));
return $this;
}

/**
* Add support for the PHP7.3+ `setcookie` with options, in a <PHP7.3-friendly way
*
* @param string $name The name of the cookie to set
* @param mixed $value The cookie value
* @param array $options Cookie options
*
* @return void
*/
private static function setcookie73($name, $value, array $options) {
$expires = isset($options['expires']) ? $options['expires'] : 0;
$path = isset($options['path']) ? $options['path'] : '/';
$domain = isset($options['domain']) ? $options['domain'] : '';
$secure = isset($options['secure']) ? $options['secure'] : false;
$httponly = isset($options['httponly']) ? $options['httponly'] : false;

// samesite can only be represented as a hack before PHP7.3
$samesite = isset($options['samesite']) ? $options['samesite'] : null;
$pathWithSamesiteHack = is_null($samesite) ? $path : "$path; SameSite=$samesite";

setcookie($name, $value, $expires, $pathWithSamesiteHack, $domain, $secure, $httponly);
}
}
?>
Loading

0 comments on commit bd9237d

Please sign in to comment.