Completed
Push — feature/fine-grained-authoriza... ( f68bce...801076 )
by Michiel
02:18
created

IdentityService::findByNameIdAndInstitution()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
cc 4
nc 4
nop 2
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupRa\RaBundle\Service;
20
21
use Exception;
22
use Psr\Log\LoggerInterface;
23
use Surfnet\StepupBundle\Command\SwitchLocaleCommand;
24
use Surfnet\StepupMiddlewareClient\Identity\Dto\IdentitySearchQuery;
25
use Surfnet\StepupMiddlewareClientBundle\Identity\Command\ExpressLocalePreferenceCommand;
26
use Surfnet\StepupMiddlewareClientBundle\Identity\Dto\Identity;
27
use Surfnet\StepupMiddlewareClientBundle\Identity\Service\IdentityService as ApiIdentityService;
28
use Surfnet\StepupRa\RaBundle\Exception\RuntimeException;
29
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
30
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
31
use Symfony\Component\Security\Core\User\UserInterface;
32
use Symfony\Component\Security\Core\User\UserProviderInterface;
33
34
class IdentityService implements UserProviderInterface
35
{
36
    /**
37
     * @var \Surfnet\StepupMiddlewareClientBundle\Identity\Service\IdentityService
38
     */
39
    private $apiIdentityService;
40
41
    /**
42
     * @var \Surfnet\StepupRa\RaBundle\Service\CommandService
43
     */
44
    private $commandService;
45
46
    /**
47
     * @var \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface
48
     */
49
    private $tokenStorage;
50
51
    /**
52
     * @var \Psr\Log\LoggerInterface
53
     */
54
    private $logger;
55
56
    public function __construct(
57
        ApiIdentityService $apiIdentityService,
58
        CommandService $commandService,
59
        TokenStorageInterface $tokenStorage,
60
        LoggerInterface $logger
61
    ) {
62
        $this->apiIdentityService = $apiIdentityService;
63
        $this->commandService = $commandService;
64
        $this->tokenStorage = $tokenStorage;
65
        $this->logger = $logger;
66
    }
67
68
    /**
69
     * For now this functionality is disabled, unsure if actually needed
70
     *
71
     * If needed, the username is the UUID of the identity so it can be fetched rather easy
72
     */
73
    public function loadUserByUsername($username)
74
    {
75
        throw new RuntimeException(sprintf('Cannot Load User By Username "%s"', $username));
76
    }
77
78
    /**
79
     * For now this functionality is disabled, unsure if actually needed
80
     */
81
    public function refreshUser(UserInterface $user)
82
    {
83
        throw new RuntimeException(sprintf('Cannot Refresh User "%s"', $user->getUsername()));
84
    }
85
86
    /**
87
     * Whether this provider supports the given user class
88
     *
89
     * @param string $class
90
     *
91
     * @return bool
92
     */
93
    public function supportsClass($class)
94
    {
95
        return $class === 'Surfnet\StepupMiddlewareClientBundle\Identity\Dto\Identity';
96
    }
97
98
    /**
99
     * @param string $identityId the UUID of the identity to find
100
     * @return null|Identity
101
     */
102
    public function findById($identityId)
103
    {
104
        return $this->apiIdentityService->get($identityId);
105
    }
106
107
    /**
108
     * @param string $nameId
109
     * @param string $institution
110
     * @return null|\Surfnet\StepupMiddlewareClientBundle\Identity\Dto\Identity
111
     * @throws \Surfnet\StepupRa\RaBundle\Exception\RuntimeException
112
     */
113
    public function findByNameIdAndInstitution($nameId, $institution)
114
    {
115
        $searchQuery = new IdentitySearchQuery($institution);
116
        $searchQuery->setNameId($nameId);
117
118
        try {
119
            $result = $this->apiIdentityService->search($searchQuery);
120
        } catch (Exception $e) {
121
            $message = sprintf('Exception when searching identity: "%s"', $e->getMessage());
122
            $this->logger->critical($message);
123
            throw new RuntimeException($message, 0, $e);
124
        }
125
126
        $elements = $result->getElements();
127
        if (count($elements) === 0) {
128
            return null;
129
        }
130
131
        if (count($elements) === 1) {
132
            return reset($elements);
133
        }
134
135
        throw new RuntimeException(sprintf(
136
            'Got an unexpected amount of identities, expected 0 or 1, got "%d"',
137
            count($elements)
138
        ));
139
    }
140
141
    /**
142
     * @param Identity $identity
143
     * @return \Surfnet\StepupMiddlewareClientBundle\Identity\Dto\RegistrationAuthorityCredentials|null
144
     */
145
    public function getRaCredentials(Identity $identity)
146
    {
147
        try {
148
            $credentials = $this->apiIdentityService->getRegistrationAuthorityCredentials($identity);
149
        } catch (Exception $e) {
150
            $message = sprintf('Exception when retrieving RA credentials: "%s"', $e->getMessage());
151
            $this->logger->critical($message);
152
153
            throw new RuntimeException($message, 0, $e);
154
        }
155
156
        return $credentials;
157
    }
158
159
    /**
160
     * @param SwitchLocaleCommand $command
161
     * @return bool
162
     */
163
    public function switchLocale(SwitchLocaleCommand $command)
164
    {
165
        /** @var TokenInterface|null */
166
        $token = $this->tokenStorage->getToken();
167
168
        if (!$token) {
169
            throw new RuntimeException('Cannot switch locales when unauthenticated');
170
        }
171
172
        /** @var Identity $identity */
173
        $identity = $token->getUser();
174
175
        $expressLocalePreferenceCommand = new ExpressLocalePreferenceCommand();
176
        $expressLocalePreferenceCommand->identityId = $command->identityId;
177
        $expressLocalePreferenceCommand->preferredLocale = $command->locale;
178
179
        $result = $this->commandService->execute($expressLocalePreferenceCommand);
180
181
        if ($result->isSuccessful()) {
182
            $identity->preferredLocale = $command->locale;
183
        }
184
185
        return $result->isSuccessful();
186
    }
187
}
188