Passed
Push — main ( d68b9c...2c74b5 )
by smiley
01:38
created

NPROne::getRequestTarget()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 21
rs 10
cc 4
nc 4
nop 1
1
<?php
2
/**
3
 * Class NPROne
4
 *
5
 * @link https://dev.npr.org
6
 * @link https://github.com/npr/npr-one-backend-proxy-php
7
 *
8
 * @created      28.07.2019
9
 * @author       smiley <[email protected]>
10
 * @copyright    2019 smiley
11
 * @license      MIT
12
 */
13
14
namespace chillerlan\OAuth\Providers\NPR;
15
16
use chillerlan\OAuth\Core\{CSRFToken, OAuth2Provider, ProviderException, TokenRefresh};
17
use Psr\Http\Message\{RequestInterface, ResponseInterface};
18
19
use function parse_url, strpos;
20
21
/**
22
 * @method \Psr\Http\Message\ResponseInterface identityFollowing(array $body = ['Affiliation'])
23
 * @method \Psr\Http\Message\ResponseInterface identityInherit(array $body = ['UserDocument'])
24
 * @method \Psr\Http\Message\ResponseInterface identityStations(array $body = ['StationIDs'])
25
 * @method \Psr\Http\Message\ResponseInterface identityUser()
26
 * @method \Psr\Http\Message\ResponseInterface listeningAggregationRecommendations(string $aggId)
27
 * @method \Psr\Http\Message\ResponseInterface listeningChannels()
28
 * @method \Psr\Http\Message\ResponseInterface listeningHistory()
29
 * @method \Psr\Http\Message\ResponseInterface listeningOrgCategoryRecommendations(string $orgId, string $category)
30
 * @method \Psr\Http\Message\ResponseInterface listeningOrgRecommendations(string $orgId)
31
 * @method \Psr\Http\Message\ResponseInterface listeningPromoRecommendations()
32
 * @method \Psr\Http\Message\ResponseInterface listeningRatings(array $body = ['RatingData'])
33
 * @method \Psr\Http\Message\ResponseInterface listeningRecommendations()
34
 * @method \Psr\Http\Message\ResponseInterface listeningSearchRecommendations()
35
 * @method \Psr\Http\Message\ResponseInterface station(string $stationId)
36
 * @method \Psr\Http\Message\ResponseInterface stations()
37
 */
38
class NPROne extends OAuth2Provider implements CSRFToken, TokenRefresh{
39
40
	public const SCOPE_IDENTITY_READONLY  = 'identity.readonly';
41
	public const SCOPE_IDENTITY_WRITE     = 'identity.write';
42
	public const SCOPE_LISTENING_READONLY = 'listening.readonly';
43
	public const SCOPE_LISTENING_WRITE    = 'listening.write';
44
	public const SCOPE_LOCALACTIVATION    = 'localactivation';
45
46
	protected string $authURL         = 'https://authorization.api.npr.org/v2/authorize';
47
	protected string $accessTokenURL  = 'https://authorization.api.npr.org/v2/token';
48
	protected ?string $revokeURL      = 'https://authorization.api.npr.org/v2/token/revoke';
49
	protected ?string $endpointMap    = NPROneEndpoints::class;
50
	protected ?string $apiDocs        = 'https://dev.npr.org/api/';
51
	protected ?string $applicationURL = 'https://dev.npr.org/console';
52
53
	/**
54
	 * @inheritDoc
55
	 */
56
	protected function getRequestTarget(string $uri):string{
57
		$parsedURL = parse_url($uri);
58
59
		if(!isset($parsedURL['path'])){
60
			throw new ProviderException('invalid path'); // @codeCoverageIgnore
61
		}
62
63
		// for some reason we were given a host name
64
		if(isset($parsedURL['host'])){
65
66
			// back out if it doesn't match
67
			if(strpos($parsedURL['host'], '.api.npr.org') === false){
68
				throw new ProviderException('given host does not match provider host'); // @codeCoverageIgnore
69
			}
70
71
			// we explicitly ignore any existing parameters here
72
			return 'https://'.$parsedURL['host'].$parsedURL['path'];
73
		}
74
75
		// $apiURL may already include a part of the path
76
		return $this->apiURL.$parsedURL['path'];
77
	}
78
79
	/**
80
	 * @inheritDoc
81
	 */
82
	public function sendRequest(RequestInterface $request):ResponseInterface{
83
84
		// get authorization only if we request the provider API
85
		if(strpos((string)$request->getUri(), '.api.npr.org') !== false){
86
			$token = $this->storage->getAccessToken($this->serviceName);
87
88
			// attempt to refresh an expired token
89
			if(
90
				$this instanceof TokenRefresh
91
				&& $this->options->tokenAutoRefresh
92
				&& ($token->isExpired() || $token->expires === $token::EOL_UNKNOWN)
93
			){
94
				$token = $this->refreshAccessToken($token); // @codeCoverageIgnore
95
			}
96
97
			$request = $this->getRequestAuthorization($request, $token);
98
		}
99
100
		return $this->http->sendRequest($request);
101
	}
102
103
}
104