Passed
Push — issue#666 ( 0a0cb9...d66c4e )
by Guilherme
08:36
created

onNewAuthorizationRequest()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 7
nop 1
dl 0
loc 15
ccs 12
cts 12
cp 1
crap 6
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\RemoteClaimsBundle\EventSubscriber;
12
13
use LoginCidadao\LogBundle\Traits\LoggerAwareTrait;
14
use LoginCidadao\OpenIDBundle\Event\AuthorizationEvent;
15
use LoginCidadao\OpenIDBundle\LoginCidadaoOpenIDEvents;
16
use LoginCidadao\RemoteClaimsBundle\Entity\RemoteClaimAuthorization;
17
use LoginCidadao\RemoteClaimsBundle\Model\HttpUri;
18
use LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimFetcherInterface;
19
use LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimInterface;
20
use LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimManagerInterface;
21
use LoginCidadao\RemoteClaimsBundle\Model\TagUri;
22
use Psr\Log\LoggerAwareInterface;
23
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
25
26
class AuthorizationSubscriber implements EventSubscriberInterface, LoggerAwareInterface
27
{
28
    use LoggerAwareTrait;
29
30
    /** @var RemoteClaimFetcherInterface */
31
    private $claimFetcher;
32
33
    /** @var RemoteClaimInterface[] */
34
    private $remoteClaims;
35
36
    /** @var RemoteClaimManagerInterface */
37
    private $remoteClaimManager;
38
39
    /** @var AuthorizationCheckerInterface */
40
    private $authChecker;
41
42
    /**
43
     * AuthorizationSubscriber constructor.
44
     * @param RemoteClaimManagerInterface $remoteClaimManager
45
     * @param RemoteClaimFetcherInterface $claimFetcher
46
     * @param AuthorizationCheckerInterface $authChecker
47
     */
48 7
    public function __construct(
49
        RemoteClaimManagerInterface $remoteClaimManager,
50
        RemoteClaimFetcherInterface $claimFetcher,
51
        AuthorizationCheckerInterface $authChecker
52
    ) {
53 7
        $this->remoteClaimManager = $remoteClaimManager;
54 7
        $this->claimFetcher = $claimFetcher;
55 7
        $this->authChecker = $authChecker;
56 7
    }
57
58 15
    public static function getSubscribedEvents()
59
    {
60
        return [
61 15
            LoginCidadaoOpenIDEvents::NEW_AUTHORIZATION_REQUEST => 'onNewAuthorizationRequest',
62 15
            LoginCidadaoOpenIDEvents::NEW_AUTHORIZATION => ['onNewAuthorization', 100],
63 15
            LoginCidadaoOpenIDEvents::UPDATE_AUTHORIZATION => ['onUpdateAuthorization', 100],
64 15
            LoginCidadaoOpenIDEvents::REVOKE_AUTHORIZATION => 'onRevokeAuthorization',
65
        ];
66
    }
67
68 3
    public function onNewAuthorizationRequest(AuthorizationEvent $event)
69
    {
70 3
        if (false === $this->authChecker->isGranted('FEATURE_REMOTE_CLAIMS')) {
71 1
            return;
72
        }
73 2
        foreach ($event->getScope() as $scope) {
74 2
            if ($this->checkHttpUri($scope) || $this->checkTagUri($scope)) {
75
                try {
76 2
                    $remoteClaim = $this->claimFetcher->getRemoteClaim($scope);
77 1
                    $this->remoteClaims[] = $remoteClaim;
78 1
                    $event->addRemoteClaim($remoteClaim);
79 1
                } catch (\Exception $e) {
80 1
                    $this->error(
81 1
                        "Error retrieving remote claim {$scope}: {$e->getMessage()}",
82 2
                        ['exception' => $e]
83
                    );
84
                }
85
            }
86
        }
87 2
    }
88
89 2
    public function onNewAuthorization(AuthorizationEvent $event)
90
    {
91 2
        if (false === $this->authChecker->isGranted('FEATURE_REMOTE_CLAIMS')) {
92 1
            return;
93
        }
94 1
        $this->enforceRemoteClaims($event);
95 1
    }
96
97 2
    public function onUpdateAuthorization(AuthorizationEvent $event)
98
    {
99 2
        if (false === $this->authChecker->isGranted('FEATURE_REMOTE_CLAIMS')) {
100 1
            return;
101
        }
102 1
        $this->enforceRemoteClaims($event);
103 1
    }
104
105 2
    public function onRevokeAuthorization(AuthorizationEvent $event)
106
    {
107 2
        if (count($event->getRemoteClaims()) === 0) {
108 1
            return;
109
        }
110
111 1
        $this->remoteClaimManager->revokeAllAuthorizations($event->getAuthorization());
112 1
    }
113
114 2
    private function checkHttpUri($uri)
115
    {
116
        try {
117 2
            $http = HttpUri::createFromString($uri);
118
119 2
            return $http->getScheme() && $http->getHost();
120 2
        } catch (\Exception $e) {
121 2
            return false;
122
        }
123
    }
124
125 2
    private function checkTagUri($uri)
126
    {
127
        try {
128 2
            TagUri::createFromString($uri);
129
130 1
            return true;
131 2
        } catch (\Exception $e) {
132 2
            return false;
133
        }
134
    }
135
136 2
    private function enforceRemoteClaims(AuthorizationEvent $event)
137
    {
138 2
        $remoteClaims = $event->getRemoteClaims();
139
140 2
        foreach ($remoteClaims as $remoteClaim) {
141 2
            $claimName = $remoteClaim->getName();
142
143 2
            $accessToken = bin2hex(random_bytes(20));
144 2
            $authorization = (new RemoteClaimAuthorization())
145 2
                ->setClient($event->getClient())
146 2
                ->setClaimProvider($remoteClaim->getProvider())
147 2
                ->setPerson($event->getPerson())
148 2
                ->setClaimName($claimName)
149 2
                ->setAccessToken($accessToken);
150
151 2
            $this->remoteClaimManager->enforceAuthorization($authorization);
152
        }
153 2
    }
154
}
155