Passed
Push — 4.4 ( f1e9e8...b52373 )
by Pol
02:34
created

CasGuardAuthenticator::getUser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 7
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 10
c 2
b 0
f 0
cc 3
nc 3
nop 2
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace drupol\CasBundle\Security;
6
7
use drupol\CasBundle\Security\Core\User\CasUserProviderInterface;
8
use drupol\psrcas\CasInterface;
9
use drupol\psrcas\Introspection\Contract\ServiceValidate;
10
use drupol\psrcas\Introspection\Introspector;
11
use drupol\psrcas\Utils\Uri;
12
use InvalidArgumentException;
13
use Psr\Http\Message\ServerRequestFactoryInterface;
14
use Psr\Http\Message\UriFactoryInterface;
15
use Symfony\Component\HttpFoundation\RedirectResponse;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
18
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19
use Symfony\Component\Security\Core\Exception\AuthenticationException;
20
use Symfony\Component\Security\Core\User\UserInterface;
21
use Symfony\Component\Security\Core\User\UserProviderInterface;
22
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
23
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
24
25
/**
26
 * Class CasGuardAuthenticator.
27
 */
28
class CasGuardAuthenticator extends AbstractGuardAuthenticator implements LogoutSuccessHandlerInterface
29
{
30
    /**
31
     * The PSR CAS library.
32
     *
33
     * @var \drupol\psrcas\CasInterface
34
     */
35
    private $cas;
36
37
    /**
38
     * @var \Psr\Http\Message\ServerRequestFactoryInterface
39
     */
40
    private $serverRequestFactory;
41
42
    /**
43
     * @var \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface
44
     */
45
    private $tokenStorage;
46
47
    /**
48
     * @var \Psr\Http\Message\UriFactoryInterface
49
     */
50
    private $uriFactory;
51
52
    /**
53
     * CasGuardAuthenticator constructor.
54
     *
55
     * @param \drupol\psrcas\CasInterface $cas
56
     * @param \Psr\Http\Message\UriFactoryInterface $uriFactory
57
     * @param \Psr\Http\Message\ServerRequestFactoryInterface $serverRequestFactory
58
     * @param \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface $tokenStorage
59
     */
60 10
    public function __construct(
61
        CasInterface $cas,
62
        UriFactoryInterface $uriFactory,
63
        ServerRequestFactoryInterface $serverRequestFactory,
64
        TokenStorageInterface $tokenStorage
65
    ) {
66 10
        $this->cas = $cas;
67 10
        $this->uriFactory = $uriFactory;
68 10
        $this->serverRequestFactory = $serverRequestFactory;
69 10
        $this->tokenStorage = $tokenStorage;
70 10
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 1
    public function checkCredentials($response, UserInterface $user)
76
    {
77
        try {
78 1
            $introspect = Introspector::detect($response);
79 1
        } catch (InvalidArgumentException $exception) {
80 1
            throw new AuthenticationException($exception->getMessage());
81
        }
82
83 1
        if (false === ($introspect instanceof ServiceValidate)) {
84 1
            throw new AuthenticationException(
85 1
                'Failure in the returned response'
86
            );
87
        }
88
89 1
        return true;
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function getCredentials(Request $request)
96
    {
97
        $response = $this
98
            ->cas
99
            ->requestTicketValidation();
100
101
        if (null === $response) {
102
            throw new AuthenticationException('Unable to authenticate the user with such service ticket.');
103
        }
104
105
        return $response;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111 1
    public function getUser($response, UserProviderInterface $userProvider)
112
    {
113 1
        if (false === ($userProvider instanceof CasUserProviderInterface)) {
114 1
            throw new AuthenticationException('Unable to load the user through the given User Provider.');
115
        }
116
117
        try {
118 1
            $user = $userProvider->loadUserByResponse($response);
119 1
        } catch (AuthenticationException $exception) {
120 1
            throw $exception;
121
        }
122
123 1
        return $user;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129 1
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
130
    {
131 1
        if (true === $request->query->has('ticket')) {
132 1
            return new RedirectResponse(
133 1
                (string) Uri::removeParams(
134 1
                    $this->uriFactory->createUri(
135 1
                        $request->getUri()
136
                    ),
137 1
                    'ticket'
138
                )
139
            );
140
        }
141 1
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146 1
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
147
    {
148 1
        return new RedirectResponse(
149 1
            (string) Uri::removeParams(
150 1
                $this->uriFactory->createUri(
151 1
                    $request->getUri()
152
                ),
153 1
                'ticket'
154
            )
155
        );
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161 1
    public function onLogoutSuccess(Request $request)
162
    {
163 1
        return new RedirectResponse(
164
            $this
165 1
                ->cas
166 1
                ->logout()
167 1
                ->getHeaderLine('location')
168
        );
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174 1
    public function start(Request $request, ?AuthenticationException $authException = null)
175
    {
176 1
        return new RedirectResponse(
177
            $this
178 1
                ->cas
179 1
                ->login()
180 1
                ->getHeaderLine('location')
181
        );
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187 2
    public function supports(Request $request)
188
    {
189 2
        if (null !== $this->tokenStorage->getToken()) {
190 1
            return false;
191
        }
192
193
        return $this
194 1
            ->cas
195 1
            ->withServerRequest(
196
                $this
197 1
                    ->serverRequestFactory
198 1
                    ->createServerRequest(
199 1
                        $request->getMethod(),
200 1
                        $request->getUri()
201
                    )
202
            )
203 1
            ->supportAuthentication();
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209 1
    public function supportsRememberMe()
210
    {
211 1
        return false;
212
    }
213
}
214