Test Failed
Branch development (214703)
by Philippe
02:20
created

HubicService::getRedirectUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 1
1
<?php
2
/*
3
 * This program is free software: you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation, either version 3 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 */
16
17
namespace Filoucrackeur\Hubic\Service;
18
19
use Filoucrackeur\Hubic\Domain\Model\Account;
20
use GuzzleHttp\RequestOptions;
21
use Psr\Http\Message\ResponseInterface;
22
use TYPO3\CMS\Backend\Utility\BackendUtility;
23
use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
24
use TYPO3\CMS\Core\Http\RequestFactory;
25
use TYPO3\CMS\Core\SingletonInterface;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
28
29
class HubicService implements SingletonInterface
30
{
31
    public const AUTHORIZATION_ENDPOINT = 'https://api.hubic.com/oauth/auth/';
32
33
    public const TOKEN_ENDPOINT = 'https://api.hubic.com/oauth/token/';
34
35
    public const DOMAIN_API = 'https://api.hubic.com/';
36
37
    public const VERSION_API = '1.0';
38
39
    /**
40
     * @var RequestFactory
41
     */
42
    protected $requestFactory;
43
44
    /**
45
     * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
46
     */
47
    protected $persistenceManager;
48
49
    /**
50
     * @var \Filoucrackeur\Hubic\Domain\Model\Account
51
     */
52
    protected $account;
53
54
    /**
55
     * @param Account $account
56
     */
57
    public function setAccount(Account $account)
58
    {
59
        $this->account = $account;
60
    }
61
62
    /**
63
     * @param Account $account
64
     *
65
     * @return bool
66
     */
67
    public function accessToken(Account $account)
68
    {
69
        $credentials = base64_encode($account->getClientId() . ':' . $account->getClientSecret());
70
        $additionalOptions = [
71
            'headers' => [
72
                'Content-Type' => 'application/x-www-form-urlencoded',
73
                'Authorization' => 'Basic ' . $credentials,
74
            ],
75
            RequestOptions::FORM_PARAMS => [
76
                'code' => GeneralUtility::_GET('code'),
77
                'redirect_uri' => 'http://localhost/',
78
                'grant_type' => 'authorization_code',
79
            ],
80
            RequestOptions::VERSION => '1.1',
81
        ];
82
83
        $response = $this->requestFactory->request(self::TOKEN_ENDPOINT, 'POST', $additionalOptions);
84
85
        if (200 === $response->getStatusCode()) {
86
            $content = json_decode($response->getBody()->getContents());
87
            $account->setAccessToken($content->access_token);
88
            $account->setRefreshToken($content->refresh_token);
89
            $this->persistenceManager->update($account);
90
            $this->persistenceManager->persistAll();
91
        }
92
93
        return true;
94
    }
95
96
    /**
97
     * @param Account $account
98
     */
99
    public function refreshToken(Account $account)
100
    {
101
102
        $credentials = base64_encode($account->getClientId() . ':' . $account->getClientSecret());
103
        $additionalOptions = [
104
            'headers' => [
105
                'Content-Type' => 'application/x-www-form-urlencoded',
106
                'Authorization' => 'Basic ' . $credentials,
107
            ],
108
            RequestOptions::FORM_PARAMS => [
109
                'refresh_token' => $account->getRefreshToken(),
110
                'grant_type' => 'refresh_token',
111
            ],
112
            RequestOptions::VERSION => '1.1',
113
        ];
114
115
        $response = $this->requestFactory->request(self::TOKEN_ENDPOINT, 'POST', $additionalOptions);
116
117
        if (200 === $response->getStatusCode()) {
118
            $content = json_decode($response->getBody()->getContents());
119
            $account->setAccessToken($content->access_token);
120
            $this->persistenceManager->update($account);
121
            $this->persistenceManager->persistAll();
122
        }
123
124
        return true;
125
    }
126
127
    /**
128
     * @param string $path
129
     * @param string $method
130
     *
131
     * @return \Psr\Http\Message\ResponseInterface
132
     */
133
    public function fetch(string $path, $method = 'GET')
134
    {
135
136
        $additionalOptions = [
137
            'headers' => [
138
                'Content-Type' => 'application/x-www-form-urlencoded',
139
                'Authorization' => 'Bearer ' . $this->account->getAccessToken(),
140
            ],
141
            RequestOptions::VERSION => '1.1',
142
        ];
143
144
        try {
145
            $response = $this->requestFactory->request(self::DOMAIN_API . self::VERSION_API . $path, $method, $additionalOptions);
146
147
            if (200 === $response->getStatusCode()) {
148
                return json_decode($response->getBody()->getContents());
149
            }
150
        } catch (\Exception $e) {
151
            if ($this->refreshToken($this->account)) {
152
                return $this->fetch($path, $method);
153
            }
154
        }
155
    }
156
157
    /**
158
     * @param Account $account
159
     */
160
    public function redirectUrlRequestToken(Account $account)
161
    {
162
        $arguments = [
163
            'client_id' => $account->getClientId(),
164
            'redirect_uri' => $this->getRedirectUri($account),
165
            'scope' => $account->getScope(),
166
            'response_type' => 'code',
167
            'state' => time(),
168
        ];
169
170
        $uri = self::AUTHORIZATION_ENDPOINT . '?' . urldecode(http_build_query($arguments));
171
        header('Location: ' . $uri);
172
        die();
173
    }
174
175
    /**
176
     * @param Account $account
177
     *
178
     * @return string
179
     */
180
    private function getRedirectUri(Account $account)
181
    {
182
        $formProtection = FormProtectionFactory::get();
183
        $formToken = $formProtection->generateToken('AuthorizationRequest');
184
185
        return urlencode('http://' . $_SERVER['HTTP_HOST'] . BackendUtility::getModuleUrl('tools_HubicHubic', [
186
                'tx_hubic_tools_hubichubic' => [
187
                    'action' => 'callback',
188
                    'controller' => 'Backend\Account',
189
                    'account' => $account->getUid(),
190
                ],
191
                'formToken' => $formToken,
192
            ]));
193
    }
194
195
    public function getAccount()
196
    {
197
        return $this->fetch('/account');
198
    }
199
200
    /**
201
     * Get hubiC account Quota.
202
     *
203
     * @see https://api.hubic.com/console/
204
     *
205
     * @return ResponseInterface
206
     */
207
    public function getAccountQuota()
208
    {
209
        return $this->fetch('/account/usage');
210
    }
211
212
    /**
213
     * Get hubiC agreements.
214
     *
215
     * @see https://api.hubic.com/console/
216
     *
217
     * @return ResponseInterface
218
     */
219
    public function getAgreement()
220
    {
221
        return $this->fetch('/agreement');
222
    }
223
224
    /**
225
     * Get hubiC getAllLinks.
226
     *
227
     * @see https://api.hubic.com/console/
228
     *
229
     * @return ResponseInterface
230
     */
231
    public function getAllLinks()
232
    {
233
        return $this->fetch('/account/getAllLinks');
234
    }
235
236
    /**
237
     * @param RequestFactory $requestFactory
238
     */
239
    public function injectRequestFactory(RequestFactory $requestFactory)
240
    {
241
        $this->requestFactory = $requestFactory;
242
    }
243
244
    /**
245
     * @param PersistenceManager $persistenceManager
246
     */
247
    public function injectPersistenceManager(PersistenceManager $persistenceManager): void
248
    {
249
        $this->persistenceManager = $persistenceManager;
250
    }
251
}
252