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

isSubjectIdentifierPersisted()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 2
rs 9.4285
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.
Loading history...
110 1
            return $sub->getSubjectIdentifier();
111
        }
112
113 2
        return null;
114
    }
115
116 4
    private function calculateSubjectIdentifier(
117
        PersonInterface $subject,
118
        ClientMetadata $metadata = null,
119
        $forceSubjectType = null
120
    ) {
121 4
        $id = $subject->getId();
122
123 4
        $subjectType = $this->getSubjectType($metadata);
124 4
        if ($forceSubjectType !== null) {
125
            $subjectType = $forceSubjectType;
126
        }
127
128 4
        if ($subjectType === 'pairwise') {
129 1
            $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

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