Merge remote-tracking branch 'origin/support/3.0' into develop

# Conflicts:
#	composer.lock
#	datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml
#	lib/composer/autoload_files.php
#	lib/composer/autoload_real.php
#	lib/composer/autoload_static.php
#	lib/composer/installed.json
#	lib/composer/installed.php
This commit is contained in:
Eric Espie
2022-07-11 17:24:06 +02:00
48 changed files with 1065 additions and 697 deletions

View File

@@ -2,11 +2,6 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
exit(1);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit7f81b4a2a468a061c306af5e447a9a9f::getLoader();

View File

@@ -149,7 +149,7 @@ class ClassLoader
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
* @psalm-var array<string, string>
*/
public function getClassMap()
{

View File

@@ -21,26 +21,11 @@ use Composer\Semver\VersionParser;
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
@@ -243,7 +228,7 @@ class InstalledVersions
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
*/
public static function getRootPackage()
{
@@ -257,7 +242,7 @@ class InstalledVersions
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
*/
public static function getRawData()
{
@@ -280,7 +265,7 @@ class InstalledVersions
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
public static function getAllRawData()
{
@@ -303,7 +288,7 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
*/
public static function reload($data)
{
@@ -313,7 +298,7 @@ class InstalledVersions
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
private static function getInstalled()
{

View File

@@ -2,7 +2,7 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// include_paths.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -11,10 +11,10 @@ if (!(PHP_VERSION_ID >= 70205)) {
$missingExtensions = array();
extension_loaded('dom') || $missingExtensions[] = 'dom';
extension_loaded('gd') || $missingExtensions[] = 'gd';
extension_loaded('iconv') || $missingExtensions[] = 'iconv';
extension_loaded('json') || $missingExtensions[] = 'json';
extension_loaded('libxml') || $missingExtensions[] = 'libxml';
extension_loaded('mysqli') || $missingExtensions[] = 'mysqli';
extension_loaded('openssl') || $missingExtensions[] = 'openssl';
extension_loaded('soap') || $missingExtensions[] = 'soap';
extension_loaded('tokenizer') || $missingExtensions[] = 'tokenizer';
extension_loaded('xml') || $missingExtensions[] = 'xml';

View File

@@ -3,3 +3,7 @@
composer.phar
composer.lock
.DS_Store
# IDE
/.idea
/.vscode

View File

@@ -46,7 +46,7 @@ $provider = new TheNetworg\OAuth2\Client\Provider\Azure([
'clientSecret' => '{azure-client-secret}',
'redirectUri' => 'https://example.com/callback-url',
//Optional
'scopes' => 'openid',
'scopes' => ['openid'],
//Optional
'defaultEndPointVersion' => '2.0'
]);

View File

@@ -22,9 +22,11 @@
"sso"
],
"require": {
"php": "^5.6|^7.0|^8.0",
"ext-json": "*",
"ext-openssl": "*",
"php": "^7.1|^8.0",
"league/oauth2-client": "~2.0",
"firebase/php-jwt": "~3.0||~4.0||~5.0"
"firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0"
},
"autoload": {
"psr-4": {

View File

@@ -3,9 +3,13 @@
namespace TheNetworg\OAuth2\Client\Provider;
use Firebase\JWT\JWT;
use Firebase\JWT\JWK;
use Firebase\JWT\Key;
use League\OAuth2\Client\Grant\AbstractGrant;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
use League\OAuth2\Client\Token\AccessTokenInterface;
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use Psr\Http\Message\ResponseInterface;
use TheNetworg\OAuth2\Client\Grant\JwtBearer;
@@ -66,7 +70,8 @@ class Azure extends AbstractProvider
}
if (!array_key_exists($version, $this->openIdConfiguration[$tenant])) {
$versionInfix = $this->getVersionUriInfix($version);
$openIdConfigurationUri = 'https://login.microsoftonline.com/' . $tenant . $versionInfix . '/.well-known/openid-configuration';
$openIdConfigurationUri = $this->urlLogin . $tenant . $versionInfix . '/.well-known/openid-configuration?appid=' . $this->clientId;
$factory = $this->getRequestFactory();
$request = $factory->getRequestWithOptions(
'get',
@@ -80,19 +85,28 @@ class Azure extends AbstractProvider
return $this->openIdConfiguration[$tenant][$version];
}
public function getBaseAuthorizationUrl()
/**
* @inheritdoc
*/
public function getBaseAuthorizationUrl(): string
{
$openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
return $openIdConfiguration['authorization_endpoint'];
}
public function getBaseAccessTokenUrl(array $params)
/**
* @inheritdoc
*/
public function getBaseAccessTokenUrl(array $params): string
{
$openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
return $openIdConfiguration['token_endpoint'];
}
public function getAccessToken($grant, array $options = [])
/**
* @inheritdoc
*/
public function getAccessToken($grant, array $options = []): AccessTokenInterface
{
if ($this->defaultEndPointVersion != self::ENDPOINT_VERSION_2_0) {
// Version 2.0 does not support the resources parameter
@@ -106,14 +120,21 @@ class Azure extends AbstractProvider
return parent::getAccessToken($grant, $options);
}
public function getResourceOwner(\League\OAuth2\Client\Token\AccessToken $token)
/**
* @inheritdoc
*/
public function getResourceOwner(\League\OAuth2\Client\Token\AccessToken $token): ResourceOwnerInterface
{
$data = $token->getIdTokenClaims();
return $this->createResourceOwner($data, $token);
}
public function getResourceOwnerDetailsUrl(\League\OAuth2\Client\Token\AccessToken $token)
/**
* @inheritdoc
*/
public function getResourceOwnerDetailsUrl(\League\OAuth2\Client\Token\AccessToken $token): string
{
return ''; // shouldn't that return such a URL?
}
public function getObjects($tenant, $ref, &$accessToken, $headers = [])
@@ -164,11 +185,11 @@ class Azure extends AbstractProvider
return 'https://' . $openIdConfiguration['msgraph_host'];
}
public function get($ref, &$accessToken, $headers = [])
public function get($ref, &$accessToken, $headers = [], $doNotWrap = false)
{
$response = $this->request('get', $ref, $accessToken, ['headers' => $headers]);
return $this->wrapResponse($response);
return $doNotWrap ? $response : $this->wrapResponse($response);
}
public function post($ref, $body, &$accessToken, $headers = [])
@@ -352,8 +373,24 @@ class Azure extends AbstractProvider
$publicKey = $pkey_array ['key'];
$keys[$keyinfo['kid']] = $publicKey;
$keys[$keyinfo['kid']] = new Key($publicKey, 'RS256');
}
} else if (isset($keyinfo['n']) && isset($keyinfo['e'])) {
$pkey_object = JWK::parseKey($keyinfo);
if ($pkey_object === false) {
throw new \RuntimeException('An attempt to read a public key from a ' . $keyinfo['n'] . ' certificate failed.');
}
$pkey_array = openssl_pkey_get_details($pkey_object);
if ($pkey_array === false) {
throw new \RuntimeException('An attempt to get a public key as an array from a ' . $keyinfo['n'] . ' certificate failed.');
}
$publicKey = $pkey_array ['key'];
$keys[$keyinfo['kid']] = new Key($publicKey, 'RS256');;
}
}
@@ -382,7 +419,10 @@ class Azure extends AbstractProvider
return $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
}
protected function checkResponse(ResponseInterface $response, $data)
/**
* @inheritdoc
*/
protected function checkResponse(ResponseInterface $response, $data): void
{
if (isset($data['odata.error']) || isset($data['error'])) {
if (isset($data['odata.error']['message']['value'])) {
@@ -402,27 +442,39 @@ class Azure extends AbstractProvider
throw new IdentityProviderException(
$message,
$response->getStatusCode(),
$response
$response->getBody()
);
}
}
protected function getDefaultScopes()
/**
* @inheritdoc
*/
protected function getDefaultScopes(): array
{
return $this->scope;
}
protected function getScopeSeparator()
/**
* @inheritdoc
*/
protected function getScopeSeparator(): string
{
return $this->scopeSeparator;
}
protected function createAccessToken(array $response, AbstractGrant $grant)
/**
* @inheritdoc
*/
protected function createAccessToken(array $response, AbstractGrant $grant): AccessToken
{
return new AccessToken($response, $this);
}
protected function createResourceOwner(array $response, \League\OAuth2\Client\Token\AccessToken $token)
/**
* @inheritdoc
*/
protected function createResourceOwner(array $response, \League\OAuth2\Client\Token\AccessToken $token): AzureResourceOwner
{
return new AzureResourceOwner($response);
}

View File

@@ -19,6 +19,8 @@ class AccessToken extends \League\OAuth2\Client\Token\AccessToken
if (!empty($options['id_token'])) {
$this->idToken = $options['id_token'];
unset($this->values['id_token']);
$keys = $provider->getJwtVerificationKeys();
$idTokenClaims = null;
try {
@@ -45,8 +47,27 @@ class AccessToken extends \League\OAuth2\Client\Token\AccessToken
}
}
public function getIdToken()
{
return $this->idToken;
}
public function getIdTokenClaims()
{
return $this->idTokenClaims;
}
/**
* @inheritdoc
*/
public function jsonSerialize()
{
$parameters = parent::jsonSerialize();
if ($this->idToken) {
$parameters['id_token'] = $this->idToken;
}
return $parameters;
}
}