Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Lti1p3Validator
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 6
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getValidatedPayload
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 validateRequest
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 validateRole
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getRegistrationRepository
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getToolLaunchValidator
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2021-2022 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoLti\models\classes\Tool\Validation;
24
25use OAT\Library\Lti1p3Core\Exception\LtiException as Lti1p3Exception;
26use OAT\Library\Lti1p3Core\Message\Launch\Validator\AbstractLaunchValidator;
27use OAT\Library\Lti1p3Core\Message\Launch\Validator\Tool\ToolLaunchValidator;
28use OAT\Library\Lti1p3Core\Message\Payload\LtiMessagePayloadInterface;
29use OAT\Library\Lti1p3Core\Registration\RegistrationRepositoryInterface;
30use OAT\Library\Lti1p3Core\Role\RoleInterface;
31use OAT\Library\Lti1p3Core\Security\Nonce\NonceRepository;
32use oat\taoLti\models\classes\LtiException;
33use Psr\Cache\CacheItemPoolInterface;
34use Psr\Http\Message\ServerRequestInterface;
35
36class Lti1p3Validator
37{
38    private ?AbstractLaunchValidator $toolLaunchValidator;
39
40    private RegistrationRepositoryInterface $registrationRepository;
41    private CacheItemPoolInterface $cacheAdapter;
42
43    public function __construct(
44        RegistrationRepositoryInterface $registrationRepository,
45        CacheItemPoolInterface $cacheAdapter,
46        AbstractLaunchValidator $toolLaunchValidator = null
47    ) {
48        $this->registrationRepository = $registrationRepository;
49        $this->cacheAdapter = $cacheAdapter;
50        $this->toolLaunchValidator = $toolLaunchValidator;
51    }
52
53    /**
54     * @throws LtiException
55     */
56    public function getValidatedPayload(ServerRequestInterface $request): LtiMessagePayloadInterface
57    {
58        try {
59            $ltiMessagePayload = $this->validateRequest($request);
60
61            $this->validateRole($ltiMessagePayload);
62        } catch (Lti1p3Exception $exception) {
63            throw new LtiException($exception->getMessage());
64        }
65
66        return $ltiMessagePayload;
67    }
68
69    /**
70     * @throws Lti1p3Exception
71     */
72    public function validateRequest(ServerRequestInterface $request): LtiMessagePayloadInterface
73    {
74        $validator = $this->getToolLaunchValidator();
75
76        $result = $validator->validatePlatformOriginatingLaunch($request);
77
78        if ($result->hasError()) {
79            throw new Lti1p3Exception($result->getError());
80        }
81
82        $ltiMessagePayload = $result->getPayload();
83
84        if ($ltiMessagePayload === null) {
85            throw new Lti1p3Exception('No LTI message payload received.');
86        }
87
88        return $ltiMessagePayload;
89    }
90
91    /**
92     * @throws LtiException
93     */
94    public function validateRole(LtiMessagePayloadInterface $ltiMessagePayload): void
95    {
96        $roles = $ltiMessagePayload->getValidatedRoleCollection();
97
98        if (!$roles->canFindBy(RoleInterface::TYPE_CONTEXT)) {
99            throw new LtiException('No valid IMS context role has been provided.');
100        }
101    }
102
103    private function getRegistrationRepository(): RegistrationRepositoryInterface
104    {
105        return $this->registrationRepository;
106    }
107
108    /**
109     * @return ToolLaunchValidator
110     */
111    public function getToolLaunchValidator(): AbstractLaunchValidator
112    {
113        return $this->toolLaunchValidator ?? new ToolLaunchValidator(
114            $this->getRegistrationRepository(),
115            new NonceRepository($this->cacheAdapter)
116        );
117    }
118}