Skip to content

Commit 3a13a22

Browse files
committed
🛀 extract OAuth2 RFC features into traits to reduce bloat
1 parent 6affa64 commit 3a13a22

31 files changed

+510
-415
lines changed

.phpstan/baseline-lt-8.2.neon

+3-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
parameters:
22
ignoreErrors:
3-
-
4-
message: "#^Call to method getBytesFromString\\(\\) on an unknown class Random\\\\Randomizer\\.$#"
5-
count: 1
6-
path: ../src/Core/OAuth2Provider.php
7-
8-
-
9-
message: "#^Instantiated class Random\\\\Engine\\\\Secure not found\\.$#"
10-
count: 1
11-
path: ../src/Core/OAuth2Provider.php
12-
13-
-
14-
message: "#^Instantiated class Random\\\\Randomizer not found\\.$#"
15-
count: 1
16-
path: ../src/Core/OAuth2Provider.php
17-
3+
- message: "#^Call to method getBytesFromString\\(\\) on an unknown class Random\\\\Randomizer\\.$#"
4+
- message: "#^Instantiated class Random\\\\Engine\\\\Secure not found\\.$#"
5+
- message: "#^Instantiated class Random\\\\Randomizer not found\\.$#"

.phpstan/baseline-lt-8.3.neon

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
parameters:
22
ignoreErrors:
3-
-
4-
message: "#^Call to an undefined method Random\\\\Randomizer\\:\\:getBytesFromString\\(\\)\\.$#"
5-
count: 1
6-
path: ../src/Core/OAuth2Provider.php
7-
3+
- message: "#^Call to an undefined method Random\\\\Randomizer\\:\\:getBytesFromString\\(\\)\\.$#"

src/Core/ClientCredentialsTrait.php

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/**
3+
* Trait ClientCredentialsTrait
4+
*
5+
* @created 19.09.2024
6+
* @author smiley <smiley@chillerlan.net>
7+
* @copyright 2024 smiley
8+
* @license MIT
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace chillerlan\OAuth\Core;
13+
14+
use chillerlan\HTTP\Utils\QueryUtil;
15+
use Psr\Http\Message\ResponseInterface;
16+
use function implode;
17+
use const PHP_QUERY_RFC1738;
18+
19+
/**
20+
* Implements Client Credentials functionality
21+
*
22+
* @see \chillerlan\OAuth\Core\ClientCredentials
23+
*/
24+
trait ClientCredentialsTrait{
25+
26+
/**
27+
* implements ClientCredentials::getClientCredentialsToken()
28+
*
29+
* @see \chillerlan\OAuth\Core\ClientCredentials::getClientCredentialsToken()
30+
*
31+
* @param string[]|null $scopes
32+
* @throws \chillerlan\OAuth\Providers\ProviderException
33+
*/
34+
public function getClientCredentialsToken(array|null $scopes = null):AccessToken{
35+
$body = $this->getClientCredentialsTokenRequestBodyParams($scopes);
36+
$response = $this->sendClientCredentialsTokenRequest(($this->clientCredentialsTokenURL ?? $this->accessTokenURL), $body);
37+
$token = $this->parseTokenResponse($response);
38+
39+
// provider didn't send a set of scopes with the token response, so add the given ones manually
40+
if(empty($token->scopes)){
41+
$token->scopes = ($scopes ?? []);
42+
}
43+
44+
$this->storage->storeAccessToken($token, $this->name);
45+
46+
return $token;
47+
}
48+
49+
/**
50+
* prepares the request body parameters for the client credentials token request
51+
*
52+
* @see \chillerlan\OAuth\Core\OAuth2Provider::getClientCredentialsToken()
53+
*
54+
* @param string[]|null $scopes
55+
* @return array<string, string>
56+
*/
57+
protected function getClientCredentialsTokenRequestBodyParams(array|null $scopes):array{
58+
$body = ['grant_type' => 'client_credentials'];
59+
60+
if(!empty($scopes)){
61+
$body['scope'] = implode($this::SCOPES_DELIMITER, $scopes);
62+
}
63+
64+
return $body;
65+
}
66+
67+
/**
68+
* sends a request to the client credentials endpoint, using basic authentication
69+
*
70+
* @see \chillerlan\OAuth\Core\OAuth2Provider::getClientCredentialsToken()
71+
*
72+
* @param array<string, scalar> $body
73+
*/
74+
protected function sendClientCredentialsTokenRequest(string $url, array $body):ResponseInterface{
75+
76+
$request = $this->requestFactory
77+
->createRequest('POST', $url)
78+
->withHeader('Accept', 'application/json')
79+
->withHeader('Accept-Encoding', 'identity')
80+
->withHeader('Content-Type', 'application/x-www-form-urlencoded')
81+
->withBody($this->streamFactory->createStream(QueryUtil::build($body, PHP_QUERY_RFC1738)))
82+
;
83+
84+
foreach($this::HEADERS_AUTH as $header => $value){
85+
$request = $request->withHeader($header, $value);
86+
}
87+
88+
$request = $this->addBasicAuthHeader($request);
89+
90+
return $this->http->sendRequest($request);
91+
}
92+
93+
}

0 commit comments

Comments
 (0)