-
Notifications
You must be signed in to change notification settings - Fork 67
Expand file tree
/
Copy pathAuthRequest.php
More file actions
132 lines (116 loc) · 4.65 KB
/
AuthRequest.php
File metadata and controls
132 lines (116 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
declare(strict_types=1);
namespace Gnikyt\BasicShopifyAPI\Middleware;
use Exception;
use Gnikyt\BasicShopifyAPI\BasicShopifyAPI;
use Gnikyt\BasicShopifyAPI\Options;
use Gnikyt\BasicShopifyAPI\Traits\IsRequestType;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
/**
* Ensures we have the proper request for private and public calls.
* Also modifies issues with redirects.
*/
class AuthRequest extends AbstractMiddleware
{
use IsRequestType;
/**
* Run.
*
* @param callable $handler
*
* @throws Exception For missing API key or password for private apps.
* @throws Exception For missing access token on GraphQL calls.
*
* @return callable
*/
public function __invoke(callable $handler): callable
{
$self = $this;
return function (RequestInterface $request, array $options) use ($self, $handler) {
// Get the request URI
$uri = $request->getUri();
$isPrivate = $self->api->getOptions()->isPrivate();
$apiKey = $self->api->getOptions()->getApiKey();
$apiPassword = $self->api->getOptions()->getApiPassword();
$accessToken = $self->api->getSession()->getAccessToken();
if ($self->isAuthableRequest($uri)) {
if ($self->isRestRequest($uri)) {
// Checks for REST
if ($isPrivate && ($apiKey === null || $apiPassword === null)) {
// Key and password are required for private API calls
throw new Exception('API key and password required for private Shopify REST calls');
}
if ($isPrivate) {
// Private: Add auth for REST calls, add the basic auth header
$request = $request->withHeader(
'Authorization',
'Basic ' . base64_encode("{$apiKey}:{$apiPassword}")
);
} else {
// Public: Add the token header
$request = $request->withHeader(BasicShopifyAPI::HEADER_ACCESS_TOKEN, $accessToken);
}
} else {
// Checks for Graph
if ($isPrivate && ($apiPassword === null && $accessToken === null)) {
// Private apps need password for use as access token
throw new Exception('API password/access token required for private Shopify GraphQL calls');
} elseif (!$isPrivate && $accessToken === null) {
// Need access token for public calls
throw new Exception('Access token required for public Shopify GraphQL calls');
}
// Public/Private: Add the token header
$request = $request->withHeader(
BasicShopifyAPI::HEADER_ACCESS_TOKEN,
$apiPassword ?? $accessToken
);
}
}
// Adjust URI path to be versioned
$uri = $request->getUri();
$request = $request->withUri(
$uri->withPath(
$this->versionPath($uri)
)
);
return $handler($request, $options);
};
}
/**
* Determines if the request requires auth headers.
*/
protected function isAuthableRequest(UriInterface $uri): bool
{
return preg_match('/\/admin\/oauth\/(authorize|access_token)/', $uri->getPath()) === 0;
}
/**
* Versions the API call with the set version.
*/
protected function versionPath(UriInterface $uri): string
{
$version = $this->api->getOptions()->getVersion();
if (
$version === null
|| preg_match(Options::VERSION_PATTERN, $uri->getPath())
|| !$this->isAuthableRequest($uri)
|| !$this->isVersionableRequest($uri)
) {
// No version set, or already versioned... nothing to do
return $uri->getPath();
}
// Graph request
if ($this->isGraphRequest($uri)) {
return preg_replace('/\/admin(\/api)?\//', "/admin/api/{$version}/", $uri->getPath());
}
// REST request
return preg_replace('/\/admin(\/api)?\//', "/admin/api/{$version}/", $uri->getPath());
}
/**
* Determines if the request requires versioning.
*/
protected function isVersionableRequest(UriInterface $uri): bool
{
return preg_match('/\/admin\/(oauth\/access_scopes)/', $uri->getPath()) === 0;
}
}