Passed
Push — main ( e1532e...a8ba51 )
by Breno
02:01
created

GovBr::getAuthorizationUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace BrenoRoosevelt\OAuth2\Client;
5
6
use Exception;
7
use League\OAuth2\Client\Provider\AbstractProvider;
8
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
9
use League\OAuth2\Client\Token\AccessToken;
10
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
11
use Psr\Http\Message\ResponseInterface;
12
13
class GovBr extends AbstractProvider
14
{
15
    use BearerAuthorizationTrait;
16
17
    private $urlAuthorize;
18
    private $urlAccessToken;
19
    private $urlResourceOwnerDetails;
20
21
    final public function __construct(array $options = [], array $collaborators = [])
22
    {
23
        list(
24
            $this->urlAuthorize,
25
            $this->urlAccessToken,
26
            $this->urlResourceOwnerDetails
27
        ) = array_values(self::productionEnvironment());
28
29
        parent::__construct($options, $collaborators);
30
    }
31
32
    /**
33
     * Cria uma instância para ambiente de homologação
34
     *
35
     * @param array $options
36
     * @param array $collaborators
37
     * @return self
38
     */
39
    public static function staging(array $options, array $collaborators = []): self
40
    {
41
        $staging = new self($options, $collaborators);
42
        list(
43
            $staging->urlAuthorize,
44
            $staging->urlAccessToken,
45
            $staging->urlResourceOwnerDetails
46
        ) = array_values(self::stagingEnvironment());
47
48
        return $staging;
49
    }
50
51
    /**
52
     * Cria uma instância para ambiente de produção
53
     * Pode ser criado diretamente via construtor
54
     *
55
     * @param array $options
56
     * @param array $collaborators
57
     * @return self
58
     */
59
    public static function production(array $options, array $collaborators = []): self
60
    {
61
        return new self($options, $collaborators);
62
    }
63
64
    public function getDefaultScopes(): array
65
    {
66
        return [
67
            'openid',
68
            'email',
69
            'phone',
70
            'profile',
71
            'govbr_confiabilidades'
72
        ];
73
    }
74
75
    public function getScopeSeparator(): string
76
    {
77
        return '+';
78
    }
79
80
    protected function getAuthorizationParameters(array $options): array
81
    {
82
        if (!isset($options['nonce'])) {
83
            $options['nonce'] = md5(uniqid('govbr', true));
84
        }
85
86
        return parent::getAuthorizationParameters($options);
87
    }
88
    /**
89
     * @inheritDoc
90
     */
91
    protected function createResourceOwner(array $response, AccessToken $token)
92
    {
93
        return new GovBrUser($response, $token);
94
    }
95
96
    public function getAvatar(GovBrUser $govBrUser): ?Avatar
97
    {
98
        $request = $this->getAuthenticatedRequest(
99
            self::METHOD_GET,
100
            $govBrUser->getAvatarUrl(),
101
            $govBrUser->token()
102
        );
103
104
        $response = $this->getResponse($request);
105
106
        return
107
            new Avatar(
108
                (string) $response->getBody(),
109
                $response->getHeaderLine('Content-type')
110
            );
111
    }
112
113
    private static function productionEnvironment(): array
114
    {
115
        return [
116
            'urlAuthorize'            => 'https://sso.acesso.gov.br/authorize',
117
            'urlAccessToken'          => 'https://sso.acesso.gov.br/token',
118
            'urlResourceOwnerDetails' => 'https://sso.acesso.gov.br/userinfo',
119
        ];
120
    }
121
122
    private static function stagingEnvironment(): array
123
    {
124
        return [
125
            'urlAuthorize'            => 'https://sso.staging.acesso.gov.br/authorize',
126
            'urlAccessToken'          => 'https://sso.staging.acesso.gov.br/token',
127
            'urlResourceOwnerDetails' => 'https://sso.staging.acesso.gov.br/userinfo',
128
        ];
129
    }
130
131
    public function getBaseAuthorizationUrl(): string
132
    {
133
        return $this->urlAuthorize;
134
    }
135
136
    public function getBaseAccessTokenUrl(array $params): string
137
    {
138
        return $this->urlAccessToken;
139
    }
140
141
    public function getResourceOwnerDetailsUrl(AccessToken $token): string
142
    {
143
        return $this->urlResourceOwnerDetails;
144
    }
145
146
    /**
147
     * @param ResponseInterface $response
148
     * @param array|string $data
149
     * @throws IdentityProviderException
150
     * @see https://manual-roteiro-integracao-login-unico.servicos.gov.br/pt/stable/iniciarintegracao.html#resultados-esperados-ou-erros-do-acesso-ao-servicos-do-login-unico
151
     */
152
    protected function checkResponse(ResponseInterface $response, $data)
153
    {
154
        $code = $response->getStatusCode();
155
        $errorResponse = ($code >= 400 && $code <= 599);
156
157
        if (isset($data['error']) || $errorResponse) {
158
            $error = $data['descricao'] ?? $data['error'] ?? (string) $response->getBody();
159
            if (!is_string($error)) {
160
                $error = var_export($error, true);
161
            }
162
163
            $errorCode = $data['codigo'] ?? $code;
164
            throw new IdentityProviderException($error, $errorCode, $data);
165
        }
166
    }
167
}
168