105 lines
3.9 KiB
PHP
105 lines
3.9 KiB
PHP
<?php
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
namespace CloudObjects\SDK\WebAPI;
|
|
|
|
use Exception;
|
|
use ML\JsonLD\Node;
|
|
use GuzzleHttp\Client;
|
|
use Webmozart\Assert\Assert;
|
|
use CloudObjects\SDK\NodeReader;
|
|
|
|
class OAuth2AuthServer {
|
|
|
|
private $reader;
|
|
private $authServer;
|
|
private $consumer;
|
|
|
|
private $grantType;
|
|
private $clientId;
|
|
private $clientSecret;
|
|
|
|
public function __construct(Node $authServer) {
|
|
$this->reader = new NodeReader([
|
|
'prefixes' => [
|
|
'oauth2' => 'coid://oauth2.co-n.net/'
|
|
]
|
|
]);
|
|
|
|
Assert::true($this->reader->hasProperty($authServer, 'oauth2:hasTokenEndpoint'),
|
|
"Authorization Server must have a token endpoint.");
|
|
Assert::startsWith($this->reader->getFirstValueString($authServer, 'oauth2:hasTokenEndpoint'),
|
|
"https://",
|
|
"Token endpoint must be an https:// URL.");
|
|
Assert::true($this->reader->hasProperty($authServer, 'oauth2:supportsGrantType'),
|
|
"Authorization Server must support at least one grant type.");
|
|
Assert::true($this->reader->hasProperty($this->authServer, 'oauth2:usesClientIDFrom'),
|
|
"Authorization Server must define client ID property.");
|
|
Assert::true($this->reader->hasProperty($this->authServer, 'oauth2:usesClientSecretFrom'),
|
|
"Authorization Server must define client secret property.");
|
|
|
|
$this->authServer = $authServer;
|
|
}
|
|
|
|
private function assertClientCredentialPropertiesExist() : void {
|
|
|
|
}
|
|
|
|
public function configureConsumer(Node $consumer) : void {
|
|
$this->assertClientCredentialPropertiesExist();
|
|
$clientIDProperty = $this->reader->getFirstValueString($this->authServer,
|
|
'oauth2:usesClientIDFrom');
|
|
$clientSecretProperty = $this->reader->getFirstValueString($this->authServer,
|
|
'oauth2:usesClientSecretFrom');
|
|
|
|
Assert::true($this->reader->hasProperty($consumer, $clientIDProperty),
|
|
"Namespace must have Client ID");
|
|
Assert::true($this->reader->hasProperty($consumer, $clientSecretProperty),
|
|
"Namespace must have Client Secret");
|
|
|
|
if ($this->reader->hasPropertyValue($this->authServer,
|
|
'oauth2:supportsGrantType', 'oauth2:ClientCredentials')) {
|
|
// No additional conditions for "client_credentials" flow
|
|
$this->grantType = 'client_credentials';
|
|
} else {
|
|
throw new Exception("No flow/grant_type found.");
|
|
}
|
|
|
|
$this->consumer = $consumer;
|
|
$this->clientId = $this->reader->getFirstValueString($consumer, $clientIDProperty);
|
|
$this->clientSecret = $this->reader->getFirstValueString($consumer, $clientSecretProperty);
|
|
}
|
|
|
|
public function getAccessToken() {
|
|
Assert::notNull($this->consumer, "Missing consumer.");
|
|
Assert::notNull($this->grantType, "Missing grant_type.");
|
|
Assert::notNull($this->clientId, "Missing client_id.");
|
|
Assert::notNull($this->clientSecret, "Missing client_secret.");
|
|
|
|
$client = new Client;
|
|
$tokenEndpointUrl = $this->reader->getFirstValueString($this->authServer, 'oauth2:hasTokenEndpoint');
|
|
$params = [
|
|
'grant_type' => $this->grantType,
|
|
'client_id' => $this->clientId,
|
|
'client_secret' => $this->clientSecret
|
|
];
|
|
|
|
switch ($this->grantType) {
|
|
case "client_credentials":
|
|
// no additional params needed
|
|
default:
|
|
throw new Exception("No flow/grant_type found.");
|
|
}
|
|
|
|
$tokenResponse = json_decode($client->post($tokenEndpointUrl, [
|
|
'form_params' => $params
|
|
])->getBody(true));
|
|
|
|
Assert::keyExists($tokenResponse, 'access_token');
|
|
|
|
return $tokenResponse['access_token'];
|
|
}
|
|
} |