Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.95% covered (warning)
82.95%
73 / 88
80.00% covered (warning)
80.00%
12 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
Lti1p3RegistrationRepository
82.95% covered (warning)
82.95%
73 / 88
80.00% covered (warning)
80.00%
12 / 15
26.85
0.00% covered (danger)
0.00%
0 / 1
 find
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 findAll
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 findByClientId
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 findByPlatformIssuer
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 findByToolIssuer
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getTool
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultPlatform
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultTool
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 createRegistrationByProvider
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
2
 createRegistrationByPlatform
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
 getLtiProviderService
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLtiPlatformService
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getToolKeyChainRepository
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCachedPlatformKeyChainRepository
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPlatformKeyChainRepository
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
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) 2020 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoLti\models\classes\Platform\Repository;
24
25use OAT\Library\Lti1p3Core\Platform\Platform;
26use OAT\Library\Lti1p3Core\Registration\Registration;
27use OAT\Library\Lti1p3Core\Registration\RegistrationInterface;
28use OAT\Library\Lti1p3Core\Registration\RegistrationRepositoryInterface;
29use OAT\Library\Lti1p3Core\Security\Key\KeyChainRepositoryInterface;
30use OAT\Library\Lti1p3Core\Tool\Tool;
31use oat\oatbox\service\ConfigurableService;
32use oat\taoLti\models\classes\LtiProvider\LtiProvider;
33use oat\taoLti\models\classes\LtiProvider\LtiProviderService;
34use oat\taoLti\models\classes\Platform\LtiPlatformRegistration;
35use oat\taoLti\models\classes\Security\DataAccess\Repository\CachedPlatformKeyChainRepository;
36use oat\taoLti\models\classes\Security\DataAccess\Repository\PlatformKeyChainRepository;
37use oat\taoLti\models\classes\Security\DataAccess\Repository\ToolKeyChainRepository;
38
39class Lti1p3RegistrationRepository extends ConfigurableService implements RegistrationRepositoryInterface
40{
41    public const SERVICE_ID = 'taoLti/Lti1p3RegistrationRepository';
42    public const OPTION_ROOT_URL = 'rootUrl';
43    private const PLATFORM_ID = 'tao';
44    private const TOOL_ID = 'tao_tool';
45    private const OIDC_PATH = 'taoLti/Security/oidc';
46    private const OAUTH_PATH = 'taoLti/Security/oauth';
47    private const JWKS_PATH = 'taoLti/Security/jwks';
48
49    public function find(string $identifier): ?RegistrationInterface
50    {
51        $ltiProvider = $this->getLtiProviderService()->searchById($identifier);
52
53        if (!$ltiProvider) {
54            $ltiPlatform = $this->getLtiPlatformService()->searchById($identifier);
55            if ($ltiPlatform) {
56                return $this->createRegistrationByPlatform($ltiPlatform);
57            } else {
58                return null;
59            }
60        }
61
62        return $this->createRegistrationByProvider($ltiProvider);
63    }
64
65    public function findAll(): array
66    {
67        $registrations = [];
68
69        foreach ($this->getLtiProviderService()->findAll() as $ltiProvider) {
70            $registrations[] = $this->createRegistrationByProvider($ltiProvider);
71        }
72        foreach ($this->getLtiPlatformService()->findAll() as $ltiPlatform) {
73            $registrations[] = $this->createRegistrationByPlatform($ltiPlatform);
74        }
75
76        return $registrations;
77    }
78
79    public function findByClientId(string $clientId): ?RegistrationInterface
80    {
81        $ltiProvider = $this->getLtiProviderService()->searchByToolClientId($clientId);
82
83        if (!$ltiProvider) {
84            $ltiPlatform = $this->getLtiPlatformService()->searchByClientId($clientId);
85            if ($ltiPlatform) {
86                return $this->createRegistrationByPlatform($ltiPlatform);
87            } else {
88                return null;
89            }
90        }
91
92        return $this->createRegistrationByProvider($ltiProvider);
93    }
94
95    public function findByPlatformIssuer(string $issuer, string $clientId = null): ?RegistrationInterface
96    {
97        $platform = $this->getLtiPlatformService()->searchByIssuer($issuer, $clientId);
98        if (!$platform) {
99            return null;
100        }
101        return $this->createRegistrationByPlatform($platform);
102    }
103
104    public function findByToolIssuer(string $issuer, string $clientId = null): ?RegistrationInterface
105    {
106        $provider = $this->getLtiProviderService()->searchByIssuer($issuer, $clientId);
107        if (!$provider) {
108            return null;
109        }
110        return $this->createRegistrationByProvider($provider);
111    }
112
113    private function getTool(LtiProvider $ltiProvider): Tool
114    {
115        return new Tool(
116            $ltiProvider->getToolIdentifier(),
117            $ltiProvider->getToolName(),
118            $ltiProvider->getToolAudience(),
119            $ltiProvider->getToolOidcLoginInitiationUrl(),
120            $ltiProvider->getToolLaunchUrl()
121        );
122    }
123
124    private function getDefaultPlatform(): Platform
125    {
126        return new Platform(
127            self::PLATFORM_ID,
128            self::PLATFORM_ID,
129            rtrim($this->getOption(self::OPTION_ROOT_URL), '/'),
130            $this->getOption(self::OPTION_ROOT_URL) . self::OIDC_PATH,
131            $this->getOption(self::OPTION_ROOT_URL) . self::OAUTH_PATH
132        );
133    }
134
135    private function getDefaultTool(): Tool
136    {
137        return new Tool(
138            self::TOOL_ID,
139            self::TOOL_ID,
140            rtrim($this->getOption(self::OPTION_ROOT_URL), '/'),
141            $this->getOption(self::OPTION_ROOT_URL) . self::OIDC_PATH
142        );
143    }
144
145    private function createRegistrationByProvider(LtiProvider $ltiProvider): ?Registration
146    {
147        $toolKeyChain = $this->getToolKeyChainRepository()->find($ltiProvider->getId());
148
149        $platformKeyChain = $this->getCachedPlatformKeyChainRepository()->find($ltiProvider->getId());
150
151        if ($platformKeyChain === null) {
152            return null;
153        }
154
155        return new Registration(
156            $ltiProvider->getId(),
157            $ltiProvider->getToolClientId(),
158            $this->getDefaultPlatform(),
159            $this->getTool($ltiProvider),
160            $ltiProvider->getToolDeploymentIds(),
161            $platformKeyChain,
162            $toolKeyChain,
163            $this->getOption(self::OPTION_ROOT_URL) . self::JWKS_PATH,
164            $ltiProvider->getToolJwksUrl()
165        );
166    }
167
168    private function createRegistrationByPlatform(LtiPlatformRegistration $ltiPlatform): ?Registration
169    {
170        // use platform key chain
171        $toolKeyChain = $this->getCachedPlatformKeyChainRepository()
172            ->find($this->getPlatformKeyChainRepository()->getDefaultKeyId());
173
174        $platform = new Platform(
175            $ltiPlatform->getIdentifier(),
176            $ltiPlatform->getIdentifier(),
177            $ltiPlatform->getAudience(),
178            $ltiPlatform->getOidcAuthenticationUrl(),
179            $ltiPlatform->getOAuth2AccessTokenUrl()
180        );
181
182        return new Registration(
183            $ltiPlatform->getIdentifier(),
184            $ltiPlatform->getClientId(),
185            $platform,
186            $this->getDefaultTool(),
187            [$ltiPlatform->getDeploymentId()],
188            null,
189            $toolKeyChain,
190            $ltiPlatform->getJwksUrl(),
191            $this->getOption(self::OPTION_ROOT_URL) . self::JWKS_PATH
192        );
193    }
194
195    private function getLtiProviderService(): LtiProviderService
196    {
197        return $this->getServiceLocator()->get(LtiProviderService::SERVICE_ID);
198    }
199
200    private function getLtiPlatformService(): LtiPlatformRepositoryInterface
201    {
202        return $this->getServiceLocator()->get(LtiPlatformRepositoryInterface::SERVICE_ID);
203    }
204
205    private function getToolKeyChainRepository(): KeyChainRepositoryInterface
206    {
207        return $this->getServiceLocator()->get(ToolKeyChainRepository::class);
208    }
209
210    private function getCachedPlatformKeyChainRepository(): KeyChainRepositoryInterface
211    {
212        return $this->getServiceLocator()->get(CachedPlatformKeyChainRepository::class);
213    }
214
215    private function getPlatformKeyChainRepository(): PlatformKeyChainRepository
216    {
217        return $this->getServiceLocator()->get(PlatformKeyChainRepository::class);
218    }
219}