Completed
Push — bugfix/institution-mixed-casin... ( 591620...3de533 )
by
unknown
02:21
created

mayRaCommandBeExecutedOnBehalfOf()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.4586
c 0
b 0
f 0
cc 7
nc 7
nop 3
1
<?php
2
/**
3
 * Copyright 2010 SURFnet B.V.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace Surfnet\StepupMiddleware\ApiBundle\Authorization\Service;
19
20
use Psr\Log\LoggerInterface;
21
use Surfnet\Stepup\Configuration\Value\InstitutionRole;
22
use Surfnet\Stepup\Identity\Value\IdentityId;
23
use Surfnet\Stepup\Identity\Value\Institution;
24
use Surfnet\StepupMiddleware\ApiBundle\Identity\Service\IdentityService;
25
use Surfnet\StepupMiddleware\ApiBundle\Identity\Service\WhitelistService;
26
use Surfnet\StepupMiddleware\CommandHandlingBundle\Command\Command;
27
use Surfnet\StepupMiddleware\CommandHandlingBundle\Command\RaExecutable;
28
use Surfnet\StepupMiddleware\CommandHandlingBundle\Command\SelfServiceExecutable;
29
use Surfnet\StepupMiddleware\CommandHandlingBundle\Identity\Command\CreateIdentityCommand;
30
use Surfnet\StepupMiddleware\CommandHandlingBundle\Identity\Command\UpdateIdentityCommand;
31
32
class CommandAuthorizationService
33
{
34
35
    /**
36
     * @var WhitelistService
37
     */
38
    private $whitelistService;
39
    /**
40
     * @var IdentityService
41
     */
42
    private $identityService;
43
    /**
44
     * @var AuthorizationContextService
45
     */
46
    private $authorizationContextService;
47
    /**
48
     * @var LoggerInterface
49
     */
50
    private $logger;
51
52
    public function __construct(
53
        WhitelistService $whitelistService,
54
        IdentityService $identityService,
55
        LoggerInterface $logger,
56
        AuthorizationContextService $authorizationContextService
57
    ) {
58
        $this->logger = $logger;
59
        $this->authorizationContextService = $authorizationContextService;
60
        $this->whitelistService = $whitelistService;
61
        $this->identityService = $identityService;
62
    }
63
64
    /**
65
     * @param Institution $institution
66
     * @param IdentityId|null $actorId
67
     * @return bool
68
     */
69
    public function isInstitutionWhitelisted(Institution $institution, IdentityId $actorId = null)
70
    {
71
        // If the actor is SRAA all actions should be allowed
72
        if (!is_null($actorId) && $this->isSraa($actorId)) {
73
            return true;
74
        }
75
76
        if ($this->whitelistService->isWhitelisted($institution->getInstitution())) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $this->whitelistS...ion->getInstitution());.
Loading history...
77
            return true;
78
        }
79
80
        return false;
81
    }
82
83
    /**
84
     * @param Command $command
85
     * @param IdentityId|null $actorId
86
     * @return bool
87
     */
88
    public function maySelfServiceCommandBeExecutedOnBehalfOf(Command $command, IdentityId $actorId = null)
89
    {
90
        // Assert self service command could be executed
91
        if ($command instanceof SelfServiceExecutable) {
92
            $this->logger->notice('Asserting a SelfService command');
93
94
            // If the actor is SRAA all actions should be allowed
95
            if ($this->isSraa($actorId)) {
96
                return true;
97
            }
98
99
            // the createIdentityCommand is used to create an Identity for a new user,
100
            // the updateIdentityCommand is used to update name or email of an identity
101
            // Both are only sent by the SS when the Identity is not logged in yet,
102
            // thus there is not Metadata::actorInstitution,
103
            if ($command instanceof CreateIdentityCommand || $command instanceof UpdateIdentityCommand) {
104
                return true;
105
            }
106
107
            // Validate if the actor is the user
108
            if ($command->getIdentityId() !== $actorId->getIdentityId()) {
0 ignored issues
show
Bug introduced by
It seems like $actorId is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
109
                return false;
110
            }
111
        }
112
113
        return true;
114
    }
115
116
    /**
117
     * @param Command $command
118
     * @param IdentityId|null $actorId
119
     * @param Institution|null $actorInstitution
120
     * @return bool
121
     */
122
    public function mayRaCommandBeExecutedOnBehalfOf(Command $command, IdentityId $actorId = null, Institution $actorInstitution = null)
123
    {
124
        // Assert RAA specific authorizations
125
        if ($command instanceof RaExecutable) {
126
            $this->logger->notice('Asserting a RA command');
127
128
            // The actor metadata should be set
129
            if (is_null($actorId) || is_null($actorInstitution)) {
130
                return false;
131
            }
132
133
            // If the actor is SRAA all actions should be allowed
134
            if ($this->isSraa($actorId)) {
135
                return true;
136
            }
137
138
            $raInstitution = $command->getRaInstitution();
139
            if (is_null($raInstitution)) {
140
                $raInstitution = $actorInstitution->getInstitution();
141
            }
142
143
            $authorizationContext = $this->authorizationContextService->buildInstitutionAuthorizationContext(
144
                $actorId,
145
                InstitutionRole::useRaa()
146
            );
147
148
            if (!$authorizationContext->getInstitutions()->contains(new Institution($raInstitution))) {
149
                return false;
150
            }
151
        }
152
153
        return true;
154
    }
155
156
    /**
157
     * @param IdentityId|null $actorId
158
     * @return bool
159
     */
160
    private function isSraa(IdentityId $actorId = null)
161
    {
162
        if (is_null($actorId)) {
163
            return false;
164
        }
165
166
        $registrationAuthorityCredentials = $this->identityService->findRegistrationAuthorityCredentialsOf($actorId->getIdentityId());
167
        if (!$registrationAuthorityCredentials) {
168
            return false;
169
        }
170
171
        if (!$registrationAuthorityCredentials->isSraa()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $registrationAuth...yCredentials->isSraa();.
Loading history...
172
            return false;
173
        }
174
175
        return true;
176
    }
177
}
178