Completed
Push — master ( f6198e...300d99 )
by Paweł
53:20
created

TokenAuthenticator::getUser()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2.0023

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 24
ccs 11
cts 12
cp 0.9167
rs 8.9713
c 1
b 0
f 0
cc 2
eloc 14
nc 2
nop 2
crap 2.0023
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Core Bundle.
7
 *
8
 * Copyright 2015 Sourcefabric z.u. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2015 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\CoreBundle\Security\Authenticator;
18
19
use Doctrine\ORM\EntityManagerInterface;
20
use SWP\Bundle\CoreBundle\Model\UserInterface as CoreUserInterface;
21
use SWP\Bundle\CoreBundle\Repository\ApiKeyRepository;
22
use SWP\Component\MultiTenancy\Context\TenantContextInterface;
23
use SWP\Component\MultiTenancy\Repository\TenantRepositoryInterface;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpFoundation\JsonResponse;
26
use Symfony\Component\Security\Core\User\UserInterface;
27
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
28
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
29
use Symfony\Component\Security\Core\Exception\AuthenticationException;
30
use Symfony\Component\Security\Core\User\UserProviderInterface;
31
32
class TokenAuthenticator extends AbstractGuardAuthenticator
33
{
34
    /**
35
     * @var ApiKeyRepository
36
     */
37
    protected $apiKeyRepository;
38
39
    /**
40
     * @var TenantContextInterface
41
     */
42
    protected $tenantContext;
43
44
    /**
45
     * @var TenantRepositoryInterface
46
     */
47
    protected $tenantRepository;
48
49
    /**
50
     * @var EntityManagerInterface
51
     */
52
    protected $entityManager;
53 99
54
    /**
55
     * TokenAuthenticator constructor.
56
     *
57
     * @param ApiKeyRepository          $apiKeyRepository
58 99
     * @param TenantContextInterface    $tenantContext
59 99
     * @param TenantRepositoryInterface $tenantRepository
60 99
     * @param EntityManagerInterface    $entityManager
61 99
     */
62
    public function __construct(
63
        ApiKeyRepository $apiKeyRepository,
64
        TenantContextInterface $tenantContext,
65
        TenantRepositoryInterface $tenantRepository,
66
        EntityManagerInterface $entityManager
67 76
    ) {
68
        $this->apiKeyRepository = $apiKeyRepository;
69 76
        $this->tenantContext = $tenantContext;
70
        $this->tenantRepository = $tenantRepository;
71
        $this->entityManager = $entityManager;
72
    }
73
74
    /**
75
     * Called on every request. Return whatever credentials you want,
76 76
     * or null to stop authentication.
77
     */
78
    public function getCredentials(Request $request)
79
    {
80 76
        if (!$token = $request->headers->get('Authorization', $request->query->get('auth_token'))) {
81
            // no token? Return null and no other methods will be called
82 76
            return;
83 76
        }
84 76
85 76
        // What you return here will be passed to getUser() as $credentials
86
        return [
87 76
            'token' => $token,
88
        ];
89
    }
90
91
    public function getUser($credentials, UserProviderInterface $userProvider)
92 76
    {
93 76
        $this->entityManager->getFilters()->disable('tenantable');
94
        $apiKey = $this->apiKeyRepository
95
            ->getValidToken(str_replace('Basic ', '', $credentials['token']))
96 76
            ->getQuery()
97 76
            ->getOneOrNullResult();
98
99 76
        $this->entityManager->getFilters()->enable('tenantable');
100
101
        if (null === $apiKey) {
102 76
            return;
103
        }
104 76
105 76
        // extend valid time after login
106 76
        $apiKey->extendValidTo();
107
        $this->apiKeyRepository->flush();
108 76
109 76
        /** @var CoreUserInterface $user */
110
        $user = $apiKey->getUser();
111
        $user->addRole('ROLE_INTERNAL_API');
112
113
        return $user;
114
    }
115
116 76
    public function checkCredentials($credentials, UserInterface $user)
117
    {
118
        if ($user instanceof CoreUserInterface) {
119 76
            $currentOrganization = $this->tenantContext->getTenant()->getOrganization();
120
            $userOrganization = $this->tenantRepository->findOneByCode($user->getTenantCode())->getOrganization();
121
122
            if ($currentOrganization->getId() === $userOrganization->getId()) {
123
                return true;
124
            }
125
        }
126
127
        return false;
128
    }
129
130
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
131
    {
132
        // on success, let the request continue
133
        return;
134
    }
135
136
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
137
    {
138
        $data = [
139
            'status' => 403,
140
            'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),
141
        ];
142
143
        return new JsonResponse($data, 403);
144
    }
145
146
    /**
147
     * Called when authentication is needed, but it's not sent.
148
     */
149
    public function start(Request $request, AuthenticationException $authException = null)
150
    {
151
        $data = [
152
            'status' => 401,
153
            'message' => 'Authentication Required',
154
        ];
155
156
        return new JsonResponse($data, 401);
157
    }
158
159
    public function supportsRememberMe()
160
    {
161
        return false;
162
    }
163
}
164