friendship ended with social-app. php is my new best friend
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 */
10declare(strict_types=1);
11
12namespace chillerlan\OAuth\Core;
13
14use chillerlan\HTTP\Utils\QueryUtil;
15use Psr\Http\Message\ResponseInterface;
16use function implode;
17use const PHP_QUERY_RFC1738;
18
19/**
20 * Implements Client Credentials functionality
21 *
22 * @see \chillerlan\OAuth\Core\ClientCredentials
23 */
24trait 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}