Failed Conditions
Push — issue#774 ( 057f04...ee9377 )
by Guilherme
05:15
created

calculateSubjectIdentifier()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 4
nop 3
dl 0
loc 21
ccs 11
cts 11
cp 1
crap 3
rs 9.3142
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\OpenIDBundle\Service;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use LoginCidadao\CoreBundle\Model\PersonInterface;
15
use LoginCidadao\OAuthBundle\Model\ClientInterface;
16
use LoginCidadao\OpenIDBundle\Entity\ClientMetadata;
17
use LoginCidadao\OpenIDBundle\Entity\SubjectIdentifier;
18
use LoginCidadao\OpenIDBundle\Entity\SubjectIdentifierRepository;
19
20
class SubjectIdentifierService
21
{
22
    /** @var EntityManagerInterface */
23
    private $em;
24
25
    /** @var string */
26
    private $pairwiseSubjectIdSalt;
27
28
    /**
29
     * @var SubjectIdentifierRepository
30
     */
31
    private $subjectIdentifierRepo;
32
33
    /**
34
     * SubjectIdentifierService constructor.
35
     * @param EntityManagerInterface $em
36
     * @param SubjectIdentifierRepository $subjectIdentifierRepo
37
     * @param $pairwiseSubjectIdSalt
38
     */
39 9
    public function __construct(
40
        EntityManagerInterface $em,
41
        SubjectIdentifierRepository $subjectIdentifierRepo,
42
        $pairwiseSubjectIdSalt
43
    ) {
44 9
        $this->em = $em;
45 9
        $this->subjectIdentifierRepo = $subjectIdentifierRepo;
46 9
        $this->pairwiseSubjectIdSalt = $pairwiseSubjectIdSalt;
47 9
    }
48
49
    /**
50
     * @param PersonInterface $subject
51
     * @param ClientMetadata|null $metadata
52
     * @param bool $fetch do not try to fetch from the DB. Used as a performance boost for the subject identifier generator command.
53
     * @return string
54
     */
55 4
    public function getSubjectIdentifier(PersonInterface $subject, ClientMetadata $metadata = null, $fetch = true)
56
    {
57 4
        $sub = $fetch ? $this->fetchSubjectIdentifier($subject, $metadata) : null;
58
59 4
        if ($sub === null) {
60 3
            return $this->calculateSubjectIdentifier($subject, $metadata);
61
        }
62
63 1
        return $sub;
64
    }
65
66
    /**
67
     * @param PersonInterface $person
68
     * @param ClientInterface|ClientMetadata $client
69
     * @return bool
70
     */
71 1
    public function isSubjectIdentifierPersisted(PersonInterface $person, $client)
72
    {
73
        /** @var SubjectIdentifier $sub */
74 1
        $sub = $this->getSubjectIdentifierEntity($person, $client);
75
76 1
        return $client !== null && $sub instanceof SubjectIdentifier;
77
    }
78
79
    /**
80
     * @param $subjectIdentifier
81
     * @param ClientInterface|null $client
82
     * @return PersonInterface|null|object
83
     */
84 1
    public function getPerson($subjectIdentifier, ClientInterface $client = null)
85
    {
86 1
        $criteria = ['subjectIdentifier' => $subjectIdentifier];
87 1
        if ($client instanceof ClientInterface) {
88 1
            $criteria['client'] = $client;
89
        }
90
91 1
        return $this->subjectIdentifierRepo->findOneBy($criteria);
92
    }
93
94
    /**
95
     * @param PersonInterface $subject
96
     * @param ClientMetadata|ClientInterface $client
97
     * @return mixed|null
98
     * @internal param ClientInterface|ClientMetadata|null $metadata
99
     */
100 4
    private function fetchSubjectIdentifier(PersonInterface $subject, $client = null)
101
    {
102 4
        if (!$client) {
103 1
            return null;
104
        }
105
106
        /** @var SubjectIdentifier $sub */
107 3
        $sub = $this->getSubjectIdentifierEntity($subject, $client);
108
109 3
        if ($sub instanceof SubjectIdentifier) {
0 ignored issues
show
introduced by
$sub is always a sub-type of LoginCidadao\OpenIDBundle\Entity\SubjectIdentifier. If $sub can have other possible types, add them to src/LoginCidadao/OpenIDB...ctIdentifierService.php:106.
Loading history...
110 1
            return $sub->getSubjectIdentifier();
111
        }
112
113 2
        return null;
114
    }
115
116
    /**
117
     * @param PersonInterface $subject
118
     * @param ClientMetadata $metadata
119
     * @param string $forceSubjectType
120
     * @return mixed|string
121
     */
122 5
    private function calculateSubjectIdentifier(
123
        PersonInterface $subject,
124
        ClientMetadata $metadata = null,
125
        $forceSubjectType = null
126
    ) {
127 5
        $id = $subject->getId();
128
129 5
        $subjectType = $this->getSubjectType($metadata);
130 5
        if ($forceSubjectType !== null) {
131 1
            $subjectType = $forceSubjectType;
132
        }
133
134 5
        if ($subjectType === 'pairwise') {
135 2
            $sectorIdentifier = $metadata->getSectorIdentifier();
0 ignored issues
show
Bug introduced by
The method getSectorIdentifier() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
            /** @scrutinizer ignore-call */ 
136
            $sectorIdentifier = $metadata->getSectorIdentifier();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
136 2
            $salt = $this->pairwiseSubjectIdSalt;
137 2
            $pairwise = hash('sha256', $sectorIdentifier.$id.$salt);
138
139 2
            return $pairwise;
140
        }
141
142 3
        return $id;
143
    }
144
145
    /**
146
     * @param PersonInterface $person
147
     * @param ClientMetadata $metadata
148
     * @param bool $persist should the created SubjectIdentifier be persisted?
149
     * @return SubjectIdentifier
150
     */
151 2
    public function enforceSubjectIdentifier(PersonInterface $person, ClientMetadata $metadata, $persist = true)
152
    {
153 2
        $sub = $this->getSubjectIdentifierEntity($person, $metadata);
154 2
        if ($sub instanceof SubjectIdentifier) {
155 1
            return $sub;
156
        }
157
158 1
        $sub = (new SubjectIdentifier())
159 1
            ->setClient($metadata->getClient())
160 1
            ->setPerson($person)
161 1
            ->setSubjectIdentifier($this->calculateSubjectIdentifier($person, $metadata));
162
163 1
        if ($persist) {
164 1
            $this->em->persist($sub);
165 1
            $this->em->flush($sub);
166
        }
167
168 1
        return $sub;
169
    }
170
171
    /**
172
     * @param PersonInterface $person
173
     * @param ClientInterface|ClientMetadata $client
174
     * @return null|SubjectIdentifier
175
     */
176 7
    private function getSubjectIdentifierEntity(PersonInterface $person, $client)
177
    {
178 7
        if ($client instanceof ClientMetadata) {
179 6
            $client = $client->getClient();
180
        }
181
182
        /** @var null|SubjectIdentifier $subjectIdentifier */
183 7
        $subjectIdentifier = $this->subjectIdentifierRepo->findOneBy([
184 7
            'person' => $person,
185 7
            'client' => $client,
186
        ]);
187
188 7
        return $subjectIdentifier;
189
    }
190
191
    /**
192
     * @param ClientMetadata $metadata
193
     * @return string
194
     */
195 5
    private function getSubjectType(ClientMetadata $metadata = null)
196
    {
197 5
        return $metadata instanceof ClientMetadata && $metadata->getSubjectType() === 'pairwise' ? 'pairwise' : 'public';
198
    }
199
200
    /**
201
     * @param PersonInterface $person
202
     * @param ClientMetadata $metadata
203
     * @return SubjectIdentifier|null
204
     */
205 1
    public function convertSubjectIdentifier(PersonInterface $person, ClientMetadata $metadata)
206
    {
207 1
        $sub = $this->getSubjectIdentifierEntity($person, $metadata);
208
209 1
        $newSub = $this->calculateSubjectIdentifier($person, $metadata, 'pairwise');
210
211 1
        $sub->setSubjectIdentifier($newSub);
212
213 1
        return $sub;
214
    }
215
}
216