Completed
Pull Request — development (#3)
by Philippe
04:45 queued 02:15
created

HubicService::deleteLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
crap 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 Filoucrackeur\Hubic\Domain\Repository\AccountRepository;
21
use GuzzleHttp\RequestOptions;
22
use Psr\Http\Message\ResponseInterface;
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\Mvc\Web\Routing\UriBuilder;
28
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
29
30
class HubicService implements SingletonInterface
31
{
32
    const AUTHORIZATION_ENDPOINT = 'https://api.hubic.com/oauth/auth/';
33
34
    const TOKEN_ENDPOINT = 'https://api.hubic.com/oauth/token/';
35
36
    const DOMAIN_API = 'https://api.hubic.com/';
37
38
    const VERSION_API = '1.0';
39
40
    /**
41
     * @var RequestFactory
42
     */
43
    protected $requestFactory;
44
45
    /**
46
     * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
47
     */
48
    protected $persistenceManager;
49
50
    /**
51
     * @var \Filoucrackeur\Hubic\Domain\Repository\AccountRepository
52
     */
53
    protected $accountRepository;
54
55
    /**
56
     * @var \Filoucrackeur\Hubic\Domain\Model\Account
57
     */
58
    protected $account;
59
60
    /**
61
     * @param Account $account
62
     *
63
     * @return bool
64
     * @throws \RuntimeException
65
     */
66 1
    public function accessToken(Account $account): bool
67
    {
68 1
        $credentials = base64_encode($account->getClientId() . ':' . $account->getClientSecret());
69
        $additionalOptions = [
70
            'headers' => [
71 1
                'Content-Type' => 'application/x-www-form-urlencoded',
72 1
                'Authorization' => 'Basic ' . $credentials,
73
            ],
74 1
            RequestOptions::FORM_PARAMS => [
75 1
                'code' => GeneralUtility::_GET('code'),
76 1
                'redirect_uri' => $this->getHost() . '/',
77 1
                'grant_type' => 'authorization_code',
78
            ],
79 1
            RequestOptions::VERSION => '1.1',
80
        ];
81
82 1
        $response = $this->requestFactory->request(self::TOKEN_ENDPOINT, 'POST', $additionalOptions);
83
84 1
        if (200 === $response->getStatusCode()) {
85 1
            $content = json_decode($response->getBody()->getContents());
86 1
            $account->setAccessToken($content->access_token);
87 1
            $account->setRefreshToken($content->refresh_token);
88 1
            $expireIn = new \DateTime('+ ' . (int)$content->expires_in . ' seconds');
89 1
            $account->setExpirationDate($expireIn);
90 1
            $this->persistenceManager->update($account);
91 1
            $this->persistenceManager->persistAll();
92
        }
93
94 1
        return true;
95
    }
96
97
    /**
98
     * @return string
99
     */
100 2
    public function getHost(): string
101
    {
102 2
        return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
103
    }
104
105
    /**
106
     * @param Account $account
107
     */
108
    public function redirectUrlRequestToken(Account $account)
109
    {
110
        $arguments = [
111
            'client_id' => $account->getClientId(),
112
            'redirect_uri' => $this->getRedirectUri($account),
113
            'scope' => $account->getScope(),
114
            'response_type' => 'code',
115
            'state' => time(),
116
        ];
117
118
        $uri = self::AUTHORIZATION_ENDPOINT . '?' . urldecode(http_build_query($arguments));
119
        header('Location: ' . $uri);
120
    }
121
122
    /**
123
     * @param Account $account
124
     *
125
     * @return string
126
     */
127
    public function getRedirectUri(Account $account): string
128
    {
129
        $formProtection = FormProtectionFactory::get();
130
        $formToken = $formProtection->generateToken('AuthorizationRequest');
131
132
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
133
134
        return urlencode($this->getHost() . $uriBuilder
135
                ->setCreateAbsoluteUri(true)
136
                ->setArguments([
137
                    'tx_hubic_tools_hubichubic' => [
138
                        'action' => 'callback',
139
                        'controller' => 'Backend\Account',
140
                        'account' => $account->getUid(),
141
                    ],
142
                    'formToken' => $formToken
143
                ])->buildBackendUri());
144
    }
145
146
    /**
147
     * @return ResponseInterface|string
148
     */
149 1
    public function getAccount()
150
    {
151 1
        return $this->fetch('/account');
152
    }
153
154
    /**
155
     * @param Account $account
156
     */
157 7
    public function setAccount(Account $account)
158
    {
159 7
        $this->account = $account;
160 7
    }
161
162
    /**
163
     * @param string $path
164
     * @param string $method
165
     * @param array $arguments
166
     * @return \Psr\Http\Message\ResponseInterface|string
167
     */
168 1
    public function fetch(string $path, $method = 'GET', array $arguments = [])
169
    {
170
        $additionalOptions = [
171
            'headers' => [
172 1
                'Content-Type' => 'application/x-www-form-urlencoded',
173 1
                'Authorization' => 'Bearer ' . $this->account->getAccessToken(),
174
            ],
175 1
            RequestOptions::VERSION => '1.1',
176
        ];
177
178 1
        if (!empty($arguments)) {
179
            $additionalOptions[RequestOptions::FORM_PARAMS] = $arguments;
180
        }
181
182
        try {
183 1
            $response = $this->requestFactory->request(self::DOMAIN_API . self::VERSION_API . $path, $method,
184 1
                $additionalOptions);
185
186 1
            if (200 === $response->getStatusCode()) {
187 1
                return json_decode($response->getBody()->getContents());
188
            }
189
        } catch (\Exception $e) {
190
            if ($this->refreshToken($this->account)) {
191
                return $this->fetch($path, $method);
192
            }
193
        }
194 1
        return null;
195
    }
196
197
    /**
198
     * @param Account $account
199
     * @return bool
200
     */
201 1
    public function refreshToken(Account $account): bool
202
    {
203
204 1
        $credentials = base64_encode($account->getClientId() . ':' . $account->getClientSecret());
205
        $additionalOptions = [
206
            'headers' => [
207 1
                'Content-Type' => 'application/x-www-form-urlencoded',
208 1
                'Authorization' => 'Basic ' . $credentials,
209
            ],
210 1
            RequestOptions::FORM_PARAMS => [
211 1
                'refresh_token' => $account->getRefreshToken(),
212 1
                'grant_type' => 'refresh_token',
213
            ],
214 1
            RequestOptions::VERSION => '1.1',
215
        ];
216
217 1
        $response = $this->requestFactory->request(self::TOKEN_ENDPOINT, 'POST', $additionalOptions);
218
219 1
        if (200 === $response->getStatusCode()) {
220 1
            $content = json_decode($response->getBody()->getContents());
221 1
            $account->setAccessToken($content->access_token);
222 1
            $this->persistenceManager->update($account);
223 1
            $this->persistenceManager->persistAll();
224
        }
225
226 1
        return true;
227
    }
228
229
    /**
230
     * @param Account $account
231
     */
232 1
    public function delete(Account $account)
233
    {
234 1
        $this->persistenceManager->remove($account);
235 1
        $this->persistenceManager->persistAll();
236 1
    }
237
238
    /**
239
     * @param Account $account
240
     */
241 1
    public function unlink(Account $account)
242
    {
243 1
        $account->setAccessToken('');
244 1
        $account->setRefreshToken('');
245 1
        $this->persistenceManager->update($account);
246 1
        $this->persistenceManager->persistAll();
247 1
    }
248
249
    /**
250
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
251
     */
252 1
    public function getAccounts()
253
    {
254 1
        return $this->accountRepository->findAll();
255
    }
256
257
    /**
258
     * Get hubiC account Quota.
259
     *
260
     * @see https://api.hubic.com/console/
261
     *
262
     * @return ResponseInterface|null
263
     */
264 1
    public function getAccountQuota()
265
    {
266 1
        return $this->fetch('/account/usage');
267
    }
268
269
    /**
270
     * Get hubiC agreements.
271
     *
272
     * @see https://api.hubic.com/console/
273
     *
274
     * @return ResponseInterface|null
275
     */
276 1
    public function getAgreement()
277
    {
278 1
        return $this->fetch('/agreement');
279
    }
280
281
    /**
282
     * Get hubiC getAllLinks.
283
     *
284
     * @see https://api.hubic.com/console/
285
     *
286
     * @return ResponseInterface|null
287
     */
288 2
    public function getAllLinks()
289
    {
290 2
        return $this->fetch('/account/getAllLinks');
291
    }
292
293
    /**
294
     * Delete hubiC link.
295
     *
296
     * @see https://api.hubic.com/console/
297
     *
298
     * @param Account $account
299
     * @param string $uri
300
     * @return ResponseInterface|null
301
     */
302 1
    public function deleteLink(Account $account, string $uri)
303
    {
304 1
        $this->setAccount($account);
305
306
        $arguments = [
307 1
            'uri' => $uri
308
        ];
309
310 1
        return $this->fetch('/account/link', 'DELETE', $arguments);
311
    }
312
313
    /**
314
     * @param RequestFactory $requestFactory
315
     */
316 13
    public function injectRequestFactory(RequestFactory $requestFactory)
317
    {
318 13
        $this->requestFactory = $requestFactory;
319 13
    }
320
321
    /**
322
     * @param PersistenceManager $persistenceManager
323
     */
324 12
    public function injectPersistenceManager(PersistenceManager $persistenceManager)
325
    {
326 12
        $this->persistenceManager = $persistenceManager;
327 12
    }
328
329
    /**
330
     * @param AccountRepository $accountRepository
331
     */
332 1
    public function injectAccountRepository(AccountRepository $accountRepository)
333
    {
334 1
        $this->accountRepository = $accountRepository;
335 1
    }
336
}
337