Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/core 5.0.0 #17

Merged
merged 4 commits into from
Apr 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ before_script:
script:
- mkdir -p build/logs
- ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
- ./vendor/bin/psalm --shepherd

after_script:
- ./vendor/bin/php-coveralls -v
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
CHANGELOG
=========

5.0.0
-----

* Added psalm support
* Deleted MembershipServiceServer in favor to MembershipServiceServerRequestHandler (to be used with core LtiServiceServer)
* Updated oat-sa/lib-lti1p3-core dependency to version 5.0
* Updated MembershipServiceServerBuilderInterface parameters to work with registration
* Updated MembershipServiceClient (to work with core LtiServiceClient)
* Updated overall constructors to handle nullable parameters
* Updated documentation

4.0.0
-----

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
[![Latest Version](https://img.shields.io/github/tag/oat-sa/lib-lti1p3-nrps.svg?style=flat&label=release)](https://github.com/oat-sa/lib-lti1p3-nrps/tags)
[![License GPL2](http://img.shields.io/badge/licence-GPL%202.0-blue.svg)](http://www.gnu.org/licenses/gpl-2.0.html)
[![Build Status](https://travis-ci.org/oat-sa/lib-lti1p3-nrps.svg?branch=master)](https://travis-ci.org/oat-sa/lib-lti1p3-nrps)
[![Coverage Status](https://coveralls.io/repos/github/oat-sa/lib-lti1p3-nrps/badge.svg?branch=master)](https://coveralls.io/github/oat-sa/lib-lti1p3-nrps?branch=master)
[![Test Coverage Status](https://coveralls.io/repos/github/oat-sa/lib-lti1p3-nrps/badge.svg?branch=master)](https://coveralls.io/github/oat-sa/lib-lti1p3-nrps?branch=master)
[![Psalm Level Status](https://shepherd.dev/github/oat-sa/lib-lti1p3-nrps/level.svg)](https://shepherd.dev/github/oat-sa/lib-lti1p3-nrps)
[![Packagist Downloads](http://img.shields.io/packagist/dt/oat-sa/lib-lti1p3-nrps.svg)](https://packagist.org/packages/oat-sa/lib-lti1p3-nrps)

> PHP library for [LTI 1.3 Names and Role Provisioning Services](https://www.imsglobal.org/spec/lti-nrps/v2p0) implementations as platforms and / or as tools, based on [LTI 1.3 Core library](https://github.com/oat-sa/lib-lti1p3-core).
Expand Down
9 changes: 7 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
"require": {
"ext-json": "*",
"php": ">=7.2.0",
"oat-sa/lib-lti1p3-core": "^4.0"
"oat-sa/lib-lti1p3-core": "^5.0"
},
"require-dev": {
"phpunit/phpunit": "8.5.14",
"php-coveralls/php-coveralls": "^2.4"
"php-coveralls/php-coveralls": "^2.4",
"psalm/plugin-phpunit": "^0.15.1",
"vimeo/psalm": "^4.6"
},
"autoload": {
"psr-4": {
Expand All @@ -22,5 +24,8 @@
"OAT\\Library\\Lti1p3Nrps\\Tests\\": "tests/",
"OAT\\Library\\Lti1p3Core\\Tests\\": "vendor/oat-sa/lib-lti1p3-core/tests/"
}
},
"config": {
"sort-packages": true
}
}
48 changes: 28 additions & 20 deletions doc/platform.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NRPS Platform - Membership service server

> How to use the [MembershipServiceServer](../src/Service/Server/MembershipServiceServer.php) to serve authenticated NRPS service calls as a platform.
> How to use the [MembershipServiceServerRequestHandler](../src/Service/Server/Handler/MembershipServiceServerRequestHandler.php) (with the core [LtiServiceServer](https://github.com/oat-sa/lib-lti1p3-core/blob/master/src/Service/Server/LtiServiceServer.php)) to serve authenticated NRPS service calls as a platform.

## Table of contents

Expand All @@ -9,7 +9,7 @@

## Features

This library provides a [MembershipServiceServer](../src/Service/Server/MembershipServiceServer.php) ready to handle context and resource link membership requests.
This library provides a [MembershipServiceServerRequestHandler](../src/Service/Server/Handler/MembershipServiceServerRequestHandler.php) ready to be use with the core [LtiServiceServer](https://github.com/oat-sa/lib-lti1p3-core/blob/master/src/Service/Server/LtiServiceServer.php) to handle context and resource link membership requests.

- it accepts a [PSR7 ServerRequestInterface](https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface),
- leverages the [required IMS LTI 1.3 service authentication](https://www.imsglobal.org/spec/security/v1p0/#securing_web_services),
Expand All @@ -30,47 +30,55 @@ use OAT\Library\Lti1p3Nrps\Service\Server\Builder\MembershipServiceServerBuilder
$builder = new class() implements MembershipServiceServerBuilderInterface
{
public function buildContextMembership(
string $role = null,
int $limit = null,
int $offset = null
RegistrationInterface $registration,
?string $role = null,
?int $limit = null,
?int $offset = null
): MembershipInterface {
// Logic for building context membership for a given registration
}

public function buildResourceLinkMembership(
RegistrationInterface $registration,
string $resourceLinkIdentifier,
string $role = null,
int $limit = null,
int $offset = null
?string $role = null,
?int $limit = null,
?int $offset = null
): MembershipInterface {
// Logic for building resource link membership for a given registration and resource link identifier
}
};
```

You can then construct the [MembershipServiceServer](../src/Service/Server/MembershipServiceServer.php) with:
- the [AccessTokenRequestValidator](https://github.com/oat-sa/lib-lti1p3-core/blob/master/src/Service/Server/Validator/AccessTokenRequestValidator.php) (from lti1p3-core)
- your [MembershipServiceServerBuilderInterface](../src/Service/Server/Builder/MembershipServiceServerBuilderInterface.php) implementation
Then:
- you can construct the [MembershipServiceServerRequestHandler](../src/Service/Server/Handler/MembershipServiceServerRequestHandler.php) (constructed with your [MembershipServiceServerBuilderInterface](../src/Service/Server/Builder/MembershipServiceServerBuilderInterface.php) implementation)
- to finally expose it to requests using the core [LtiServiceServer](https://github.com/oat-sa/lib-lti1p3-core/blob/master/src/Service/Server/LtiServiceServer.php) (constructed with the [RequestAccessTokenValidator](https://github.com/oat-sa/lib-lti1p3-core/blob/master/src/Security/OAuth2/Validator/RequestAccessTokenValidator.php), from core library)

To finally expose it to requests:
```php
<?php

use OAT\Library\Lti1p3Core\Registration\RegistrationRepositoryInterface;
use OAT\Library\Lti1p3Core\Service\Server\Validator\AccessTokenRequestValidator;
use OAT\Library\Lti1p3Nrps\Service\Server\MembershipServiceServer;
use OAT\Library\Lti1p3Core\Security\OAuth2\Validator\RequestAccessTokenValidator;
use OAT\Library\Lti1p3Core\Service\Server\LtiServiceServer;
use OAT\Library\Lti1p3Nrps\Service\Server\Builder\MembershipServiceServerBuilderInterface;
use OAT\Library\Lti1p3Nrps\Service\Server\Handler\MembershipServiceServerRequestHandler;
use Psr\Http\Message\ServerRequestInterface;

/** @var ServerRequestInterface $request */
$request = ...

/** @var RegistrationRepositoryInterface $repository */
$repository = ...

$validator = new AccessTokenRequestValidator($repository);
/** @var MembershipServiceServerBuilderInterface $builder */
$builder = ...

$membershipServiceServer = new MembershipServiceServer($validator, $builder);
$validator = new RequestAccessTokenValidator($repository);

/** @var ServerRequestInterface $request */
$request = ...
$handler = new MembershipServiceServerRequestHandler($builder);

$server = new LtiServiceServer($validator, $handler);

// Generates a response containing the built membership representation
$response = $membershipServiceServer->handle($request);
// Generates an authenticated response containing the built membership representation
$response = $server->handle($request);
```
2 changes: 1 addition & 1 deletion doc/tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Features

This library provides a [MembershipServiceClient](../src/Service/Client/MembershipServiceClient.php) (based on the [core service client](https://github.com/oat-sa/lib-lti1p3-core/blob/master/doc/service/service-client.md)) that allow retrieving NRPS memberships exposed by a platform.
This library provides a [MembershipServiceClient](../src/Service/Client/MembershipServiceClient.php) (based on the [core LtiServiceClient](https://github.com/oat-sa/lib-lti1p3-core/blob/master/doc/service/service-client.md)) that allow retrieving NRPS memberships exposed by a platform.

You can use:
- `getContextMembershipFromPayload()` to get [context membership](https://www.imsglobal.org/spec/lti-nrps/v2p0#context-membership) from a received LTI message payload
Expand Down
25 changes: 25 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0"?>
<psalm
autoloader="vendor/autoload.php"
errorLevel="3"
hideExternalErrors="true"
useDocblockTypes="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src"/>
<ignoreFiles>
<directory name="doc"/>
<directory name="tests"/>
<directory name="vendor"/>
</ignoreFiles>
</projectFiles>
<mockClasses>
<class name="PHPUnit\Framework\MockObject\MockObject"/>
</mockClasses>
<plugins>
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
</plugins>
</psalm>
4 changes: 2 additions & 2 deletions src/Factory/Member/MemberFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class MemberFactory implements MemberFactoryInterface
private $messageFactory;

public function __construct(
UserIdentityFactoryInterface $userIdentityFactory = null,
MessageFactoryInterface $messageFactory = null
?UserIdentityFactoryInterface $userIdentityFactory = null,
?MessageFactoryInterface $messageFactory = null
) {
$this->userIdentityFactory = $userIdentityFactory ?? new UserIdentityFactory();
$this->messageFactory = $messageFactory ?? new MessageFactory();
Expand Down
6 changes: 3 additions & 3 deletions src/Factory/Membership/MembershipFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class MembershipFactory implements MembershipFactoryInterface
private $memberFactory;

public function __construct(
ContextFactoryInterface $contextFactory = null,
MemberFactoryInterface $memberFactory = null
?ContextFactoryInterface $contextFactory = null,
?MemberFactoryInterface $memberFactory = null
) {
$this->contextFactory = $contextFactory ?? new ContextFactory();
$this->memberFactory = $memberFactory ?? new MemberFactory();
Expand All @@ -52,7 +52,7 @@ public function __construct(
/**
* @throws LtiExceptionInterface
*/
public function create(array $data, string $relationLink = null): MembershipInterface
public function create(array $data, ?string $relationLink = null): MembershipInterface
{
try {
$memberCollection = new MemberCollection();
Expand Down
2 changes: 1 addition & 1 deletion src/Factory/Membership/MembershipFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@

interface MembershipFactoryInterface
{
public function create(array $data): MembershipInterface;
public function create(array $data, ?string $relationLink = null): MembershipInterface;
}
2 changes: 1 addition & 1 deletion src/Model/Context/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Context implements ContextInterface
/** @var string|null */
private $title;

public function __construct(string $identifier, string $label = null, string $title = null)
public function __construct(string $identifier, ?string $label = null, ?string $title = null)
{
$this->identifier = $identifier;
$this->label = $label;
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Member/Member.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function __construct(
string $status,
array $roles,
array $properties = [],
MessageInterface $message = null
?MessageInterface $message = null
) {
$this->userIdentity = $userIdentity;
$this->status = $status;
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Membership/Membership.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
string $identifier,
ContextInterface $context,
MemberCollectionInterface $members,
string $relationLink = null
?string $relationLink = null
) {
$this->identifier = $identifier;
$this->context = $context;
Expand Down
2 changes: 1 addition & 1 deletion src/Serializer/MembershipSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class MembershipSerializer implements MembershipSerializerInterface
/** @var MembershipFactoryInterface */
private $membershipFactory;

public function __construct(MembershipFactoryInterface $membershipFactory = null)
public function __construct(?MembershipFactoryInterface $membershipFactory = null)
{
$this->membershipFactory = $membershipFactory ?? new MembershipFactory();
}
Expand Down
57 changes: 31 additions & 26 deletions src/Service/Client/MembershipServiceClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
use OAT\Library\Lti1p3Core\Exception\LtiExceptionInterface;
use OAT\Library\Lti1p3Core\Message\Payload\LtiMessagePayloadInterface;
use OAT\Library\Lti1p3Core\Registration\RegistrationInterface;
use OAT\Library\Lti1p3Core\Service\Client\ServiceClient;
use OAT\Library\Lti1p3Core\Service\Client\ServiceClientInterface;
use OAT\Library\Lti1p3Core\Service\Client\LtiServiceClient;
use OAT\Library\Lti1p3Core\Service\Client\LtiServiceClientInterface;
use OAT\Library\Lti1p3Nrps\Model\Membership\MembershipInterface;
use OAT\Library\Lti1p3Nrps\Serializer\MembershipSerializer;
use OAT\Library\Lti1p3Nrps\Serializer\MembershipSerializerInterface;
Expand All @@ -40,17 +40,17 @@
*/
class MembershipServiceClient implements MembershipServiceInterface
{
/** @var ServiceClientInterface */
/** @var LtiServiceClientInterface */
private $client;

/** @var MembershipSerializerInterface */
private $serializer;

public function __construct(
ServiceClientInterface $client = null,
MembershipSerializerInterface $serializer = null
?LtiServiceClientInterface $client = null,
?MembershipSerializerInterface $serializer = null
) {
$this->client = $client ?? new ServiceClient();
$this->client = $client ?? new LtiServiceClient();
$this->serializer = $serializer ?? new MembershipSerializer();
}

Expand All @@ -61,17 +61,19 @@ public function __construct(
public function getContextMembershipFromPayload(
RegistrationInterface $registration,
LtiMessagePayloadInterface $payload,
string $role = null,
int $limit = null
?string $role = null,
?int $limit = null
): MembershipInterface {
try {
if (null === $payload->getNrps()) {
$nrpsClaim = $payload->getNrps();

if (null === $nrpsClaim) {
throw new InvalidArgumentException('Provided payload does not contain NRPS claim');
}

return $this->getMembership(
$registration,
$payload->getNrps()->getContextMembershipsUrl(),
$nrpsClaim->getContextMembershipsUrl(),
null,
$role,
$limit
Expand All @@ -92,8 +94,8 @@ public function getContextMembershipFromPayload(
public function getContextMembership(
RegistrationInterface $registration,
string $membershipServiceUrl,
string $role = null,
int $limit = null
?string $role = null,
?int $limit = null
): MembershipInterface {
try {
return $this->getMembership(
Expand All @@ -119,22 +121,25 @@ public function getContextMembership(
public function getResourceLinkMembershipFromPayload(
RegistrationInterface $registration,
LtiMessagePayloadInterface $payload,
string $role = null,
int $limit = null
?string $role = null,
?int $limit = null
): MembershipInterface {
try {
if (null === $payload->getResourceLink()) {
$resourceLinkClaim = $payload->getResourceLink();
$nrpsClaim = $payload->getNrps();

if (null === $resourceLinkClaim) {
throw new InvalidArgumentException('Provided payload does not contain ResourceLink claim');
}

if (null === $payload->getNrps()) {
if (null === $nrpsClaim) {
throw new InvalidArgumentException('Provided payload does not contain NRPS claim');
}

return $this->getMembership(
$registration,
$payload->getNrps()->getContextMembershipsUrl(),
$payload->getResourceLink()->getIdentifier(),
$nrpsClaim->getContextMembershipsUrl(),
$resourceLinkClaim->getIdentifier(),
$role,
$limit
);
Expand All @@ -155,8 +160,8 @@ public function getResourceLinkMembership(
RegistrationInterface $registration,
string $membershipServiceUrl,
string $resourceLinkIdentifier,
string $role = null,
int $limit = null
?string $role = null,
?int $limit = null
): MembershipInterface {
try {
return $this->getMembership(
Expand All @@ -178,9 +183,9 @@ public function getResourceLinkMembership(
private function getMembership(
RegistrationInterface $registration,
string $membershipServiceUrl,
string $resourceLinkIdentifier = null,
string $role = null,
int $limit = null
?string $resourceLinkIdentifier = null,
?string $role = null,
?int $limit = null
): MembershipInterface {
$response = $this->client->request(
$registration,
Expand All @@ -206,9 +211,9 @@ private function getMembership(

private function buildNrpsEndpointUrl(
string $membershipServiceUrl,
string $resourceLinkIdentifier = null,
string $role = null,
int $limit = null
?string $resourceLinkIdentifier = null,
?string $role = null,
?int $limit = null
): string {
$parameters = array_filter([
'rlid' => $resourceLinkIdentifier,
Expand Down
Loading