Passed
Push — 1.0 ( d00332...1da4bb )
by Pol
02:09
created

CasGuardAuthenticator::onLogoutSuccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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