Failed Conditions
Push — issue#702_rs ( ed72a1...cdafcf )
by Guilherme
07:33
created

ClientManager::populateNewMetadata()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 19
nc 8
nop 1
dl 0
loc 36
rs 8.439
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\Manager;
12
13
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
14
use Doctrine\ORM\EntityManagerInterface;
15
use LoginCidadao\CoreBundle\Entity\PersonRepository;
16
use LoginCidadao\CoreBundle\Event\GetClientEvent;
17
use LoginCidadao\CoreBundle\Event\LoginCidadaoCoreEvents;
18
use LoginCidadao\CoreBundle\Model\PersonInterface;
19
use LoginCidadao\OAuthBundle\Model\ClientInterface;
20
use LoginCidadao\OpenIDBundle\Entity\ClientMetadata;
21
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
22
23
class ClientManager
24
{
25
    /** @var EventDispatcherInterface */
26
    private $dispatcher;
27
28
    /** @var EntityManagerInterface */
29
    private $em;
30
31
    /** @var PersonRepository */
32
    private $personRepository;
33
34
    /** @var string */
35
    private $publicScopes;
36
37
    /**
38
     * ClientManager constructor.
39
     * @param EntityManagerInterface $em
40
     * @param EventDispatcherInterface $dispatcher
41
     * @param PersonRepository $personRepository
42
     * @param $publicScopes
43
     */
44
    public function __construct(
45
        EntityManagerInterface $em,
46
        EventDispatcherInterface $dispatcher,
47
        PersonRepository $personRepository,
48
        $publicScopes
49
    ) {
50
        $this->em = $em;
51
        $this->dispatcher = $dispatcher;
52
        $this->personRepository = $personRepository;
53
        $this->publicScopes = $publicScopes;
54
    }
55
56
    /**
57
     * @param mixed $id
58
     * @return ClientInterface|null
59
     */
60
    public function getClientById($id)
61
    {
62
        if ($id === null) {
63
            return null;
64
        }
65
        $randomId = null;
66
        if (strstr($id, '_') !== false) {
67
            $parts = explode('_', $id);
68
            $id = $parts[0];
69
            $randomId = $parts[1];
70
        }
71
72
        $repo = $this->em->getRepository('LoginCidadaoOAuthBundle:Client');
73
74
        if ($randomId) {
75
            $client = $repo->findOneBy([
76
                'id' => $id,
77
                'randomId' => $randomId,
78
            ]);
79
        } else {
80
            $client = $repo->find($id);
81
        }
82
        $event = new GetClientEvent($client);
83
        $this->dispatcher->dispatch(LoginCidadaoCoreEvents::GET_CLIENT, $event);
84
85
        return $event->getClient();
86
    }
87
88
    /**
89
     * @param ClientMetadata $data
90
     * @return ClientInterface
91
     * @throws UniqueConstraintViolationException
92
     */
93
    public function register(ClientMetadata $data)
94
    {
95
        $client = $data->getClient();
96
97
        $this->em->persist($client);
98
99
        $data->setClient($client);
100
        $this->em->persist($data);
101
102
        $this->em->flush();
103
104
        return $client;
105
    }
106
107
    private function sanitizeClient(ClientInterface $client)
108
    {
109
        if ($client->getName() === null) {
110
            $firstUrl = $client->getRedirectUris()
111
                ? parse_url($client->getRedirectUris()[0], PHP_URL_HOST)
112
                : 'Unamed Client';
113
            $client->setName($firstUrl);
114
        }
115
        if ($client->getDescription() === null) {
116
            $client->setDescription('');
117
        }
118
        if ($client->getTermsOfUseUrl() === null) {
119
            $client->setTermsOfUseUrl('');
120
        }
121
        if ($client->getSiteUrl() === null) {
122
            $client->setSiteUrl('');
123
        }
124
125
        return $client;
126
    }
127
128
    public function populateNewMetadata(ClientMetadata $data)
129
    {
130
        $this->initializeRegistrationAccessToken($data);
131
132
        if ($data->getClient() === null) {
133
            $client = $data->toClient();
134
        } else {
135
            $client = $data->getClient();
136
        }
137
138
        $client = $this->sanitizeClient($client);
139
        if ($data->getClientName() === null) {
140
            $data->setClientName($client->getName());
141
        }
142
143
        if (count($data->getContacts()) > 0) {
144
            /** @var PersonInterface[] $owners */
145
            $owners = $this->personRepository->findBy([
146
                'email' => $data->getContacts(),
147
            ]);
148
149
            foreach ($owners as $person) {
150
                if (!$person->getEmailConfirmedAt() instanceof \DateTime) {
151
                    // Email is not verified. Skipping...
152
                    continue;
153
                }
154
                $client->getOwners()->add($person);
155
            }
156
        }
157
158
        $publicScopes = explode(' ', $this->publicScopes);
159
        $client->setAllowedScopes($publicScopes);
160
161
        $data->setClient($client);
162
163
        return $data;
164
    }
165
166
    private function initializeRegistrationAccessToken(ClientMetadata &$data)
167
    {
168
        if (null === $data->getRegistrationAccessToken()) {
169
            $registrationAccessToken = bin2hex(random_bytes(120));
170
            $data->setRegistrationAccessToken($registrationAccessToken);
171
        }
172
    }
173
}
174