Failed Conditions
Push — issue#666 ( f415d0...521a08 )
by Guilherme
12:02
created

SubjectIdentifierService   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 155
ccs 52
cts 52
cp 1
rs 10
c 0
b 0
f 0
wmc 19

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getSubjectIdentifier() 0 9 3
A isSubjectIdentifierPersisted() 0 6 2
A calculateSubjectIdentifier() 0 13 3
A fetchSubjectIdentifier() 0 14 3
A getSubjectIdentifierEntity() 0 13 2
A enforceSubjectIdentifier() 0 18 3
A getPerson() 0 8 2
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(PersonInterface $subject, ClientMetadata $metadata = null)
117
    {
118 4
        $id = $subject->getId();
119
120 4
        if ($metadata instanceof ClientMetadata && $metadata->getSubjectType() === 'pairwise') {
121 1
            $sectorIdentifier = $metadata->getSectorIdentifier();
122 1
            $salt = $this->pairwiseSubjectIdSalt;
123 1
            $pairwise = hash('sha256', $sectorIdentifier.$id.$salt);
124
125 1
            return $pairwise;
126
        }
127
128 3
        return $id;
129
    }
130
131
    /**
132
     * @param PersonInterface $person
133
     * @param ClientMetadata $metadata
134
     * @param bool $persist should the created SubjectIdentifier be persisted?
135
     * @return SubjectIdentifier
136
     */
137 2
    public function enforceSubjectIdentifier(PersonInterface $person, ClientMetadata $metadata, $persist = true)
138
    {
139 2
        $sub = $this->getSubjectIdentifierEntity($person, $metadata);
140 2
        if ($sub instanceof SubjectIdentifier) {
141 1
            return $sub;
142
        }
143
144 1
        $sub = (new SubjectIdentifier())
145 1
            ->setClient($metadata->getClient())
146 1
            ->setPerson($person)
147 1
            ->setSubjectIdentifier($this->calculateSubjectIdentifier($person, $metadata));
148
149 1
        if ($persist) {
150 1
            $this->em->persist($sub);
151 1
            $this->em->flush($sub);
152
        }
153
154 1
        return $sub;
155
    }
156
157
    /**
158
     * @param PersonInterface $person
159
     * @param ClientInterface|ClientMetadata $client
160
     * @return null|SubjectIdentifier
161
     */
162 6
    private function getSubjectIdentifierEntity(PersonInterface $person, $client)
163
    {
164 6
        if ($client instanceof ClientMetadata) {
165 5
            $client = $client->getClient();
166
        }
167
168
        /** @var null|SubjectIdentifier $subjectIdentifier */
169 6
        $subjectIdentifier = $this->subjectIdentifierRepo->findOneBy([
170 6
            'person' => $person,
171 6
            'client' => $client,
172
        ]);
173
174 6
        return $subjectIdentifier;
175
    }
176
}
177