1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-24 07:03:06 +02:00

HybridAuth and PHPMailer updated.

This commit is contained in:
Cameron
2020-12-20 17:50:56 -08:00
parent 153cf33aa7
commit aee1d26df8
160 changed files with 3159 additions and 3574 deletions

211
composer.lock generated
View File

@@ -6,6 +6,60 @@
],
"content-hash": "69374030afa61b1e84c6c973551b0e5f",
"packages": [
{
"name": "firebase/php-jwt",
"version": "v5.2.0",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
"reference": "feb0e820b8436873675fd3aca04f3728eb2185cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/feb0e820b8436873675fd3aca04f3728eb2185cb",
"reference": "feb0e820b8436873675fd3aca04f3728eb2185cb",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": ">=4.8 <=9"
},
"type": "library",
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"jwt",
"php"
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
"source": "https://github.com/firebase/php-jwt/tree/master"
},
"time": "2020-03-25T18:49:23+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.7.0",
@@ -83,20 +137,22 @@
},
{
"name": "hybridauth/hybridauth",
"version": "3.3.0",
"version": "3.6.0",
"source": {
"type": "git",
"url": "https://github.com/hybridauth/hybridauth.git",
"reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04"
"reference": "222ab4e6ee6ffd81caa77283142f3aa97afa5863"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/51cb2ad2f04d175d298b51e919868dec1d4d8b04",
"reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04",
"url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/222ab4e6ee6ffd81caa77283142f3aa97afa5863",
"reference": "222ab4e6ee6ffd81caa77283142f3aa97afa5863",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
"firebase/php-jwt": "*",
"php": ">=5.4.0",
"phpseclib/phpseclib": "~2.0"
},
"require-dev": {
"ext-curl": "*",
@@ -124,6 +180,7 @@
"Authentication",
"OpenId",
"api",
"apple",
"authorization",
"facebook",
"google",
@@ -131,7 +188,12 @@
"social",
"twitter"
],
"time": "2020-04-16T08:04:26+00:00"
"support": {
"gitter": "https://gitter.im/hybridauth/hybridauth",
"issues": "https://github.com/hybridauth/hybridauth/issues",
"source": "https://github.com/hybridauth/hybridauth/tree/3.6.0"
},
"time": "2020-10-21T16:32:08+00:00"
},
{
"name": "ifsnop/mysqldump-php",
@@ -186,6 +248,10 @@
"php5",
"sql"
],
"support": {
"issues": "https://github.com/ifsnop/mysqldump-php/issues",
"source": "https://github.com/ifsnop/mysqldump-php/tree/master"
},
"time": "2020-04-03T14:40:40+00:00"
},
{
@@ -381,27 +447,31 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.1.6",
"version": "v6.2.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3"
"reference": "e38888a75c070304ca5514197d4847a59a5c853f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e38888a75c070304ca5514197d4847a59a5c853f",
"reference": "e38888a75c070304ca5514197d4847a59a5c853f",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-filter": "*",
"ext-hash": "*",
"php": ">=5.5.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"doctrine/annotations": "^1.2",
"friendsofphp/php-cs-fixer": "^2.2",
"phpunit/phpunit": "^4.8 || ^5.7"
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.5.6",
"yoast/phpunit-polyfills": "^0.2.0"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
@@ -439,13 +509,126 @@
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.2.0"
},
"funding": [
{
"url": "https://github.com/synchro",
"url": "https://github.com/Synchro",
"type": "github"
}
],
"time": "2020-05-27T12:24:03+00:00"
"time": "2020-11-25T15:24:57+00:00"
},
{
"name": "phpseclib/phpseclib",
"version": "2.0.30",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phing/phing": "~2.7",
"phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
"squizlabs/php_codesniffer": "~2.0"
},
"suggest": {
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
},
"type": "library",
"autoload": {
"files": [
"phpseclib/bootstrap.php"
],
"psr-4": {
"phpseclib\\": "phpseclib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jim Wigginton",
"email": "terrafrost@php.net",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "pm@datasphere.ch",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "bantu@phpbb.com",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "petrich@tronic-media.com",
"role": "Developer"
},
{
"name": "Graham Campbell",
"email": "graham@alt-three.com",
"role": "Developer"
}
],
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"homepage": "http://phpseclib.sourceforge.net",
"keywords": [
"BigInteger",
"aes",
"asn.1",
"asn1",
"blowfish",
"crypto",
"cryptography",
"encryption",
"rsa",
"security",
"sftp",
"signature",
"signing",
"ssh",
"twofish",
"x.509",
"x509"
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.30"
},
"funding": [
{
"url": "https://github.com/terrafrost",
"type": "github"
},
{
"url": "https://www.patreon.com/phpseclib",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
"type": "tidelift"
}
],
"time": "2020-12-17T05:42:04+00:00"
},
{
"name": "psr/http-message",

View File

@@ -29,7 +29,7 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '1f38b3b3dd231c274f4df1a529883655108b611e',
'reference' => '153cf33aa76c3378a8332616fe68fd796d00343b',
'name' => 'e107inc/e107',
),
'versions' =>
@@ -41,7 +41,16 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '1f38b3b3dd231c274f4df1a529883655108b611e',
'reference' => '153cf33aa76c3378a8332616fe68fd796d00343b',
),
'firebase/php-jwt' =>
array (
'pretty_version' => 'v5.2.0',
'version' => '5.2.0.0',
'aliases' =>
array (
),
'reference' => 'feb0e820b8436873675fd3aca04f3728eb2185cb',
),
'guzzlehttp/psr7' =>
array (
@@ -54,12 +63,12 @@ private static $installed = array (
),
'hybridauth/hybridauth' =>
array (
'pretty_version' => '3.3.0',
'version' => '3.3.0.0',
'pretty_version' => '3.6.0',
'version' => '3.6.0.0',
'aliases' =>
array (
),
'reference' => '51cb2ad2f04d175d298b51e919868dec1d4d8b04',
'reference' => '222ab4e6ee6ffd81caa77283142f3aa97afa5863',
),
'ifsnop/mysqldump-php' =>
array (
@@ -99,12 +108,21 @@ private static $installed = array (
),
'phpmailer/phpmailer' =>
array (
'pretty_version' => 'v6.1.6',
'version' => '6.1.6.0',
'pretty_version' => 'v6.2.0',
'version' => '6.2.0.0',
'aliases' =>
array (
),
'reference' => 'c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3',
'reference' => 'e38888a75c070304ca5514197d4847a59a5c853f',
),
'phpseclib/phpseclib' =>
array (
'pretty_version' => '2.0.30',
'version' => '2.0.30.0',
'aliases' =>
array (
),
'reference' => '136b9ca7eebef78be14abf90d65c5e57b6bc5d36',
),
'psr/http-message' =>
array (

View File

@@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname(dirname($vendorDir));
return array(
'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
'MatthiasMullie\\PathConverter\\' => array($vendorDir . '/matthiasmullie/path-converter/src'),
@@ -14,4 +15,5 @@ return array(
'Ifsnop\\' => array($vendorDir . '/ifsnop/mysqldump-php/src/Ifsnop'),
'Hybridauth\\' => array($vendorDir . '/hybridauth/hybridauth/src'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
);

View File

@@ -9,9 +9,14 @@ class ComposerStaticInit4ce406ae486ac58c9aa71537459207ae
public static $files = array (
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
);
public static $prefixLengthsPsr4 = array (
'p' =>
array (
'phpseclib\\' => 10,
),
'P' =>
array (
'Psr\\Http\\Message\\' => 17,
@@ -35,9 +40,17 @@ class ComposerStaticInit4ce406ae486ac58c9aa71537459207ae
array (
'GuzzleHttp\\Psr7\\' => 16,
),
'F' =>
array (
'Firebase\\JWT\\' => 13,
),
);
public static $prefixDirsPsr4 = array (
'phpseclib\\' =>
array (
0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib',
),
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-message/src',
@@ -70,6 +83,10 @@ class ComposerStaticInit4ce406ae486ac58c9aa71537459207ae
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
),
'Firebase\\JWT\\' =>
array (
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
),
);
public static $classMap = array (

View File

@@ -1,5 +1,62 @@
{
"packages": [
{
"name": "firebase/php-jwt",
"version": "v5.2.0",
"version_normalized": "5.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
"reference": "feb0e820b8436873675fd3aca04f3728eb2185cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/feb0e820b8436873675fd3aca04f3728eb2185cb",
"reference": "feb0e820b8436873675fd3aca04f3728eb2185cb",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": ">=4.8 <=9"
},
"time": "2020-03-25T18:49:23+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"jwt",
"php"
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
"source": "https://github.com/firebase/php-jwt/tree/master"
},
"install-path": "../firebase/php-jwt"
},
{
"name": "guzzlehttp/psr7",
"version": "1.7.0",
@@ -80,27 +137,29 @@
},
{
"name": "hybridauth/hybridauth",
"version": "3.3.0",
"version_normalized": "3.3.0.0",
"version": "3.6.0",
"version_normalized": "3.6.0.0",
"source": {
"type": "git",
"url": "https://github.com/hybridauth/hybridauth.git",
"reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04"
"reference": "222ab4e6ee6ffd81caa77283142f3aa97afa5863"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/51cb2ad2f04d175d298b51e919868dec1d4d8b04",
"reference": "51cb2ad2f04d175d298b51e919868dec1d4d8b04",
"url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/222ab4e6ee6ffd81caa77283142f3aa97afa5863",
"reference": "222ab4e6ee6ffd81caa77283142f3aa97afa5863",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
"firebase/php-jwt": "*",
"php": ">=5.4.0",
"phpseclib/phpseclib": "~2.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.8.35 || ^6.5 || ^8"
},
"time": "2020-04-16T08:04:26+00:00",
"time": "2020-10-21T16:32:08+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -124,6 +183,7 @@
"Authentication",
"OpenId",
"api",
"apple",
"authorization",
"facebook",
"google",
@@ -131,6 +191,11 @@
"social",
"twitter"
],
"support": {
"gitter": "https://gitter.im/hybridauth/hybridauth",
"issues": "https://github.com/hybridauth/hybridauth/issues",
"source": "https://github.com/hybridauth/hybridauth/tree/3.6.0"
},
"install-path": "../hybridauth/hybridauth"
},
{
@@ -393,28 +458,32 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.1.6",
"version_normalized": "6.1.6.0",
"version": "v6.2.0",
"version_normalized": "6.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3"
"reference": "e38888a75c070304ca5514197d4847a59a5c853f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e38888a75c070304ca5514197d4847a59a5c853f",
"reference": "e38888a75c070304ca5514197d4847a59a5c853f",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-filter": "*",
"ext-hash": "*",
"php": ">=5.5.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"doctrine/annotations": "^1.2",
"friendsofphp/php-cs-fixer": "^2.2",
"phpunit/phpunit": "^4.8 || ^5.7"
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.5.6",
"yoast/phpunit-polyfills": "^0.2.0"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
@@ -424,7 +493,7 @@
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"time": "2020-05-27T12:24:03+00:00",
"time": "2020-11-25T15:24:57+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -454,14 +523,130 @@
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.2.0"
},
"funding": [
{
"url": "https://github.com/synchro",
"url": "https://github.com/Synchro",
"type": "github"
}
],
"install-path": "../phpmailer/phpmailer"
},
{
"name": "phpseclib/phpseclib",
"version": "2.0.30",
"version_normalized": "2.0.30.0",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phing/phing": "~2.7",
"phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
"squizlabs/php_codesniffer": "~2.0"
},
"suggest": {
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
},
"time": "2020-12-17T05:42:04+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"phpseclib/bootstrap.php"
],
"psr-4": {
"phpseclib\\": "phpseclib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jim Wigginton",
"email": "terrafrost@php.net",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "pm@datasphere.ch",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "bantu@phpbb.com",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "petrich@tronic-media.com",
"role": "Developer"
},
{
"name": "Graham Campbell",
"email": "graham@alt-three.com",
"role": "Developer"
}
],
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"homepage": "http://phpseclib.sourceforge.net",
"keywords": [
"BigInteger",
"aes",
"asn.1",
"asn1",
"blowfish",
"crypto",
"cryptography",
"encryption",
"rsa",
"security",
"sftp",
"signature",
"signing",
"ssh",
"twofish",
"x.509",
"x509"
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.30"
},
"funding": [
{
"url": "https://github.com/terrafrost",
"type": "github"
},
{
"url": "https://www.patreon.com/phpseclib",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
"type": "tidelift"
}
],
"install-path": "../phpseclib/phpseclib"
},
{
"name": "psr/http-message",
"version": "1.0.1",

View File

@@ -6,7 +6,7 @@
'aliases' =>
array (
),
'reference' => '1f38b3b3dd231c274f4df1a529883655108b611e',
'reference' => '153cf33aa76c3378a8332616fe68fd796d00343b',
'name' => 'e107inc/e107',
),
'versions' =>
@@ -18,7 +18,16 @@
'aliases' =>
array (
),
'reference' => '1f38b3b3dd231c274f4df1a529883655108b611e',
'reference' => '153cf33aa76c3378a8332616fe68fd796d00343b',
),
'firebase/php-jwt' =>
array (
'pretty_version' => 'v5.2.0',
'version' => '5.2.0.0',
'aliases' =>
array (
),
'reference' => 'feb0e820b8436873675fd3aca04f3728eb2185cb',
),
'guzzlehttp/psr7' =>
array (
@@ -31,12 +40,12 @@
),
'hybridauth/hybridauth' =>
array (
'pretty_version' => '3.3.0',
'version' => '3.3.0.0',
'pretty_version' => '3.6.0',
'version' => '3.6.0.0',
'aliases' =>
array (
),
'reference' => '51cb2ad2f04d175d298b51e919868dec1d4d8b04',
'reference' => '222ab4e6ee6ffd81caa77283142f3aa97afa5863',
),
'ifsnop/mysqldump-php' =>
array (
@@ -76,12 +85,21 @@
),
'phpmailer/phpmailer' =>
array (
'pretty_version' => 'v6.1.6',
'version' => '6.1.6.0',
'pretty_version' => 'v6.2.0',
'version' => '6.2.0.0',
'aliases' =>
array (
),
'reference' => 'c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3',
'reference' => 'e38888a75c070304ca5514197d4847a59a5c853f',
),
'phpseclib/phpseclib' =>
array (
'pretty_version' => '2.0.30',
'version' => '2.0.30.0',
'aliases' =>
array (
),
'reference' => '136b9ca7eebef78be14abf90d65c5e57b6bc5d36',
),
'psr/http-message' =>
array (

View File

@@ -1,7 +1,7 @@
Contributing
============
HybridAuth is a community driven project, and it needs your help to keep the project going.
Hybridauth is a community driven project, and it needs your help to keep the project going.
### Report Problems
@@ -30,7 +30,7 @@ Before contributing code, please consider these guide lines:
**Coding Style**
HybridAuth follows [PSR-1](http://www.php-fig.org/psr/psr-1/) and [PSR-2](http://www.php-fig.org/psr/psr-2/).
Hybridauth follows [PSR-1](http://www.php-fig.org/psr/psr-1/) and [PSR-2](http://www.php-fig.org/psr/psr-2/).
Please prevent your IDE for reformatting huge chunks of code/files as it make it nearly impossible to see what changes were
actually made to a file on your Pull Request.
@@ -40,7 +40,7 @@ actually made to a file on your Pull Request.
Additional providers, minor enhancements, bugs and typos fixes are most welcome. Large and "breaking" changes should be
discussed ahead of time. **Please ask first**.
HybridAuth 3 is compatible with **PHP 5.4** and therefore all code supplied must stick to this requirement.
Hybridauth 3 is compatible with **PHP 5.4** and therefore all code supplied must stick to this requirement.
**License**

View File

@@ -2,7 +2,7 @@ Except where otherwise noted in the source code (i.e., LightOpenID and OAuth
Library, which are covered by similar licences but with different Copyright
notices) all the files are:
Copyright (C) 2009-2019, HybridAuth authors. All Rights Reserved.
Copyright (C) 2009-2019, Hybridauth authors. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -26,7 +26,7 @@ THE SOFTWARE.
-----------------------
HybridAuth includes a copy of LightOpenID, licensed as follows:
Hybridauth includes a copy of LightOpenID, licensed as follows:
Copyright (c) 2013-2016 Mewp (mewp151 at gmail dot com)
@@ -52,7 +52,7 @@ THE SOFTWARE.
-----------------------
HybridAuth includes a modified copy of OAuth PHP Library, licensed as follows:
Hybridauth includes a modified copy of OAuth PHP Library, licensed as follows:
Copyright (c) 2007-2011 Andy Smith

View File

@@ -1,4 +1,4 @@
## [Hybridauth](https://hybridauth.github.io/) 3.3
## [Hybridauth](https://hybridauth.github.io/) 3.5
[![Build Status](https://travis-ci.org/hybridauth/hybridauth.svg?branch=master)](https://travis-ci.org/hybridauth/hybridauth) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/hybridauth/hybridauth/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/hybridauth/hybridauth/?branch=master) [![Latest Stable Version](https://poser.pugx.org/hybridauth/hybridauth/v/stable.png)](https://packagist.org/packages/hybridauth/hybridauth) [![Join the chat at https://gitter.im/hybridauth/hybridauth](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hybridauth/hybridauth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -13,7 +13,10 @@ Hybridauth provides a number of basic [examples](https://github.com/hybridauth/h
```php
$config = [
'callback' => 'https://example.com/path/to/script.php',
'keys' => [ 'key' => 'your-twitter-consumer-key', 'secret' => 'your-twitter-consumer-secret' ]
'keys' => [
'key' => 'your-twitter-consumer-key',
'secret' => 'your-twitter-consumer-secret',
],
];
try {
@@ -46,6 +49,7 @@ To install Hybridauth we recommend [Composer](https://getcomposer.org/), the now
|---------|-------------|-------------------------|-------------------------|-------------|
| 2.x | Maintenance | [v2][hybridauth-2-repo] | [v2][hybridauth-2-docs] | >= 5.3 |
| 3.x | Development | [v3][hybridauth-3-repo] | [v3][hybridauth-3-docs] | >= 5.4 |
| 4.x | Future | -- | -- | >= 7.3 |
[hybridauth-2-repo]: https://github.com/hybridauth/hybridauth/tree/v2
[hybridauth-3-repo]: https://github.com/hybridauth/hybridauth/

View File

@@ -1,12 +0,0 @@
Hybridauth 3 Examples
======================
File | Description
-------------- | ------------------------------------------------------------------------------
example_01.php | This simple example illustrate how to authenticate users with GitHub. If you're new to Hybridauth, this file is the one you'll likely want to check.
example_02.php | Details how to use users in a similar fashion to Hybridauth 2. Note that while Hybridauth 3 provides a similar interface to Hybridauth 2, both versions are not fully compatible with each other.
example_03.php | An example on how use Access Tokens to access providers APIs, and how to setup custom API endpoints.
example_04.php | A simple example that shows how to connect users to providers using OpenID.
example_05.php | A simple example that shows how to use Guzzle as a Http Client for Hybridauth instead of PHP Curl extension.
example_06/ | A simple example that shows how to organize multiple providers.
example_07/ | A simple example that shows how to organize multiple providers, using a pop-up.

View File

@@ -1,190 +0,0 @@
<?php
/*!
* This simple example illustrate how to authenticate users with GitHub.
*
* Most other providers work pretty much the same.
*/
/**
* Step 0: Start PHP session
*
* Normally this step is not required as HybridAuth will attempt to start the session for you, however
* in some cases it might be better to call session_start() at top of script to avoid cookie-based sessions
* issues.
*
* See: http://php.net/manual/en/function.session-start.php#refsect1-function.session-start-notes
* http://stackoverflow.com/a/8028987
*/
session_start();
/**
* Step 1: Require the Hybridauth Library
*
* Should be as simple as including Composer's autoloader.
*/
include 'vendor/autoload.php';
/**
* Step 2: Configuring Your Application
*
* If you're already familiar with the process, you can skip the explanation below.
*
* To get started with GitHub authentication, you need to create a new GitHub application.
*
* First, navigate to https://github.com/settings/developers then click the Register
* new application button at the top right of that page and fill in any required fields
* such as the application name, description and website.
*
* Set the Authorization callback URL to https://path/to/hybridauth/examples/example_01.php.
* Understandably, you need to replace 'path/to/hybridauth' with the real path to this script.
*
* Note that Hybridauth provides an utility function that can generate the current page url for you
* and can be used for the callback. Example: 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl()
*
* After configuring your GitHub application, simple replace 'your-app-id' and 'your-app-secret'
* with your application credentials (Client ID and Client Secret).
*
* Providers who uses OAuth 2.0 protocol (i.g., GitHub, Facebook, Google, etc.) may need
* an Authorization scope as additional parameter. Authorization scopes are strings that
* enable access to particular resources, such as user data.
*
* https://developer.github.com/v3/oauth/
* https://developer.github.com/v3/oauth/#scopes
*/
$config = [
'callback' => 'https://path/to/hybridauth/examples/example_01.php', // or Hybridauth\HttpClient\Util::getCurrentUrl()
'keys' => [ 'id' => 'your-app-id', 'secret' => 'your-app-secret' ], // Your Github application credentials
/* optional : set scope
'scope' => 'user:email', */
/* optional : set debug mode
'debug_mode' => true,
// Path to file writeable by the web server. Required if 'debug_mode' is not false
'debug_file' => __FILE__ . '.log', */
/* optional : customize Curl settings
// for more information on curl, refer to: http://www.php.net/manual/fr/function.curl-setopt.php
'curl_options' => [
// setting custom certificates
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CAINFO => '/path/to/your/certificate.crt',
// set a valid proxy ip address
CURLOPT_PROXY => '*.*.*.*:*',
// set a custom user agent
CURLOPT_USERAGENT => ''
] */
];
/**
* Step 3: Instantiate Github Adapter
*
* This example instantiates a GitHub adapter using the array $config we just built.
*/
$github = new Hybridauth\Provider\GitHub($config);
/**
* Step 4: Authenticating Users
*
* When invoked, `authenticate()` will redirect users to GitHub login page where they
* will be asked to grant access to your application. If they do, GitHub will redirect
* the users back to Authorization callback URL (i.e., this script).
*
* Note that GitHub and few other providers will ask their users for authorisation
* only once.
*/
$github->authenticate();
/**
* Step 5: Retrieve Users Profiles
*
* Calling getUserProfile returns an instance of class Hybridauth\User\Profile which contain the
* connected user's profile in simple and standardized structure across all the social APIs supported
* by HybridAuth.
*/
$userProfile = $github->getUserProfile();
echo 'Hi '.$userProfile->displayName;
/**
* Bonus: Access GitHub API
*
* Now that the user is authenticated with Gihub, and depending on the authorization given to your
* application, you should be able to query the said API on behalf of the user.
*
* As an example we list the authenticated user's public gists.
*/
$apiResponse = $github->apiRequest('gists');
/**
* Step 6: Disconnect the adapter
*
* This will erase the current user authentication data from session, and any further
* attempt to communicate with Github API will result on an authorisation exception.
*/
$github->disconnect();
/**
* Final note: Catching Exceptions
*
* Hybridauth use exceptions extensively and it's important that these exceptions
* be properly caught/handled in your code.
*
* Below is a basic example of how to catch exceptions.
*
* Note that on the previous step we disconnected from the API; meaning Hybridauth
* has erased the oauth access token used to sign http requests from the current
* session, thus, any new request we now make will now throw an exception.
*
* It's important that you don't show Hybridauth exception's messages to the end user as
* they may include sensitive data, and that you use your own error messages instead.
*/
try {
$github->getUserProfile();
}
/**
* Catch Curl Errors
*
* This kind of error may happen in case of:
* - Internet or Network issues.
* - Your server configuration is not setup correctly.
*
* The full list of curl errors that may happen can be found at http://curl.haxx.se/libcurl/c/libcurl-errors.html
*/
catch (Hybridauth\Exception\HttpClientFailureException $e) {
echo 'Curl text error message : '.$github->getHttpClient()->getResponseClientError();
}
/**
* Catch API Requests Errors
*
* This usually happens when requesting a:
* - Wrong URI or a mal-formatted http request.
* - Protected resource without providing a valid access token.
*/
catch (Hybridauth\Exception\HttpRequestFailedException $e) {
echo 'Raw API Response: '.$github->getHttpClient()->getResponseBody();
}
/**
* Base PHP's exception that catches everything [else]
*/
catch (\Exception $e) {
echo 'Oops! We ran into an unknown issue: '.$e->getMessage();
}

View File

@@ -1,76 +0,0 @@
<?php
/*!
* Details how to use users in a similar fashion to Hybridauth 2. Note that while Hybridauth 3 provides
* a similar interface to Hybridauth 2, both versions are not fully compatible with each other.
*/
include 'vendor/autoload.php';
use Hybridauth\Hybridauth;
use Hybridauth\HttpClient;
$config = [
'callback' => HttpClient\Util::getCurrentUrl(),
'providers' => [
'GitHub' => [
'enabled' => true,
'keys' => [ 'id' => '', 'secret' => '' ],
],
'Google' => [
'enabled' => true,
'keys' => [ 'id' => '', 'secret' => '' ],
],
'Facebook' => [
'enabled' => true,
'keys' => [ 'id' => '', 'secret' => '' ],
],
'Twitter' => [
'enabled' => true,
'keys' => [ 'key' => '', 'secret' => '' ],
]
],
/* optional : set debug mode
'debug_mode' => true,
// Path to file writeable by the web server. Required if 'debug_mode' is not false
'debug_file' => __FILE__ . '.log', */
/* optional : customize Curl settings
// for more information on curl, refer to: http://www.php.net/manual/fr/function.curl-setopt.php
'curl_options' => [
// setting custom certificates
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CAINFO => '/path/to/your/certificate.crt',
// set a valid proxy ip address
CURLOPT_PROXY => '*.*.*.*:*',
// set a custom user agent
CURLOPT_USERAGENT => ''
] */
];
try {
$hybridauth = new Hybridauth( $config );
$adapter = $hybridauth->authenticate( 'GitHub' );
// $adapter = $hybridauth->authenticate( 'Google' );
// $adapter = $hybridauth->authenticate( 'Facebook' );
// $adapter = $hybridauth->authenticate( 'Twitter' );
$tokens = $adapter->getAccessToken();
$userProfile = $adapter->getUserProfile();
// print_r( $tokens );
// print_r( $userProfile );
$adapter->disconnect();
}
catch (\Exception $e) {
echo $e->getMessage();
}

View File

@@ -1,33 +0,0 @@
<?php
/*!
* An example on how use Access Tokens to access providers APIs, and how to setup custom API endpoints.
*/
include 'vendor/autoload.php';
$config = [
'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
'keys' => [ 'id' => 'your-facebook-app-id', 'secret' => 'your-facebook-app-secret' ],
'endpoints' => [
'api_base_url' => 'https://graph.facebook.com/v2.8/',
'authorize_url' => 'https://www.facebook.com/dialog/oauth',
'access_token_url' => 'https://graph.facebook.com/oauth/access_token',
]
];
try {
$adapter = new Hybridauth\Provider\Facebook( $config );
$adapter->setAccessToken(['access_token' => 'user-facebook-access-token']);
$userProfile = $adapter->getUserProfile();
// print_r( $userProfile );
$adapter->disconnect();
}
catch( Exception $e ){
echo $e->getMessage();
}

View File

@@ -1,32 +0,0 @@
<?php
/*!
* A simple example that shows how to connect users to providers using OpenID.
*/
include 'vendor/autoload.php';
$config = [
'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
'openid_identifier' => 'https://open.login.yahooapis.com/openid20/www.yahoo.com/xrds',
// 'openid_identifier' => 'https://openid.stackexchange.com/',
// 'openid_identifier' => 'http://steamcommunity.com/openid',
// etc.
];
try {
$adapter = new Hybridauth\Provider\OpenID( $config );
$adapter->authenticate();
$tokens = $adapter->getAccessToken();
$userProfile = $adapter->getUserProfile();
// print_r( $tokens );
// print_r( $userProfile );
$adapter->disconnect();
}
catch( Exception $e ){
echo $e->getMessage();
}

View File

@@ -1,33 +0,0 @@
<?php
/*!
* A simple example that shows how to use Guzzle as a Http Client for Hybridauth instead of PHP Curl extention.
*/
include 'vendor/autoload.php';
$config = [
'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
'keys' => [ 'id' => '', 'secret' => '' ],
];
$guzzle = new Hybridauth\HttpClient\Guzzle(null, [
// 'verify' => true, # Set to false to disable SSL certificate verification
]);
try {
$adapter = new Hybridauth\Provider\Github($config, $guzzle);
$adapter->authenticate();
$tokens = $adapter->getAccessToken();
$userProfile = $adapter->getUserProfile();
// print_r( $tokens );
// print_r( $userProfile );
$adapter->disconnect();
}
catch( Exception $e ){
echo $e->getMessage();
}

View File

@@ -1,59 +0,0 @@
<?php
/**
* A simple example that shows how to use multiple providers.
*/
include 'vendor/autoload.php';
include 'config.php';
use Hybridauth\Exception\Exception;
use Hybridauth\Hybridauth;
use Hybridauth\HttpClient;
use Hybridauth\Storage\Session;
try {
/**
* Feed configuration array to Hybridauth.
*/
$hybridauth = new Hybridauth($config);
/**
* Initialize session storage.
*/
$storage = new Session();
/**
* Hold information about provider when user clicks on Sign In.
*/
if (isset($_GET['provider'])) {
$storage->set('provider', $_GET['provider']);
}
/**
* When provider exists in the storage, try to authenticate user and clear storage.
*
* When invoked, `authenticate()` will redirect users to provider login page where they
* will be asked to grant access to your application. If they do, provider will redirect
* the users back to Authorization callback URL (i.e., this script).
*/
if ($provider = $storage->get('provider')) {
$hybridauth->authenticate($provider);
$storage->set('provider', null);
}
/**
* This will erase the current user authentication data from session, and any further
* attempt to communicate with provider.
*/
if (isset($_GET['logout'])) {
$adapter = $hybridauth->getAdapter($_GET['logout']);
$adapter->disconnect();
}
/**
* Redirects user to home page (i.e., index.php in our case)
*/
HttpClient\Util::redirect('https://path/to/hybridauth/examples/example_06');
} catch (Exception $e) {
echo $e->getMessage();
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Build a configuration array to pass to `Hybridauth\Hybridauth`
*/
$config = [
/**
* Set the Authorization callback URL to https://path/to/hybridauth/examples/example_06/callback.php.
* Understandably, you need to replace 'path/to/hybridauth' with the real path to this script.
*/
'callback' => 'https://path/to/hybridauth/examples/example_06/callback.php',
'providers' => [
'Twitter' => [
'enabled' => true,
'keys' => [
'key' => '...',
'secret' => '...',
],
],
'LinkedIn' => [
'enabled' => true,
'keys' => [
'id' => '...',
'secret' => '...',
],
],
'Facebook' => [
'enabled' => true,
'keys' => [
'id' => '...',
'secret' => '...',
],
],
],
];

View File

@@ -1,49 +0,0 @@
<?php
/**
* Build a simple HTML page with multiple providers.
*/
include 'vendor/autoload.php';
include 'config.php';
use Hybridauth\Hybridauth;
$hybridauth = new Hybridauth($config);
$adapters = $hybridauth->getConnectedAdapters();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 06</title>
</head>
<body>
<h1>Sign in</h1>
<ul>
<?php foreach ($hybridauth->getProviders() as $name) : ?>
<?php if (!isset($adapters[$name])) : ?>
<li>
<a href="<?php print $config['callback'] . "?provider={$name}"; ?>">
Sign in with <strong><?php print $name; ?></strong>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php if ($adapters) : ?>
<h1>You are logged in:</h1>
<ul>
<?php foreach ($adapters as $name => $adapter) : ?>
<li>
<strong><?php print $adapter->getUserProfile()->displayName; ?></strong> from
<i><?php print $name; ?></i>
<span>(<a href="<?php print $config['callback'] . "?logout={$name}"; ?>">Log Out</a>)</span>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</body>
</html>

View File

@@ -1,97 +0,0 @@
<?php
/**
* A simple example that shows how to use multiple providers, opening provider authentication in a pop-up.
*/
require 'path/to/vendor/autoload.php';
require 'config.php';
use Hybridauth\Exception\Exception;
use Hybridauth\Hybridauth;
use Hybridauth\HttpClient;
use Hybridauth\Storage\Session;
try {
$hybridauth = new Hybridauth($config);
$storage = new Session();
$error = false;
//
// Event 1: User clicked SIGN-IN link
//
if (isset($_GET['provider'])) {
// Validate provider exists in the $config
if (in_array($_GET['provider'], $hybridauth->getProviders())) {
// Store the provider for the callback event
$storage->set('provider', $_GET['provider']);
} else {
$error = $_GET['provider'];
}
}
//
// Event 2: User clicked LOGOUT link
//
if (isset($_GET['logout'])) {
if (in_array($_GET['logout'], $hybridauth->getProviders())) {
// Disconnect the adapter
$adapter = $hybridauth->getAdapter($_GET['logout']);
$adapter->disconnect();
} else {
$error = $_GET['logout'];
}
}
//
// Handle invalid provider errors
//
if ($error) {
error_log('HybridAuth Error: Provider '. json_encode($error) .' not found or not enabled in $config');
// Close the pop-up window
echo "
<script>
window.opener.location.reload();
window.close();
</script>";
exit;
}
//
// Event 3: Provider returns via CALLBACK
//
if ($provider = $storage->get('provider')) {
$hybridauth->authenticate($provider);
$storage->set('provider', null);
// Retrieve the provider record
$adapter = $hybridauth->getAdapter($provider);
$userProfile = $adapter->getUserProfile();
$accessToken = $adapter->getAccessToken();
// add your custom AUTH functions (if any) here
// ...
$data = [
'token' => $accessToken,
'identifier' => $userProfile->identifier,
'email' => $userProfile->email,
'first_name' => $userProfile->firstName,
'last_name' => $userProfile->lastName,
'photoURL' => strtok($userProfile->photoURL,'?'),
];
// ...
// Close pop-up window
echo "
<script>
window.opener.location.reload();
window.close();
</script>";
}
} catch (Exception $e) {
error_log( $e->getMessage());
echo $e->getMessage();
}

View File

@@ -1,27 +0,0 @@
<?php
/**
* Build a configuration array to pass to `Hybridauth\Hybridauth`
*
* Set the Authorization callback URL to https://path/to/hybridauth/examples/example_07/callback.php
* Understandably, you need to replace 'path/to/hybridauth' with the real path to this script.
*/
$config = [
'callback' => 'https://path/to/hybridauth/examples/example_07/callback.php',
'providers' => [
'Google' => [
'enabled' => true,
'keys' => [
'id' => '...',
'secret' => '...',
],
'scope' => 'email',
],
// 'Yahoo' => ['enabled' => true, 'keys' => [ 'key' => '...', 'secret' => '...']],
// 'Facebook' => ['enabled' => true, 'keys' => [ 'id' => '...', 'secret' => '...']],
// 'Twitter' => ['enabled' => true, 'keys' => [ 'key' => '...', 'secret' => '...']],
// 'Instagram' => ['enabled' => true, 'keys' => [ 'id' => '...', 'secret' => '...']],
],
];

View File

@@ -1,61 +0,0 @@
<?php
/**
* Build a simple HTML page with multiple providers, opening provider authentication in a pop-up.
*/
require 'path/to/vendor/autoload.php';
require 'config.php';
use Hybridauth\Hybridauth;
$hybridauth = new Hybridauth($config);
$adapters = $hybridauth->getConnectedAdapters();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 07</title>
<script>
function auth_popup( provider ){
// replace 'path/to/hybridauth' with the real path to this script
var authWindow = window.open('https://path/to/hybridauth/examples/example_07/callback.php?provider='+provider, 'authWindow', 'width=600,height=400,scrollbars=yes');
return false;
}
</script>
</head>
<body>
<h1>Sign in</h1>
<ul>
<?php foreach ($hybridauth->getProviders() as $name) : ?>
<?php if (!isset($adapters[$name])) : ?>
<li>
<a href="#" onclick="javascript:auth_popup('<?php print $name ?>');">
Sign in with <?php print $name ?>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php if ($adapters) : ?>
<h1>You are logged in:</h1>
<ul>
<?php foreach ($adapters as $name => $adapter) : ?>
<li>
<strong><?php print $adapter->getUserProfile()->displayName; ?></strong> from
<i><?php print $name; ?></i>
<span>(<a href="<?php print $config['callback'] . "?logout={$name}"; ?>">Log Out</a>)</span>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</body>
</html>

View File

@@ -1 +0,0 @@
403.

View File

@@ -78,23 +78,23 @@ abstract class AbstractAdapter implements AdapterInterface
/**
* Whether to validate API status codes of http responses
*
* @var boolean
* @var bool
*/
protected $validateApiResponseHttpCode = true;
/**
* Common adapters constructor.
*
* @param array $config
* @param array $config
* @param HttpClientInterface $httpClient
* @param StorageInterface $storage
* @param LoggerInterface $logger
* @param StorageInterface $storage
* @param LoggerInterface $logger
*/
public function __construct(
$config = [],
HttpClientInterface $httpClient = null,
StorageInterface $storage = null,
LoggerInterface $logger = null
StorageInterface $storage = null,
LoggerInterface $logger = null
) {
$this->providerId = (new \ReflectionClass($this))->getShortName();
@@ -114,15 +114,20 @@ abstract class AbstractAdapter implements AdapterInterface
}
/**
* Load adapter's configuration
*/
* Load adapter's configuration
*/
abstract protected function configure();
/**
* Adapter initializer
*/
* Adapter initializer
*/
abstract protected function initialize();
/**
* {@inheritdoc}
*/
abstract public function isConnected();
/**
* {@inheritdoc}
*/
@@ -179,16 +184,6 @@ abstract class AbstractAdapter implements AdapterInterface
throw new NotImplementedException('Provider does not support this feature.');
}
/**
* {@inheritdoc}
*
* Checking access_token only works for oauth1 and oauth2, openid will overwrite this method.
*/
public function isConnected()
{
return (bool) $this->getStoredData('access_token');
}
/**
* {@inheritdoc}
*/
@@ -215,7 +210,7 @@ abstract class AbstractAdapter implements AdapterInterface
foreach ($tokenNames as $name) {
if ($this->getStoredData($name)) {
$tokens[ $name ] = $this->getStoredData($name);
$tokens[$name] = $this->getStoredData($name);
}
}
@@ -297,15 +292,15 @@ abstract class AbstractAdapter implements AdapterInterface
}
/**
* Set Adapter's API callback url
*
* @param string $callback
*
* @throws InvalidArgumentException
*/
* Set Adapter's API callback url
*
* @param string $callback
*
* @throws InvalidArgumentException
*/
protected function setCallback($callback)
{
if (! filter_var($callback, FILTER_VALIDATE_URL)) {
if (!filter_var($callback, FILTER_VALIDATE_URL)) {
throw new InvalidArgumentException('A valid callback url is required.');
}
@@ -348,12 +343,12 @@ abstract class AbstractAdapter implements AdapterInterface
if ($this->httpClient->getResponseClientError()) {
throw new HttpClientFailureException(
$error.'HTTP client error: '.$this->httpClient->getResponseClientError().'.'
$error . 'HTTP client error: ' . $this->httpClient->getResponseClientError() . '.'
);
}
// if validateApiResponseHttpCode is set to false, we by pass verification of http status code
if (! $this->validateApiResponseHttpCode) {
if (!$this->validateApiResponseHttpCode) {
return;
}
@@ -361,8 +356,8 @@ abstract class AbstractAdapter implements AdapterInterface
if ($status < 200 || $status > 299) {
throw new HttpRequestFailedException(
$error . 'HTTP error '.$this->httpClient->getResponseHttpCode().
'. Raw Provider API response: '.$this->httpClient->getResponseBody().'.'
$error . 'HTTP error ' . $this->httpClient->getResponseHttpCode() .
'. Raw Provider API response: ' . $this->httpClient->getResponseBody() . '.'
);
}
}

View File

@@ -19,14 +19,14 @@ interface AdapterInterface
/**
* Initiate the appropriate protocol and process/automate the authentication or authorization flow.
*
* @return boolean|null
* @return bool|null
*/
public function authenticate();
/**
* Returns TRUE if the user is connected
*
* @return boolean
* @return bool
*/
public function isConnected();

View File

@@ -26,7 +26,7 @@ trait DataStoreTrait
* can be also used by providers to store any other useful data (i.g., user_id, auth_nonce, etc.)
*
* @param string $name
* @param mixed $value
* @param mixed $value
*/
protected function storeData($name, $value = null)
{
@@ -35,7 +35,7 @@ trait DataStoreTrait
$this->deleteStoredData($name);
}
$this->getStorage()->set($this->providerId.'.'.$name, $value);
$this->getStorage()->set($this->providerId . '.' . $name, $value);
}
/**
@@ -51,7 +51,7 @@ trait DataStoreTrait
*/
protected function getStoredData($name)
{
return $this->getStorage()->get($this->providerId.'.'.$name);
return $this->getStorage()->get($this->providerId . '.' . $name);
}
/**
@@ -61,7 +61,7 @@ trait DataStoreTrait
*/
protected function deleteStoredData($name)
{
$this->getStorage()->delete($this->providerId.'.'.$name);
$this->getStorage()->delete($this->providerId . '.' . $name);
}
/**
@@ -69,6 +69,6 @@ trait DataStoreTrait
*/
protected function clearStoredData()
{
$this->getStorage()->deleteMatch($this->providerId.'.');
$this->getStorage()->deleteMatch($this->providerId . '.');
}
}

View File

@@ -28,129 +28,129 @@ use Hybridauth\Thirdparty\OAuth\OAuthUtil;
abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
{
/**
* Base URL to provider API
*
* This var will be used to build urls when sending signed requests
*
* @var string
*/
* Base URL to provider API
*
* This var will be used to build urls when sending signed requests
*
* @var string
*/
protected $apiBaseUrl = '';
/**
* @var string
*/
* @var string
*/
protected $authorizeUrl = '';
/**
* @var string
*/
* @var string
*/
protected $requestTokenUrl = '';
/**
* @var string
*/
* @var string
*/
protected $accessTokenUrl = '';
/**
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
protected $apiDocumentation = '';
/**
* OAuth Version
*
* '1.0' OAuth Core 1.0
* '1.0a' OAuth Core 1.0 Revision A
*
* @var string
*/
* OAuth Version
*
* '1.0' OAuth Core 1.0
* '1.0a' OAuth Core 1.0 Revision A
*
* @var string
*/
protected $oauth1Version = '1.0a';
/**
* @var string
*/
* @var string
*/
protected $consumerKey = null;
/**
* @var string
*/
* @var string
*/
protected $consumerSecret = null;
/**
* @var object
*/
* @var object
*/
protected $OAuthConsumer = null;
/**
* @var object
*/
* @var object
*/
protected $sha1Method = null;
/**
* @var object
*/
* @var object
*/
protected $consumerToken = null;
/**
* Authorization Url Parameters
*
* @var boolean
*/
* Authorization Url Parameters
*
* @var bool
*/
protected $AuthorizeUrlParameters = [];
/**
* @var string
*/
* @var string
*/
protected $requestTokenMethod = 'POST';
/**
* @var array
*/
* @var array
*/
protected $requestTokenParameters = [];
/**
* @var array
*/
* @var array
*/
protected $requestTokenHeaders = [];
/**
* @var string
*/
* @var string
*/
protected $tokenExchangeMethod = 'POST';
/**
* @var array
*/
* @var array
*/
protected $tokenExchangeParameters = [];
/**
* @var array
*/
* @var array
*/
protected $tokenExchangeHeaders = [];
/**
* @var array
*/
* @var array
*/
protected $apiRequestParameters = [];
/**
* @var array
*/
* @var array
*/
protected $apiRequestHeaders = [];
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function configure()
{
$this->consumerKey = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
$this->consumerKey = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
$this->consumerSecret = $this->config->filter('keys')->get('secret');
if (! $this->consumerKey || !$this->consumerSecret) {
if (!$this->consumerKey || !$this->consumerSecret) {
throw new InvalidApplicationCredentialsException(
'Your application id is required in order to connect to ' . $this->providerId
);
@@ -165,23 +165,23 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
/**
* Set up OAuth Signature and Consumer
*
* OAuth Core: All Token requests and Protected Resources requests MUST be signed
* by the Consumer and verified by the Service Provider.
*
* The protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT..
*
* The Consumer declares a signature method in the oauth_signature_method parameter..
*
* http://oauth.net/core/1.0a/#signing_process
*/
$this->sha1Method = new OAuthSignatureMethodHMACSHA1();
* Set up OAuth Signature and Consumer
*
* OAuth Core: All Token requests and Protected Resources requests MUST be signed
* by the Consumer and verified by the Service Provider.
*
* The protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT..
*
* The Consumer declares a signature method in the oauth_signature_method parameter..
*
* http://oauth.net/core/1.0a/#signing_process
*/
$this->sha1Method = new OAuthSignatureMethodHMACSHA1();
$this->OAuthConsumer = new OAuthConsumer(
$this->consumerKey,
@@ -204,8 +204,8 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function authenticate()
{
$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
@@ -215,9 +215,14 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
try {
if (! $this->getStoredData('request_token')) {
if (!$this->getStoredData('request_token')) {
// Start a new flow.
$this->authenticateBegin();
} elseif (! $this->getStoredData('access_token')) {
} elseif (empty($_GET['oauth_token']) && empty($_GET['denied'])) {
// A previous authentication was not finished, and this request is not finishing it.
$this->authenticateBegin();
} else {
// Finish a flow.
$this->authenticateFinish();
}
} catch (Exception $exception) {
@@ -230,12 +235,20 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Initiate the authorization protocol
*
* 1. Obtaining an Unauthorized Request Token
* 2. Build Authorization URL for Authorization Request and redirect the user-agent to the
* Authorization Server.
*/
* {@inheritdoc}
*/
public function isConnected()
{
return (bool)$this->getStoredData('access_token');
}
/**
* Initiate the authorization protocol
*
* 1. Obtaining an Unauthorized Request Token
* 2. Build Authorization URL for Authorization Request and redirect the user-agent to the
* Authorization Server.
*/
protected function authenticateBegin()
{
$response = $this->requestAuthToken();
@@ -265,9 +278,9 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
[HttpClient\Util::getCurrentUrl(true)]
);
$denied = filter_input(INPUT_GET, 'denied');
$oauth_problem = filter_input(INPUT_GET, 'oauth_problem');
$oauth_token = filter_input(INPUT_GET, 'oauth_token');
$denied = filter_input(INPUT_GET, 'denied');
$oauth_problem = filter_input(INPUT_GET, 'oauth_problem');
$oauth_token = filter_input(INPUT_GET, 'oauth_token');
$oauth_verifier = filter_input(INPUT_GET, 'oauth_verifier');
if ($denied) {
@@ -278,11 +291,11 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
if ($oauth_problem) {
throw new InvalidOauthTokenException(
'Provider returned an invalid oauth_token. oauth_problem: ' . htmlentities($oauth_problem)
'Provider returned an error. oauth_problem: ' . htmlentities($oauth_problem)
);
}
if (! $oauth_token) {
if (!$oauth_token) {
throw new InvalidOauthTokenException(
'Expecting a non-null oauth_token to continue the authorization flow.'
);
@@ -296,20 +309,20 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Build Authorization URL for Authorization Request
*
* @param array $parameters
*
* @return string
*/
* Build Authorization URL for Authorization Request
*
* @param array $parameters
*
* @return string
*/
protected function getAuthorizeUrl($parameters = [])
{
$this->AuthorizeUrlParameters = !empty($parameters)
? $parameters
: array_replace(
(array) $this->AuthorizeUrlParameters,
(array) $this->config->get('authorize_url_parameters')
);
? $parameters
: array_replace(
(array)$this->AuthorizeUrlParameters,
(array)$this->config->get('authorize_url_parameters')
);
$this->AuthorizeUrlParameters['oauth_token'] = $this->getStoredData('request_token');
@@ -317,27 +330,27 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Unauthorized Request Token
*
* OAuth Core: The Consumer obtains an unauthorized Request Token by asking the Service Provider
* to issue a Token. The Request Token's sole purpose is to receive User approval and can only
* be used to obtain an Access Token.
*
* http://oauth.net/core/1.0/#auth_step1
* 6.1.1. Consumer Obtains a Request Token
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
* Unauthorized Request Token
*
* OAuth Core: The Consumer obtains an unauthorized Request Token by asking the Service Provider
* to issue a Token. The Request Token's sole purpose is to receive User approval and can only
* be used to obtain an Access Token.
*
* http://oauth.net/core/1.0/#auth_step1
* 6.1.1. Consumer Obtains a Request Token
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
protected function requestAuthToken()
{
/**
* OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect
* the User back when the Obtaining User Authorization step is completed.
*
* http://oauth.net/core/1.0a/#auth_step1
*/
* OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect
* the User back when the Obtaining User Authorization step is completed.
*
* http://oauth.net/core/1.0a/#auth_step1
*/
if ('1.0a' == $this->oauth1Version) {
$this->requestTokenParameters['oauth_callback'] = $this->callback;
}
@@ -353,51 +366,51 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Validate Unauthorized Request Token Response
*
* OAuth Core: The Service Provider verifies the signature and Consumer Key. If successful,
* it generates a Request Token and Token Secret and returns them to the Consumer in the HTTP
* response body.
*
* http://oauth.net/core/1.0/#auth_step1
* 6.1.2. Service Provider Issues an Unauthorized Request Token
*
* @param string $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidOauthTokenException
*/
* Validate Unauthorized Request Token Response
*
* OAuth Core: The Service Provider verifies the signature and Consumer Key. If successful,
* it generates a Request Token and Token Secret and returns them to the Consumer in the HTTP
* response body.
*
* http://oauth.net/core/1.0/#auth_step1
* 6.1.2. Service Provider Issues an Unauthorized Request Token
*
* @param string $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidOauthTokenException
*/
protected function validateAuthTokenRequest($response)
{
/**
* The response contains the following parameters:
*
* - oauth_token The Request Token.
* - oauth_token_secret The Token Secret.
* - oauth_callback_confirmed MUST be present and set to true.
*
* http://oauth.net/core/1.0/#auth_step1
* 6.1.2. Service Provider Issues an Unauthorized Request Token
*
* Example of a successful response:
*
* HTTP/1.1 200 OK
* Content-Type: text/html; charset=utf-8
* Cache-Control: no-store
* Pragma: no-cache
*
* oauth_token=80359084-clg1DEtxQF3wstTcyUdHF3wsdHM&oauth_token_secret=OIF07hPmJB:P
* 6qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e&example_parameter=example_value
*
* OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
*/
* The response contains the following parameters:
*
* - oauth_token The Request Token.
* - oauth_token_secret The Token Secret.
* - oauth_callback_confirmed MUST be present and set to true.
*
* http://oauth.net/core/1.0/#auth_step1
* 6.1.2. Service Provider Issues an Unauthorized Request Token
*
* Example of a successful response:
*
* HTTP/1.1 200 OK
* Content-Type: text/html; charset=utf-8
* Cache-Control: no-store
* Pragma: no-cache
*
* oauth_token=80359084-clg1DEtxQF3wstTcyUdHF3wsdHM&oauth_token_secret=OIF07hPmJB:P
* 6qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e&example_parameter=example_value
*
* OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
*/
$tokens = OAuthUtil::parse_parameters($response);
$collection = new Data\Collection($tokens);
if (! $collection->exists('oauth_token')) {
if (!$collection->exists('oauth_token')) {
throw new InvalidOauthTokenException(
'Provider returned an invalid access_token: ' . htmlentities($response)
'Provider returned no oauth_token: ' . htmlentities($response)
);
}
@@ -413,30 +426,30 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Requests an Access Token
*
* OAuth Core: The Request Token and Token Secret MUST be exchanged for an Access Token and Token Secret.
*
* http://oauth.net/core/1.0a/#auth_step3
* 6.3.1. Consumer Requests an Access Token
*
* @param string $oauth_token
* @param string $oauth_verifier
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
* Requests an Access Token
*
* OAuth Core: The Request Token and Token Secret MUST be exchanged for an Access Token and Token Secret.
*
* http://oauth.net/core/1.0a/#auth_step3
* 6.3.1. Consumer Requests an Access Token
*
* @param string $oauth_token
* @param string $oauth_verifier
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
protected function exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier = '')
{
$this->tokenExchangeParameters['oauth_token'] = $oauth_token;
/**
* OAuth Core 1.0 Revision A: oauth_verifier: The verification code received from the Service Provider
* in the "Service Provider Directs the User Back to the Consumer" step.
*
* http://oauth.net/core/1.0a/#auth_step3
*/
* OAuth Core 1.0 Revision A: oauth_verifier: The verification code received from the Service Provider
* in the "Service Provider Directs the User Back to the Consumer" step.
*
* http://oauth.net/core/1.0a/#auth_step3
*/
if ('1.0a' == $this->oauth1Version) {
$this->tokenExchangeParameters['oauth_verifier'] = $oauth_verifier;
}
@@ -452,50 +465,50 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Validate Access Token Response
*
* OAuth Core: If successful, the Service Provider generates an Access Token and Token Secret and returns
* them in the HTTP response body.
*
* The Access Token and Token Secret are stored by the Consumer and used when signing Protected Resources requests.
*
* http://oauth.net/core/1.0a/#auth_step3
* 6.3.2. Service Provider Grants an Access Token
*
* @param string $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidAccessTokenException
*/
* Validate Access Token Response
*
* OAuth Core: If successful, the Service Provider generates an Access Token and Token Secret and returns
* them in the HTTP response body.
*
* The Access Token and Token Secret are stored by the Consumer and used when signing Protected Resources requests.
*
* http://oauth.net/core/1.0a/#auth_step3
* 6.3.2. Service Provider Grants an Access Token
*
* @param string $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidAccessTokenException
*/
protected function validateAccessTokenExchange($response)
{
/**
* The response contains the following parameters:
*
* - oauth_token The Access Token.
* - oauth_token_secret The Token Secret.
*
* http://oauth.net/core/1.0/#auth_step3
* 6.3.2. Service Provider Grants an Access Token
*
* Example of a successful response:
*
* HTTP/1.1 200 OK
* Content-Type: text/html; charset=utf-8
* Cache-Control: no-store
* Pragma: no-cache
*
* oauth_token=sHeLU7Far428zj8PzlWR75&oauth_token_secret=fXb30rzoG&oauth_callback_confirmed=true
*
* OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
*/
* The response contains the following parameters:
*
* - oauth_token The Access Token.
* - oauth_token_secret The Token Secret.
*
* http://oauth.net/core/1.0/#auth_step3
* 6.3.2. Service Provider Grants an Access Token
*
* Example of a successful response:
*
* HTTP/1.1 200 OK
* Content-Type: text/html; charset=utf-8
* Cache-Control: no-store
* Pragma: no-cache
*
* oauth_token=sHeLU7Far428zj8PzlWR75&oauth_token_secret=fXb30rzoG&oauth_callback_confirmed=true
*
* OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
*/
$tokens = OAuthUtil::parse_parameters($response);
$collection = new Data\Collection($tokens);
if (! $collection->exists('oauth_token')) {
if (!$collection->exists('oauth_token')) {
throw new InvalidAccessTokenException(
'Provider returned an invalid access_token: ' . htmlentities($response)
'Provider returned no access_token: ' . htmlentities($response)
);
}
@@ -514,21 +527,21 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Send a signed request to provider API
*
* Note: Since the specifics of error responses is beyond the scope of RFC6749 and OAuth specifications,
* Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
*
* @param string $url
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
* Send a signed request to provider API
*
* Note: Since the specifics of error responses is beyond the scope of RFC6749 and OAuth specifications,
* Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
*
* @param string $url
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
@@ -547,20 +560,20 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
}
/**
* Setup and Send a Signed Oauth Request
*
* This method uses OAuth Library.
*
* @param string $uri
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
* Setup and Send a Signed Oauth Request
*
* This method uses OAuth Library.
*
* @param string $uri
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
protected function oauthRequest($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
$signing_parameters = $parameters;
@@ -582,9 +595,8 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
$this->consumerToken
);
$uri = $request->get_normalized_http_url();
$parameters = array_replace($parameters, $request->parameters);
$headers = array_replace($request->to_header(), (array) $headers);
$uri = $request->get_normalized_http_url();
$headers = array_replace($request->to_header(), (array)$headers);
$response = $this->httpClient->request(
$uri,
@@ -594,7 +606,7 @@ abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
$multipart
);
$this->validateApiResponse('Signed API request has returned an error');
$this->validateApiResponse('Signed API request to ' . $uri . ' has returned an error');
return $response;
}

View File

@@ -11,6 +11,7 @@ use Hybridauth\Exception\Exception;
use Hybridauth\Exception\InvalidApplicationCredentialsException;
use Hybridauth\Exception\InvalidAuthorizationStateException;
use Hybridauth\Exception\InvalidAuthorizationCodeException;
use Hybridauth\Exception\AuthorizationDeniedException;
use Hybridauth\Exception\InvalidAccessTokenException;
use Hybridauth\Data;
use Hybridauth\HttpClient;
@@ -24,222 +25,231 @@ use Hybridauth\HttpClient;
abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
{
/**
* Client Identifier
*
* RFC6749: client_id REQUIRED. The client identifier issued to the client during
* the registration process described by Section 2.2.
*
* http://tools.ietf.org/html/rfc6749#section-2.2
*
* @var string
*/
protected $clientId = '' ;
* Client Identifier
*
* RFC6749: client_id REQUIRED. The client identifier issued to the client during
* the registration process described by Section 2.2.
*
* http://tools.ietf.org/html/rfc6749#section-2.2
*
* @var string
*/
protected $clientId = '';
/**
* Client Secret
*
* RFC6749: client_secret REQUIRED. The client secret. The client MAY omit the
* parameter if the client secret is an empty string.
*
* http://tools.ietf.org/html/rfc6749#section-2.2
*
* @var string
*/
protected $clientSecret = '' ;
* Client Secret
*
* RFC6749: client_secret REQUIRED. The client secret. The client MAY omit the
* parameter if the client secret is an empty string.
*
* http://tools.ietf.org/html/rfc6749#section-2.2
*
* @var string
*/
protected $clientSecret = '';
/**
* Access Token Scope
*
* RFC6749: The authorization and token endpoints allow the client to specify the
* scope of the access request using the "scope" request parameter.
*
* http://tools.ietf.org/html/rfc6749#section-3.3
*
* @var string
*/
* Access Token Scope
*
* RFC6749: The authorization and token endpoints allow the client to specify the
* scope of the access request using the "scope" request parameter.
*
* http://tools.ietf.org/html/rfc6749#section-3.3
*
* @var string
*/
protected $scope = '';
/**
* Base URL to provider API
*
* This var will be used to build urls when sending signed requests
*
* @var string
*/
* Base URL to provider API
*
* This var will be used to build urls when sending signed requests
*
* @var string
*/
protected $apiBaseUrl = '';
/**
* Authorization Endpoint
*
* RFC6749: The authorization endpoint is used to interact with the resource
* owner and obtain an authorization grant.
*
* http://tools.ietf.org/html/rfc6749#section-3.1
*
* @var string
*/
* Authorization Endpoint
*
* RFC6749: The authorization endpoint is used to interact with the resource
* owner and obtain an authorization grant.
*
* http://tools.ietf.org/html/rfc6749#section-3.1
*
* @var string
*/
protected $authorizeUrl = '';
/**
* Access Token Endpoint
*
* RFC6749: The token endpoint is used by the client to obtain an access token by
* presenting its authorization grant or refresh token.
*
* http://tools.ietf.org/html/rfc6749#section-3.2
*
* @var string
*/
* Access Token Endpoint
*
* RFC6749: The token endpoint is used by the client to obtain an access token by
* presenting its authorization grant or refresh token.
*
* http://tools.ietf.org/html/rfc6749#section-3.2
*
* @var string
*/
protected $accessTokenUrl = '';
/**
* TokenInfo endpoint
*
* Access token validation. OPTIONAL.
*
* @var string
*/
* TokenInfo endpoint
*
* Access token validation. OPTIONAL.
*
* @var string
*/
protected $accessTokenInfoUrl = '';
/**
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
protected $apiDocumentation = '';
/**
* Redirection Endpoint or Callback
*
* RFC6749: After completing its interaction with the resource owner, the
* authorization server directs the resource owner's user-agent back to
* the client.
*
* http://tools.ietf.org/html/rfc6749#section-3.1.2
*
* @var string
*/
* Redirection Endpoint or Callback
*
* RFC6749: After completing its interaction with the resource owner, the
* authorization server directs the resource owner's user-agent back to
* the client.
*
* http://tools.ietf.org/html/rfc6749#section-3.1.2
*
* @var string
*/
protected $callback = '';
/**
* Authorization Url Parameters
*
* @var boolean
*/
* Authorization Url Parameters
*
* @var array
*/
protected $AuthorizeUrlParameters = [];
/**
* Authorization Request State
*
* @var boolean
*/
* Authorization Url Parameter encoding type
* @see https://www.php.net/manual/de/function.http-build-query.php
*
* @var string
*/
protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC1738;
/**
* Authorization Request State
*
* @var bool
*/
protected $supportRequestState = true;
/**
* Access Token name
*
* While most providers will use 'access_token' as name for the Access Token attribute, other do not.
* On the latter case, this should be set by sub classes.
*
* @var string
*/
* Access Token name
*
* While most providers will use 'access_token' as name for the Access Token attribute, other do not.
* On the latter case, this should be set by sub classes.
*
* @var string
*/
protected $accessTokenName = 'access_token';
/**
* Authorization Request HTTP method.
*
* @see exchangeCodeForAccessToken()
*
* @var string
*/
* Authorization Request HTTP method.
*
* @see exchangeCodeForAccessToken()
*
* @var string
*/
protected $tokenExchangeMethod = 'POST';
/**
* Authorization Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see exchangeCodeForAccessToken()
*
* @var array
*/
* Authorization Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see exchangeCodeForAccessToken()
*
* @var array
*/
protected $tokenExchangeParameters = [];
/**
* Authorization Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see exchangeCodeForAccessToken()
*
* @var array
*/
* Authorization Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see exchangeCodeForAccessToken()
*
* @var array
*/
protected $tokenExchangeHeaders = [];
/**
* Refresh Token Request HTTP method.
*
* @see refreshAccessToken()
*
* @var string
*/
* Refresh Token Request HTTP method.
*
* @see refreshAccessToken()
*
* @var string
*/
protected $tokenRefreshMethod = 'POST';
/**
* Refresh Token Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see refreshAccessToken()
*
* @var array
*/
protected $tokenRefreshParameters = [];
* Refresh Token Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see refreshAccessToken()
*
* @var array|null
*/
protected $tokenRefreshParameters = null;
/**
* Refresh Token Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see refreshAccessToken()
*
* @var array
*/
* Refresh Token Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see refreshAccessToken()
*
* @var array
*/
protected $tokenRefreshHeaders = [];
/**
* Authorization Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see apiRequest()
*
* @var array
*/
* Authorization Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see apiRequest()
*
* @var array
*/
protected $apiRequestParameters = [];
/**
* Authorization Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see apiRequest()
*
* @var array
*/
* Authorization Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see apiRequest()
*
* @var array
*/
protected $apiRequestHeaders = [];
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function configure()
{
$this->clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
$this->clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
$this->clientSecret = $this->config->filter('keys')->get('secret');
if (! $this->clientId || !$this->clientSecret) {
if (!$this->clientId || !$this->clientSecret) {
throw new InvalidApplicationCredentialsException(
'Your application id is required in order to connect to ' . $this->providerId
);
@@ -256,28 +266,31 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
$this->AuthorizeUrlParameters = [
'response_type' => 'code',
'client_id' => $this->clientId,
'redirect_uri' => $this->callback,
'scope' => $this->scope,
'client_id' => $this->clientId,
'redirect_uri' => $this->callback,
'scope' => $this->scope,
];
$this->tokenExchangeParameters = [
'client_id' => $this->clientId,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback
];
$this->tokenRefreshParameters = [
'grant_type' => 'refresh_token',
'refresh_token' => $this->getStoredData('refresh_token'),
];
$refreshToken = $this->getStoredData('refresh_token');
if (!empty($refreshToken)) {
$this->tokenRefreshParameters = [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
];
}
$this->apiRequestHeaders = [
'Authorization' => 'Bearer ' . $this->getStoredData('access_token')
@@ -285,8 +298,8 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function authenticate()
{
$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
@@ -315,34 +328,62 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* Authorization Request Error Response
*
* RFC6749: If the request fails due to a missing, invalid, or mismatching
* redirection URI, or if the client identifier is missing or invalid,
* the authorization server SHOULD inform the resource owner of the error.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.2.1
*/
* {@inheritdoc}
*/
public function isConnected()
{
if ((bool)$this->getStoredData('access_token')) {
return (!$this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
}
return false;
}
/**
* If we can use a refresh token, then an expired token does not stop us being connected.
*
* @return bool
*/
public function isRefreshTokenAvailable()
{
return is_array($this->tokenRefreshParameters);
}
/**
* Authorization Request Error Response
*
* RFC6749: If the request fails due to a missing, invalid, or mismatching
* redirection URI, or if the client identifier is missing or invalid,
* the authorization server SHOULD inform the resource owner of the error.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.2.1
*
* @throws \Hybridauth\Exception\InvalidAuthorizationCodeException
* @throws \Hybridauth\Exception\AuthorizationDeniedException
*/
protected function authenticateCheckError()
{
$error = filter_input(INPUT_GET, 'error', FILTER_SANITIZE_SPECIAL_CHARS);
if (! empty($error)) {
if (!empty($error)) {
$error_description = filter_input(INPUT_GET, 'error_description', FILTER_SANITIZE_SPECIAL_CHARS);
$error_uri = filter_input(INPUT_GET, 'error_uri', FILTER_SANITIZE_SPECIAL_CHARS);
throw new InvalidAuthorizationCodeException(
sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri)
);
$collated_error = sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri);
if ($error == 'access_denied') {
throw new AuthorizationDeniedException($collated_error);
}
throw new InvalidAuthorizationCodeException($collated_error);
}
}
/**
* Initiate the authorization protocol
*
* Build Authorization URL for Authorization Request and redirect the user-agent to the
* Authorization Server.
*/
* Initiate the authorization protocol
*
* Build Authorization URL for Authorization Request and redirect the user-agent to the
* Authorization Server.
*/
protected function authenticateBegin()
{
$authUrl = $this->getAuthorizeUrl();
@@ -353,13 +394,13 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* Finalize the authorization process
*
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
* @throws InvalidAuthorizationStateException
*/
* Finalize the authorization process
*
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
* @throws InvalidAuthorizationStateException
*/
protected function authenticateFinish()
{
$this->logger->debug(
@@ -371,31 +412,31 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
$code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
/**
* Authorization Request State
*
* RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain
* state between the request and callback. The authorization server includes
* this value when redirecting the user-agent back to the client.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.1
*/
* Authorization Request State
*
* RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain
* state between the request and callback. The authorization server includes
* this value when redirecting the user-agent back to the client.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.1
*/
if ($this->supportRequestState
&& $this->getStoredData('authorization_state') != $state
&& $this->getStoredData('authorization_state') != $state
) {
throw new InvalidAuthorizationStateException(
'The authorization state [state=' . substr(htmlentities($state), 0, 100). '] '
. 'of this page is either invalid or has already been consumed.'
'The authorization state [state=' . substr(htmlentities($state), 0, 100) . '] '
. 'of this page is either invalid or has already been consumed.'
);
}
/**
* Authorization Request Code
*
* RFC6749: If the resource owner grants the access request, the authorization
* server issues an authorization code and delivers it to the client:
*
* http://tools.ietf.org/html/rfc6749#section-4.1.2
*/
* Authorization Request Code
*
* RFC6749: If the resource owner grants the access request, the authorization
* server issues an authorization code and delivers it to the client:
*
* http://tools.ietf.org/html/rfc6749#section-4.1.2
*/
$response = $this->exchangeCodeForAccessToken($code);
$this->validateAccessTokenExchange($response);
@@ -404,32 +445,32 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* Build Authorization URL for Authorization Request
*
* RFC6749: The client constructs the request URI by adding the following
* $parameters to the query component of the authorization endpoint URI:
*
* - response_type REQUIRED. Value MUST be set to "code".
* - client_id REQUIRED.
* - redirect_uri OPTIONAL.
* - scope OPTIONAL.
* - state RECOMMENDED.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.1
*
* Sub classes may redefine this method when necessary.
*
* @param array $parameters
*
* @return string Authorization URL
*/
* Build Authorization URL for Authorization Request
*
* RFC6749: The client constructs the request URI by adding the following
* $parameters to the query component of the authorization endpoint URI:
*
* - response_type REQUIRED. Value MUST be set to "code".
* - client_id REQUIRED.
* - redirect_uri OPTIONAL.
* - scope OPTIONAL.
* - state RECOMMENDED.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.1
*
* Sub classes may redefine this method when necessary.
*
* @param array $parameters
*
* @return string Authorization URL
*/
protected function getAuthorizeUrl($parameters = [])
{
$this->AuthorizeUrlParameters = !empty($parameters)
? $parameters
: array_replace(
(array) $this->AuthorizeUrlParameters,
(array) $this->config->get('authorize_url_parameters')
(array)$this->AuthorizeUrlParameters,
(array)$this->config->get('authorize_url_parameters')
);
if ($this->supportRequestState) {
@@ -440,31 +481,32 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
$this->storeData('authorization_state', $this->AuthorizeUrlParameters['state']);
}
return $this->authorizeUrl . '?' . http_build_query($this->AuthorizeUrlParameters, '', '&');
$queryParams = http_build_query($this->AuthorizeUrlParameters, '', '&', $this->AuthorizeUrlParametersEncType);
return $this->authorizeUrl . '?' . $queryParams;
}
/**
* Access Token Request
*
* This method will exchange the received $code in loginFinish() with an Access Token.
*
* RFC6749: The client makes a request to the token endpoint by sending the
* following parameters using the "application/x-www-form-urlencoded"
* with a character encoding of UTF-8 in the HTTP request entity-body:
*
* - grant_type REQUIRED. Value MUST be set to "authorization_code".
* - code REQUIRED. The authorization code received from the authorization server.
* - redirect_uri REQUIRED.
* - client_id REQUIRED.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.3
*
* @param string $code
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
* Access Token Request
*
* This method will exchange the received $code in loginFinish() with an Access Token.
*
* RFC6749: The client makes a request to the token endpoint by sending the
* following parameters using the "application/x-www-form-urlencoded"
* with a character encoding of UTF-8 in the HTTP request entity-body:
*
* - grant_type REQUIRED. Value MUST be set to "authorization_code".
* - code REQUIRED. The authorization code received from the authorization server.
* - redirect_uri REQUIRED.
* - client_id REQUIRED.
*
* http://tools.ietf.org/html/rfc6749#section-4.1.3
*
* @param string $code
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
*/
protected function exchangeCodeForAccessToken($code)
{
$this->tokenExchangeParameters['code'] = $code;
@@ -482,47 +524,47 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* Validate Access Token Response
*
* RFC6749: If the access token request is valid and authorized, the
* authorization server issues an access token and optional refresh token.
* If the request client authentication failed or is invalid, the authorization
* server returns an error response as described in Section 5.2.
*
* Example of a successful response:
*
* HTTP/1.1 200 OK
* Content-Type: application/json;charset=UTF-8
* Cache-Control: no-store
* Pragma: no-cache
*
* {
* "access_token":"2YotnFZFEjr1zCsicMWpAA",
* "token_type":"example",
* "expires_in":3600,
* "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
* "example_parameter":"example_value"
* }
*
* http://tools.ietf.org/html/rfc6749#section-4.1.4
*
* This method uses Data_Parser to attempt to decodes the raw $response (usually JSON)
* into a data collection.
*
* @param string $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidAccessTokenException
*/
* Validate Access Token Response
*
* RFC6749: If the access token request is valid and authorized, the
* authorization server issues an access token and optional refresh token.
* If the request client authentication failed or is invalid, the authorization
* server returns an error response as described in Section 5.2.
*
* Example of a successful response:
*
* HTTP/1.1 200 OK
* Content-Type: application/json;charset=UTF-8
* Cache-Control: no-store
* Pragma: no-cache
*
* {
* "access_token":"2YotnFZFEjr1zCsicMWpAA",
* "token_type":"example",
* "expires_in":3600,
* "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
* "example_parameter":"example_value"
* }
*
* http://tools.ietf.org/html/rfc6749#section-4.1.4
*
* This method uses Data_Parser to attempt to decodes the raw $response (usually JSON)
* into a data collection.
*
* @param string $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidAccessTokenException
*/
protected function validateAccessTokenExchange($response)
{
$data = (new Data\Parser())->parse($response);
$collection = new Data\Collection($data);
if (! $collection->exists('access_token')) {
if (!$collection->exists('access_token')) {
throw new InvalidAccessTokenException(
'Provider returned an invalid access_token: ' . htmlentities($response)
'Provider returned no access_token: ' . htmlentities($response)
);
}
@@ -535,7 +577,7 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
// calculate when the access token expire
if ($collection->exists('expires_in')) {
$expires_at = time() + (int) $collection->get('expires_in');
$expires_at = time() + (int)$collection->get('expires_in');
$this->storeData('expires_in', $collection->get('expires_in'));
$this->storeData('expires_at', $expires_at);
@@ -549,34 +591,38 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* Refreshing an Access Token
*
* RFC6749: If the authorization server issued a refresh token to the
* client, the client makes a refresh request to the token endpoint by
* adding the following parameters ... in the HTTP request entity-body:
*
* - grant_type REQUIRED. Value MUST be set to "refresh_token".
* - refresh_token REQUIRED. The refresh token issued to the client.
* - scope OPTIONAL.
*
* http://tools.ietf.org/html/rfc6749#section-6
*
* This method is similar to exchangeCodeForAccessToken(). The only
* difference is here we exchange refresh_token for a new access_token.
*
* @param array $parameters
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
* Refreshing an Access Token
*
* RFC6749: If the authorization server issued a refresh token to the
* client, the client makes a refresh request to the token endpoint by
* adding the following parameters ... in the HTTP request entity-body:
*
* - grant_type REQUIRED. Value MUST be set to "refresh_token".
* - refresh_token REQUIRED. The refresh token issued to the client.
* - scope OPTIONAL.
*
* http://tools.ietf.org/html/rfc6749#section-6
*
* This method is similar to exchangeCodeForAccessToken(). The only
* difference is here we exchange refresh_token for a new access_token.
*
* @param array $parameters
*
* @return string|null Raw Provider API response, or null if we cannot refresh
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
public function refreshAccessToken($parameters = [])
{
$this->tokenRefreshParameters = !empty($parameters)
? $parameters
: $this->tokenRefreshParameters;
if (!$this->isRefreshTokenAvailable()) {
return null;
}
$response = $this->httpClient->request(
$this->accessTokenUrl,
$this->tokenRefreshMethod,
@@ -592,70 +638,75 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
}
/**
* Check whether access token has expired
*
* @return bool|null
*/
public function hasAccessTokenExpired()
* Check whether access token has expired
*
* @param int|null $time
* @return bool|null
*/
public function hasAccessTokenExpired($time = null)
{
if ($time === null) {
$time = time();
}
$expires_at = $this->getStoredData('expires_at');
if (!$expires_at) {
return null;
}
return $expires_at <= time();
return $expires_at <= $time;
}
/**
* Validate Refresh Access Token Request
*
* RFC6749: If valid and authorized, the authorization server issues an
* access token as described in Section 5.1. If the request failed
* verification or is invalid, the authorization server returns an error
* response as described in Section 5.2.
*
* http://tools.ietf.org/html/rfc6749#section-6
* http://tools.ietf.org/html/rfc6749#section-5.1
* http://tools.ietf.org/html/rfc6749#section-5.2
*
* This method simply use validateAccessTokenExchange(), however sub
* classes may redefine it when necessary.
*
* @param $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidAccessTokenException
*/
* Validate Refresh Access Token Request
*
* RFC6749: If valid and authorized, the authorization server issues an
* access token as described in Section 5.1. If the request failed
* verification or is invalid, the authorization server returns an error
* response as described in Section 5.2.
*
* http://tools.ietf.org/html/rfc6749#section-6
* http://tools.ietf.org/html/rfc6749#section-5.1
* http://tools.ietf.org/html/rfc6749#section-5.2
*
* This method simply use validateAccessTokenExchange(), however sub
* classes may redefine it when necessary.
*
* @param $response
*
* @return \Hybridauth\Data\Collection
* @throws InvalidAccessTokenException
*/
protected function validateRefreshAccessToken($response)
{
return $this->validateAccessTokenExchange($response);
}
/**
* Send a signed request to provider API
*
* RFC6749: Accessing Protected Resources: The client accesses protected
* resources by presenting the access token to the resource server. The
* resource server MUST validate the access token and ensure that it has
* not expired and that its scope covers the requested resource.
*
* Note: Since the specifics of error responses is beyond the scope of
* RFC6749 and OAuth specifications, Hybridauth will consider any HTTP
* status code that is different than '200 OK' as an ERROR.
*
* http://tools.ietf.org/html/rfc6749#section-7
*
* @param string $url
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
* Send a signed request to provider API
*
* RFC6749: Accessing Protected Resources: The client accesses protected
* resources by presenting the access token to the resource server. The
* resource server MUST validate the access token and ensure that it has
* not expired and that its scope covers the requested resource.
*
* Note: Since the specifics of error responses is beyond the scope of
* RFC6749 and OAuth specifications, Hybridauth will consider any HTTP
* status code that is different than '200 OK' as an ERROR.
*
* http://tools.ietf.org/html/rfc6749#section-7
*
* @param string $url
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
// refresh tokens if needed
@@ -667,8 +718,8 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
$url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
}
$parameters = array_replace($this->apiRequestParameters, (array) $parameters);
$headers = array_replace($this->apiRequestHeaders, (array) $headers);
$parameters = array_replace($this->apiRequestParameters, (array)$parameters);
$headers = array_replace($this->apiRequestHeaders, (array)$headers);
$response = $this->httpClient->request(
$url,
@@ -678,7 +729,7 @@ abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
$multipart // Is request multipart
);
$this->validateApiResponse('Signed API request has returned an error');
$this->validateApiResponse('Signed API request to ' . $url . ' has returned an error');
$response = (new Data\Parser())->parse($response);

View File

@@ -25,22 +25,22 @@ use Hybridauth\Thirdparty\OpenID\LightOpenID;
abstract class OpenID extends AbstractAdapter implements AdapterInterface
{
/**
* LightOpenID instance
*
* @var object
*/
* LightOpenID instance
*
* @var object
*/
protected $openIdClient = null;
/**
* Openid provider identifier
*
* @var string
*/
* Openid provider identifier
*
* @var string
*/
protected $openidIdentifier = '';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function configure()
{
if ($this->config->exists('openid_identifier')) {
@@ -56,12 +56,12 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
$hostPort = parse_url($this->callback, PHP_URL_PORT);
$hostUrl = parse_url($this->callback, PHP_URL_HOST);
$hostUrl = parse_url($this->callback, PHP_URL_HOST);
if ($hostPort) {
$hostUrl .= ':' . $hostPort;
@@ -72,8 +72,8 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function authenticate()
{
$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
@@ -92,16 +92,16 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function isConnected()
{
return (bool) $this->storage->get($this->providerId . '.user');
return (bool)$this->storage->get($this->providerId . '.user');
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function disconnect()
{
$this->storage->delete($this->providerId . '.user');
@@ -110,31 +110,31 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* Initiate the authorization protocol
*
* Include and instantiate LightOpenID
*/
* Initiate the authorization protocol
*
* Include and instantiate LightOpenID
*/
protected function authenticateBegin()
{
$this->openIdClient->identity = $this->openidIdentifier;
$this->openIdClient->identity = $this->openidIdentifier;
$this->openIdClient->returnUrl = $this->callback;
$this->openIdClient->required = [
'namePerson/first' ,
'namePerson/last' ,
'namePerson/friendly' ,
'namePerson' ,
'contact/email' ,
'birthDate' ,
'birthDate/birthDay' ,
'birthDate/birthMonth' ,
'birthDate/birthYear' ,
'person/gender' ,
'pref/language' ,
$this->openIdClient->required = [
'namePerson/first',
'namePerson/last',
'namePerson/friendly',
'namePerson',
'contact/email',
'birthDate',
'birthDate/birthDay',
'birthDate/birthMonth',
'birthDate/birthYear',
'person/gender',
'pref/language',
'contact/postalCode/home',
'contact/city/home' ,
'contact/country/home' ,
'contact/city/home',
'contact/country/home',
'media/image/default' ,
'media/image/default',
];
$authUrl = $this->openIdClient->authUrl();
@@ -145,11 +145,11 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* Finalize the authorization process.
*
* @throws AuthorizationDeniedException
* @throws UnexpectedApiResponseException
*/
* Finalize the authorization process.
*
* @throws AuthorizationDeniedException
* @throws UnexpectedApiResponseException
*/
protected function authenticateFinish()
{
$this->logger->debug(
@@ -161,13 +161,13 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
throw new AuthorizationDeniedException('User has cancelled the authentication.');
}
if (! $this->openIdClient->validate()) {
if (!$this->openIdClient->validate()) {
throw new UnexpectedApiResponseException('Invalid response received.');
}
$openidAttributes = $this->openIdClient->getAttributes();
if (! $this->openIdClient->identity) {
if (!$this->openIdClient->identity) {
throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
}
@@ -178,31 +178,31 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* Fetch user profile from received openid attributes
*
* @param array $openidAttributes
*
* @return User\Profile
*/
* Fetch user profile from received openid attributes
*
* @param array $openidAttributes
*
* @return User\Profile
*/
protected function fetchUserProfile($openidAttributes)
{
$data = new Data\Collection($openidAttributes);
$userProfile = new User\Profile();
$userProfile->identifier = $this->openIdClient->identity;
$userProfile->identifier = $this->openIdClient->identity;
$userProfile->firstName = $data->get('namePerson/first');
$userProfile->lastName = $data->get('namePerson/last');
$userProfile->email = $data->get('contact/email');
$userProfile->language = $data->get('pref/language');
$userProfile->country = $data->get('contact/country/home');
$userProfile->zip = $data->get('contact/postalCode/home');
$userProfile->gender = $data->get('person/gender');
$userProfile->photoURL = $data->get('media/image/default');
$userProfile->birthDay = $data->get('birthDate/birthDay');
$userProfile->birthMonth = $data->get('birthDate/birthMonth');
$userProfile->birthYear = $data->get('birthDate/birthDate');
$userProfile->firstName = $data->get('namePerson/first');
$userProfile->lastName = $data->get('namePerson/last');
$userProfile->email = $data->get('contact/email');
$userProfile->language = $data->get('pref/language');
$userProfile->country = $data->get('contact/country/home');
$userProfile->zip = $data->get('contact/postalCode/home');
$userProfile->gender = $data->get('person/gender');
$userProfile->photoURL = $data->get('media/image/default');
$userProfile->birthDay = $data->get('birthDate/birthDay');
$userProfile->birthMonth = $data->get('birthDate/birthMonth');
$userProfile->birthYear = $data->get('birthDate/birthDate');
$userProfile = $this->fetchUserGender($userProfile, $data->get('person/gender'));
@@ -212,36 +212,36 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* Extract users display names
*
* @param User\Profile $userProfile
* @param Data\Collection $data
*
* @return User\Profile
*/
* Extract users display names
*
* @param User\Profile $userProfile
* @param Data\Collection $data
*
* @return User\Profile
*/
protected function fetchUserDisplayName(User\Profile $userProfile, Data\Collection $data)
{
$userProfile->displayName = $data->get('namePerson');
$userProfile->displayName = $userProfile->displayName
? $userProfile->displayName
: $data->get('namePerson/friendly');
? $userProfile->displayName
: $data->get('namePerson/friendly');
$userProfile->displayName = $userProfile->displayName
? $userProfile->displayName
: trim($userProfile->firstName . ' ' . $userProfile->lastName);
? $userProfile->displayName
: trim($userProfile->firstName . ' ' . $userProfile->lastName);
return $userProfile;
}
/**
* Extract users gender
*
* @param User\Profile $userProfile
* @param string $gender
*
* @return User\Profile
*/
* Extract users gender
*
* @param User\Profile $userProfile
* @param string $gender
*
* @return User\Profile
*/
protected function fetchUserGender(User\Profile $userProfile, $gender)
{
$gender = strtolower($gender);
@@ -260,13 +260,13 @@ abstract class OpenID extends AbstractAdapter implements AdapterInterface
}
/**
* OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage.
*/
* OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage.
*/
public function getUserProfile()
{
$userProfile = $this->storage->get($this->providerId . '.user');
if (! is_object($userProfile)) {
if (!is_object($userProfile)) {
throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
}

View File

@@ -13,15 +13,15 @@ namespace Hybridauth\Data;
final class Collection
{
/**
* Data collection
*
* @var mixed
*/
* Data collection
*
* @var mixed
*/
protected $collection = null;
/**
* @param mixed $data
*/
* @param mixed $data
*/
public function __construct($data = null)
{
$this->collection = new \stdClass();
@@ -30,26 +30,26 @@ final class Collection
$this->collection = $data;
}
$this->collection = (object) $data;
$this->collection = (object)$data;
}
/**
* Retrieves the whole collection as array
*
* @return mixed
*/
* Retrieves the whole collection as array
*
* @return mixed
*/
public function toArray()
{
return (array) $this->collection;
return (array)$this->collection;
}
/**
* Retrieves an item
*
* @param $property
*
* @return mixed
*/
* Retrieves an item
*
* @param $property
*
* @return mixed
*/
public function get($property)
{
if ($this->exists($property)) {
@@ -60,11 +60,11 @@ final class Collection
}
/**
* Add or update an item
*
* @param $property
* @param mixed $value
*/
* Add or update an item
*
* @param $property
* @param mixed $value
*/
public function set($property, $value)
{
if ($property) {
@@ -73,18 +73,18 @@ final class Collection
}
/**
* .. until I come with a better name..
*
* @param $property
*
* @return Collection
*/
* .. until I come with a better name..
*
* @param $property
*
* @return Collection
*/
public function filter($property)
{
if ($this->exists($property)) {
$data = $this->get($property);
if (! is_a($data, 'Collection')) {
if (!is_a($data, 'Collection')) {
$data = new Collection($data);
}
@@ -95,42 +95,42 @@ final class Collection
}
/**
* Checks whether an item within the collection
*
* @param $property
*
* @return bool
*/
* Checks whether an item within the collection
*
* @param $property
*
* @return bool
*/
public function exists($property)
{
return property_exists($this->collection, $property);
}
/**
* Finds whether the collection is empty
*
* @return bool
*/
* Finds whether the collection is empty
*
* @return bool
*/
public function isEmpty()
{
return ! (bool) $this->count();
return !(bool)$this->count();
}
/**
* Count all items in collection
*
* @return int
*/
* Count all items in collection
*
* @return int
*/
public function count()
{
return count($this->properties());
}
/**
* Returns all items properties names
*
* @return array
*/
* Returns all items properties names
*
* @return array
*/
public function properties()
{
$properties = [];
@@ -143,10 +143,10 @@ final class Collection
}
/**
* Returns all items values
*
* @return array
*/
* Returns all items values
*
* @return array
*/
public function values()
{
$values = [];

View File

@@ -16,23 +16,23 @@ namespace Hybridauth\Data;
final class Parser
{
/**
* Decodes a string into an object.
*
* This method will first attempt to parse data as a JSON string (since most providers use this format)
* then XML and parse_str.
*
* @param string $raw
*
* @return mixed
*/
* Decodes a string into an object.
*
* This method will first attempt to parse data as a JSON string (since most providers use this format)
* then XML and parse_str.
*
* @param string $raw
*
* @return mixed
*/
public function parse($raw = null)
{
$data = $this->parseJson($raw);
if (! $data) {
if (!$data) {
$data = $this->parseXml($raw);
if (! $data) {
if (!$data) {
$data = $this->parseQueryString($raw);
}
}
@@ -41,12 +41,12 @@ final class Parser
}
/**
* Decodes a JSON string
*
* @param $result
*
* @return mixed
*/
* Decodes a JSON string
*
* @param $result
*
* @return mixed
*/
public function parseJson($result)
{
return json_decode($result);
@@ -68,28 +68,28 @@ final class Parser
libxml_use_internal_errors(false);
if (! $xml) {
if (!$xml) {
return [];
}
$arr = json_decode(json_encode((array) $xml), true);
$arr = json_decode(json_encode((array)$xml), true);
$arr = array($xml->getName() => $arr);
return $arr;
}
/**
* Parses a string into variables
*
* @param $result
*
* @return \StdClass
*/
* Parses a string into variables
*
* @param $result
*
* @return \StdClass
*/
public function parseQueryString($result)
{
parse_str($result, $output);
if (! is_array($output)) {
if (!is_array($output)) {
return $result;
}
@@ -114,6 +114,6 @@ final class Parser
{
$birthday = date_parse($birthday);
return [ $birthday['year'], $birthday['month'], $birthday['day'] ];
return [$birthday['year'], $birthday['month'], $birthday['day']];
}
}

View File

@@ -13,21 +13,21 @@ namespace Hybridauth\Exception;
class Exception extends \Exception implements ExceptionInterface
{
/**
* Shamelessly Borrowed from Slimframework
*
* @param $object
*/
* Shamelessly Borrowed from Slimframework
*
* @param $object
*/
public function debug($object)
{
$title = 'Hybridauth Exception';
$code = $this->getCode();
$title = 'Hybridauth Exception';
$code = $this->getCode();
$message = $this->getMessage();
$file = $this->getFile();
$line = $this->getLine();
$trace = $this->getTraceAsString();
$file = $this->getFile();
$line = $this->getLine();
$trace = $this->getTraceAsString();
$html = sprintf('<h1>%s</h1>', $title);
$html .= '<p>HybridAuth has encountered the following error:</p>';
$html = sprintf('<h1>%s</h1>', $title);
$html .= '<p>Hybridauth has encountered the following error:</p>';
$html .= '<h2>Details</h2>';
$html .= sprintf('<div><strong>Exception:</strong> %s</div>', get_class($this));

View File

@@ -8,103 +8,103 @@
namespace Hybridauth\HttpClient;
/**
* HybridAuth default Http client
* Hybridauth default Http client
*/
class Curl implements HttpClientInterface
{
/**
* Default curl options
*
* These defaults options can be overwritten when sending requests.
*
* See setCurlOptions()
*
* @var array
*/
* Default curl options
*
* These defaults options can be overwritten when sending requests.
*
* See setCurlOptions()
*
* @var array
*/
protected $curlOptions = [
CURLOPT_TIMEOUT => 30,
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLINFO_HEADER_OUT => true,
CURLOPT_ENCODING => 'identity',
CURLOPT_MAXREDIRS => 5,
CURLINFO_HEADER_OUT => true,
CURLOPT_ENCODING => 'identity',
// phpcs:ignore
CURLOPT_USERAGENT => 'HybridAuth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)',
CURLOPT_USERAGENT => 'Hybridauth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)',
];
/**
* Method request() arguments
*
* This is used for debugging.
*
* @var array
*/
* Method request() arguments
*
* This is used for debugging.
*
* @var array
*/
protected $requestArguments = [];
/**
* Default request headers
*
* @var array
*/
* Default request headers
*
* @var array
*/
protected $requestHeader = [
'Accept' => '*/*',
'Cache-Control' => 'max-age=0',
'Connection' => 'keep-alive',
'Expect' => '',
'Pragma' => '',
'Accept' => '*/*',
'Cache-Control' => 'max-age=0',
'Connection' => 'keep-alive',
'Expect' => '',
'Pragma' => '',
];
/**
* Raw response returned by server
*
* @var string
*/
* Raw response returned by server
*
* @var string
*/
protected $responseBody = '';
/**
* Headers returned in the response
*
* @var array
*/
* Headers returned in the response
*
* @var array
*/
protected $responseHeader = [];
/**
* Response HTTP status code
*
* @var integer
*/
* Response HTTP status code
*
* @var int
*/
protected $responseHttpCode = 0;
/**
* Last curl error number
*
* @var mixed
*/
* Last curl error number
*
* @var mixed
*/
protected $responseClientError = null;
/**
* Information about the last transfer
*
* @var mixed
*/
* Information about the last transfer
*
* @var mixed
*/
protected $responseClientInfo = [];
/**
* Hybridauth logger instance
*
* @var object
*/
* Hybridauth logger instance
*
* @var object
*/
protected $logger = null;
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
$this->requestHeader = array_replace($this->requestHeader, (array) $headers);
$this->requestHeader = array_replace($this->requestHeader, (array)$headers);
$this->requestArguments = [
'uri' => $uri,
@@ -145,9 +145,9 @@ class Curl implements HttpClientInterface
break;
}
$this->curlOptions[CURLOPT_URL] = $uri;
$this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders();
$this->curlOptions[CURLOPT_HEADERFUNCTION] = [ $this, 'fetchResponseHeader' ];
$this->curlOptions[CURLOPT_URL] = $uri;
$this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders();
$this->curlOptions[CURLOPT_HEADERFUNCTION] = [$this, 'fetchResponseHeader'];
foreach ($this->curlOptions as $opt => $value) {
curl_setopt($curl, $opt, $value);
@@ -155,10 +155,10 @@ class Curl implements HttpClientInterface
$response = curl_exec($curl);
$this->responseBody = $response;
$this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$this->responseBody = $response;
$this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$this->responseClientError = curl_error($curl);
$this->responseClientInfo = curl_getinfo($curl);
$this->responseClientInfo = curl_getinfo($curl);
if ($this->logger) {
// phpcs:ignore
@@ -176,8 +176,8 @@ class Curl implements HttpClientInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponse()
{
$curlOptions = $this->curlOptions;
@@ -187,126 +187,126 @@ class Curl implements HttpClientInterface
return [
'request' => $this->getRequestArguments(),
'response' => [
'code' => $this->getResponseHttpCode(),
'code' => $this->getResponseHttpCode(),
'headers' => $this->getResponseHeader(),
'body' => $this->getResponseBody(),
'body' => $this->getResponseBody(),
],
'client' => [
'error' => $this->getResponseClientError(),
'info' => $this->getResponseClientInfo(),
'opts' => $curlOptions,
'info' => $this->getResponseClientInfo(),
'opts' => $curlOptions,
],
];
}
/**
* Reset curl options
*
* @param array $curlOptions
*/
* Reset curl options
*
* @param array $curlOptions
*/
public function setCurlOptions($curlOptions)
{
foreach ($curlOptions as $opt => $value) {
$this->curlOptions[ $opt ] = $value;
$this->curlOptions[$opt] = $value;
}
}
/**
* Set logger instance
*
* @param object $logger
*/
* Set logger instance
*
* @param object $logger
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseBody()
{
return $this->responseBody;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseHeader()
{
return $this->responseHeader;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseHttpCode()
{
return $this->responseHttpCode;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseClientError()
{
return $this->responseClientError;
}
/**
* @return array
*/
* @return array
*/
protected function getResponseClientInfo()
{
return $this->responseClientInfo;
}
/**
* Returns method request() arguments
*
* This is used for debugging.
*
* @return array
*/
* Returns method request() arguments
*
* This is used for debugging.
*
* @return array
*/
protected function getRequestArguments()
{
return $this->requestArguments;
}
/**
* Fetch server response headers
*
* @param mixed $curl
* @param string $header
*
* @return integer
*/
* Fetch server response headers
*
* @param mixed $curl
* @param string $header
*
* @return int
*/
protected function fetchResponseHeader($curl, $header)
{
$pos = strpos($header, ':');
if (! empty($pos)) {
$key = str_replace('-', '_', strtolower(substr($header, 0, $pos)));
if (!empty($pos)) {
$key = str_replace('-', '_', strtolower(substr($header, 0, $pos)));
$value = trim(substr($header, $pos + 2));
$this->responseHeader[ $key ] = $value;
$this->responseHeader[$key] = $value;
}
return strlen($header);
}
/**
* Convert request headers to the expect curl format
*
* @return array
*/
* Convert request headers to the expect curl format
*
* @return array
*/
protected function prepareRequestHeaders()
{
$headers = [];
foreach ($this->requestHeader as $header => $value) {
$headers[] = trim($header) .': '. trim($value);
$headers[] = trim($header) . ': ' . trim($value);
}
return $headers;

View File

@@ -13,20 +13,20 @@ use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Exception\TransferException;
/**
* HybridAuth Guzzle Http client
* Hybridauth Guzzle Http client
*
* Note: This is just a proof of concept. Feel free to improve it.
*
* Example:
*
* <code>
* $guzzle = new Hybridauth\HttpClient\Guzzle( new GuzzleHttp\Client(), [
* 'verify' => '/path/to/your/certificate.crt',
* 'headers' => [ 'User-Agent' => '..' ]
* $guzzle = new Hybridauth\HttpClient\Guzzle(new GuzzleHttp\Client(), [
* 'verify' => '/path/to/your/certificate.crt',
* 'headers' => ['User-Agent' => '..']
* // 'proxy' => ...
* ]);
*
* $adapter = new Hybridauth\Provider\Github( $config, $guzzle );
* $adapter = new Hybridauth\Provider\Github($config, $guzzle);
*
* $adapter->authenticate();
* </code>
@@ -34,73 +34,73 @@ use GuzzleHttp\Exception\TransferException;
class Guzzle implements HttpClientInterface
{
/**
* Method request() arguments
*
* This is used for debugging.
*
* @var array
*/
* Method request() arguments
*
* This is used for debugging.
*
* @var array
*/
protected $requestArguments = [];
/**
* Default request headers
*
* @var array
*/
* Default request headers
*
* @var array
*/
protected $requestHeader = [];
/**
* Raw response returned by server
*
* @var string
*/
* Raw response returned by server
*
* @var string
*/
protected $responseBody = '';
/**
* Headers returned in the response
*
* @var array
*/
* Headers returned in the response
*
* @var array
*/
protected $responseHeader = [];
/**
* Response HTTP status code
*
* @var integer
*/
* Response HTTP status code
*
* @var int
*/
protected $responseHttpCode = 0;
/**
* Last curl error number
*
* @var mixed
*/
* Last curl error number
*
* @var mixed
*/
protected $responseClientError = null;
/**
* Information about the last transfer
*
* @var mixed
*/
* Information about the last transfer
*
* @var mixed
*/
protected $responseClientInfo = [];
/**
* Hybridauth logger instance
*
* @var object
*/
* Hybridauth logger instance
*
* @var object
*/
protected $logger = null;
/**
* GuzzleHttp client
*
* @var \GuzzleHttp\Client
*/
* GuzzleHttp client
*
* @var \GuzzleHttp\Client
*/
protected $client = null;
/**
* ..
* @param null $client
* @param null $client
* @param array $config
*/
public function __construct($client = null, $config = [])
@@ -109,11 +109,11 @@ class Guzzle implements HttpClientInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
$this->requestHeader = array_replace($this->requestHeader, (array) $headers);
$this->requestHeader = array_replace($this->requestHeader, (array)$headers);
$this->requestArguments = [
'uri' => $uri,
@@ -129,8 +129,8 @@ class Guzzle implements HttpClientInterface
case 'GET':
case 'DELETE':
$response = $this->client->request($method, $uri, [
'query' => $parameters,
'headers' => $this->requestHeader,
'query' => $parameters,
'headers' => $this->requestHeader,
]);
break;
case 'PUT':
@@ -171,9 +171,9 @@ class Guzzle implements HttpClientInterface
}
if (!$this->responseClientError) {
$this->responseBody = $response->getBody();
$this->responseBody = $response->getBody();
$this->responseHttpCode = $response->getStatusCode();
$this->responseHeader = $response->getHeaders();
$this->responseHeader = $response->getHeaders();
}
if ($this->logger) {
@@ -190,82 +190,82 @@ class Guzzle implements HttpClientInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponse()
{
return [
'request' => $this->getRequestArguments(),
'response' => [
'code' => $this->getResponseHttpCode(),
'code' => $this->getResponseHttpCode(),
'headers' => $this->getResponseHeader(),
'body' => $this->getResponseBody(),
'body' => $this->getResponseBody(),
],
'client' => [
'error' => $this->getResponseClientError(),
'info' => $this->getResponseClientInfo(),
'opts' => null,
'info' => $this->getResponseClientInfo(),
'opts' => null,
],
];
}
/**
* Set logger instance
*
* @param object $logger
*/
* Set logger instance
*
* @param object $logger
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseBody()
{
return $this->responseBody;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseHeader()
{
return $this->responseHeader;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseHttpCode()
{
return $this->responseHttpCode;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getResponseClientError()
{
return $this->responseClientError;
}
/**
* @return array
*/
* @return array
*/
protected function getResponseClientInfo()
{
return $this->responseClientInfo;
}
/**
* Returns method request() arguments
*
* This is used for debugging.
*
* @return array
*/
* Returns method request() arguments
*
* This is used for debugging.
*
* @return array
*/
protected function getRequestArguments()
{
return $this->requestArguments;

View File

@@ -8,51 +8,51 @@
namespace Hybridauth\HttpClient;
/**
* HybridAuth Http clients interface
* Hybridauth Http clients interface
*/
interface HttpClientInterface
{
/**
* Send request to the remote server
*
* Returns the result (Raw response from the server) on success, FALSE on failure
*
* @param string $uri
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
*/
* Send request to the remote server
*
* Returns the result (Raw response from the server) on success, FALSE on failure
*
* @param string $uri
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
*/
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
/**
* Returns raw response from the server on success, FALSE on failure
*
* @return mixed
*/
* Returns raw response from the server on success, FALSE on failure
*
* @return mixed
*/
public function getResponseBody();
/**
* Retriever the headers returned in the response
*
* @return array
*/
* Retriever the headers returned in the response
*
* @return array
*/
public function getResponseHeader();
/**
* Returns latest request HTTP status code
*
* @return integer
*/
* Returns latest request HTTP status code
*
* @return int
*/
public function getResponseHttpCode();
/**
* Returns latest error encountered by the client
* This can be either a code or error message
*
* @return mixed
*/
* Returns latest error encountered by the client
* This can be either a code or error message
*
* @return mixed
*/
public function getResponseClientError();
}

View File

@@ -15,17 +15,17 @@ use Hybridauth\Data;
class Util
{
/**
* Redirect handler.
*
* @var callable|null
*/
* Redirect handler.
*
* @var callable|null
*/
protected static $redirectHandler;
/**
* Exit handler.
*
* @var callable|null
*/
* Exit handler.
*
* @var callable|null
*/
protected static $exitHandler;
/**
@@ -56,32 +56,32 @@ class Util
}
/**
* Redirect handler to which the regular redirect() will yield the action of redirecting users.
*
* @param callable $callback
*/
* Redirect handler to which the regular redirect() will yield the action of redirecting users.
*
* @param callable $callback
*/
public static function setRedirectHandler($callback)
{
self::$redirectHandler = $callback;
}
/**
* Exit handler will be called instead of regular exit() when calling Util::redirect() method.
*
* @param callable $callback
*/
* Exit handler will be called instead of regular exit() when calling Util::redirect() method.
*
* @param callable $callback
*/
public static function setExitHandler($callback)
{
self::$exitHandler = $callback;
}
/**
* Returns the Current URL.
*
* @param bool $requestUri TRUE to use $_SERVER['REQUEST_URI'], FALSE for $_SERVER['PHP_SELF']
*
* @return string
*/
* Returns the Current URL.
*
* @param bool $requestUri TRUE to use $_SERVER['REQUEST_URI'], FALSE for $_SERVER['PHP_SELF']
*
* @return string
*/
public static function getCurrentUrl($requestUri = false)
{
$collection = new Data\Collection($_SERVER);
@@ -93,8 +93,8 @@ class Util
$protocol = 'https://';
}
return $protocol.
$collection->get('HTTP_HOST').
$collection->get($requestUri ? 'REQUEST_URI' : 'PHP_SELF');
return $protocol .
$collection->get('HTTP_HOST') .
$collection->get($requestUri ? 'REQUEST_URI' : 'PHP_SELF');
}
}

View File

@@ -25,41 +25,41 @@ use Hybridauth\HttpClient\HttpClientInterface;
class Hybridauth
{
/**
* Hybridauth config.
*
* @var array
*/
* Hybridauth config.
*
* @var array
*/
protected $config;
/**
* Storage.
*
* @var StorageInterface
*/
* Storage.
*
* @var StorageInterface
*/
protected $storage;
/**
* HttpClient.
*
* @var HttpClientInterface
*/
* HttpClient.
*
* @var HttpClientInterface
*/
protected $httpClient;
/**
* Logger.
*
* @var LoggerInterface
*/
* Logger.
*
* @var LoggerInterface
*/
protected $logger;
/**
* @param array|string $config Array with configuration or Path to PHP file that will return array
* @param HttpClientInterface $httpClient
* @param StorageInterface $storage
* @param LoggerInterface $logger
*
* @throws InvalidArgumentException
*/
* @param array|string $config Array with configuration or Path to PHP file that will return array
* @param HttpClientInterface $httpClient
* @param StorageInterface $storage
* @param LoggerInterface $logger
*
* @throws InvalidArgumentException
*/
public function __construct(
$config,
HttpClientInterface $httpClient = null,
@@ -68,34 +68,34 @@ class Hybridauth
) {
if (is_string($config) && file_exists($config)) {
$config = include $config;
} elseif (! is_array($config)) {
} elseif (!is_array($config)) {
throw new InvalidArgumentException('Hybridauth config does not exist on the given path.');
}
$this->config = $config + [
'debug_mode' => Logger::NONE,
'debug_file' => '',
'curl_options' => null,
'providers' => []
];
'debug_mode' => Logger::NONE,
'debug_file' => '',
'curl_options' => null,
'providers' => []
];
$this->storage = $storage;
$this->logger = $logger;
$this->httpClient = $httpClient;
}
/**
* Instantiate the given provider and authentication or authorization protocol.
*
* If not authenticated yet, the user will be redirected to the provider's site for
* authentication/authorisation, otherwise it will simply return an instance of
* provider's adapter.
*
* @param string $name adapter's name (case insensitive)
*
* @return \Hybridauth\Adapter\AdapterInterface
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
* Instantiate the given provider and authentication or authorization protocol.
*
* If not authenticated yet, the user will be redirected to the provider's site for
* authentication/authorisation, otherwise it will simply return an instance of
* provider's adapter.
*
* @param string $name adapter's name (case insensitive)
*
* @return \Hybridauth\Adapter\AdapterInterface
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function authenticate($name)
{
$adapter = $this->getAdapter($name);
@@ -106,14 +106,14 @@ class Hybridauth
}
/**
* Returns a new instance of a provider's adapter by name
*
* @param string $name adapter's name (case insensitive)
*
* @return \Hybridauth\Adapter\AdapterInterface
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
* Returns a new instance of a provider's adapter by name
*
* @param string $name adapter's name (case insensitive)
*
* @return \Hybridauth\Adapter\AdapterInterface
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function getAdapter($name)
{
$config = $this->getProviderConfig($name);
@@ -142,26 +142,26 @@ class Hybridauth
}
/**
* Get provider config by name.
*
* @param string $name adapter's name (case insensitive)
*
* @throws UnexpectedValueException
* @throws InvalidArgumentException
*
* @return array
*/
* Get provider config by name.
*
* @param string $name adapter's name (case insensitive)
*
* @throws UnexpectedValueException
* @throws InvalidArgumentException
*
* @return array
*/
public function getProviderConfig($name)
{
$name = strtolower($name);
$providersConfig = array_change_key_case($this->config['providers'], CASE_LOWER);
if (! isset($providersConfig[$name])) {
if (!isset($providersConfig[$name])) {
throw new InvalidArgumentException('Unknown Provider.');
}
if (! $providersConfig[$name]['enabled']) {
if (!$providersConfig[$name]['enabled']) {
throw new UnexpectedValueException('Disabled Provider.');
}
@@ -171,7 +171,7 @@ class Hybridauth
'debug_file' => $this->config['debug_file'],
];
if (! isset($config['callback']) && isset($this->config['callback'])) {
if (!isset($config['callback']) && isset($this->config['callback'])) {
$config['callback'] = $this->config['callback'];
}
@@ -179,24 +179,24 @@ class Hybridauth
}
/**
* Returns a boolean of whether the user is connected with a provider
*
* @param string $name adapter's name (case insensitive)
*
* @return boolean
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
* Returns a boolean of whether the user is connected with a provider
*
* @param string $name adapter's name (case insensitive)
*
* @return bool
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function isConnectedWith($name)
{
return $this->getAdapter($name)->isConnected();
}
/**
* Returns a list of enabled adapters names
*
* @return array
*/
* Returns a list of enabled adapters names
*
* @return array
*/
public function getProviders()
{
$providers = [];
@@ -211,19 +211,19 @@ class Hybridauth
}
/**
* Returns a list of currently connected adapters names
*
* @return array
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
* Returns a list of currently connected adapters names
*
* @return array
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function getConnectedProviders()
{
$providers = [];
foreach ($this->getProviders() as $name) {
if ($this->isConnectedWith($name)) {
$providers[] = $name;
$providers[] = $name;
}
}
@@ -231,12 +231,12 @@ class Hybridauth
}
/**
* Returns a list of new instances of currently connected adapters
*
* @return \Hybridauth\Adapter\AdapterInterface[]
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
* Returns a list of new instances of currently connected adapters
*
* @return \Hybridauth\Adapter\AdapterInterface[]
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function getConnectedAdapters()
{
$adapters = [];
@@ -253,8 +253,8 @@ class Hybridauth
}
/**
* Disconnect all currently connected adapters at once
*/
* Disconnect all currently connected adapters at once
*/
public function disconnectAllAdapters()
{
foreach ($this->getProviders() as $name) {

View File

@@ -15,9 +15,9 @@ use Hybridauth\Exception\InvalidArgumentException;
*/
class Logger implements LoggerInterface
{
const NONE = 'none'; // turn logging off
const NONE = 'none'; // turn logging off
const DEBUG = 'debug'; // debug, info and error messages
const INFO = 'info'; // info and error messages
const INFO = 'info'; // info and error messages
const ERROR = 'error'; // only error messages
/**
@@ -38,7 +38,7 @@ class Logger implements LoggerInterface
/**
* @param bool|string $level One of Logger::NONE, Logger::DEBUG, Logger::INFO, Logger::ERROR
* @param string $file File where to write messages
* @param string $file File where to write messages
*
* @throws InvalidArgumentException
* @throws RuntimeException
@@ -50,7 +50,7 @@ class Logger implements LoggerInterface
if ($level && $level !== self::NONE) {
$this->initialize($file);
$this->level = $level === true ? Logger::DEBUG : $level;
$this->level = $level === true ? Logger::DEBUG : $level;
$this->file = $file;
}
}
@@ -121,7 +121,7 @@ class Logger implements LoggerInterface
$datetime = $datetime->format(DATE_ATOM);
$content = sprintf('%s -- %s -- %s -- %s', $level, $_SERVER['REMOTE_ADDR'], $datetime, $message);
$content .= ($context ? "\n".print_r($context, true) : '');
$content .= ($context ? "\n" . print_r($context, true) : '');
$content .= "\n";
file_put_contents($this->file, $content, FILE_APPEND);

View File

@@ -18,7 +18,7 @@ interface LoggerInterface
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @param array $context
*/
public function info($message, array $context = array());
@@ -26,7 +26,7 @@ interface LoggerInterface
* Detailed debug information.
*
* @param string $message
* @param array $context
* @param array $context
*/
public function debug($message, array $context = array());
@@ -35,16 +35,16 @@ interface LoggerInterface
* be logged and monitored.
*
* @param string $message
* @param array $context
* @param array $context
*/
public function error($message, array $context = array());
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param mixed $level
* @param string $message
* @param array $context
* @param array $context
*/
public function log($level, $message, array $context = array());
}

View File

@@ -7,15 +7,20 @@
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID as OpenIDAdapter;
use Hybridauth\Adapter\OpenID;
/**
* AOL OpenID provider adapter.
*/
class AOLOpenID extends OpenIDAdapter
class AOLOpenID extends OpenID
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $openidIdentifier = 'http://openid.aol.com/';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
}

View File

@@ -20,7 +20,7 @@ class Amazon extends OAuth2
/**
* {@inheritdoc}
*/
public $scope = 'profile';
protected $scope = 'profile';
/**
* {@inheritdoc}
@@ -57,9 +57,9 @@ class Amazon extends OAuth2
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('user_id');
$userProfile->identifier = $data->get('user_id');
$userProfile->displayName = $data->get('name');
$userProfile->email = $data->get('email');
$userProfile->email = $data->get('email');
return $userProfile;
}

View File

@@ -18,33 +18,33 @@ use Hybridauth\User;
class Authentiq extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'aq:name email~rs aq:push openid';
* {@inheritdoc}
*/
protected $scope = 'aq:name email~rs aq:push openid';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://connect.authentiq.io/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://connect.authentiq.io/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://connect.authentiq.io/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'http://developers.authentiq.io/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
@@ -54,26 +54,17 @@ class Authentiq extends OAuth2
];
$this->tokenExchangeHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
$this->tokenRefreshHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
}
/**
* {@inheritdoc}
*
* Disable functionality as Authentiq Provider doesn't support this yet
*/
public function refreshAccessToken($parameters = [])
{
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('userinfo');
@@ -81,39 +72,39 @@ class Authentiq extends OAuth2
$data = new Data\Collection($response);
if (!$data->exists('sub')) {
throw new UnexpectedValueException('Provider API returned an unexpected response.');
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('sub');
$userProfile->identifier = $data->get('sub');
$userProfile->displayName = $data->get('name');
$userProfile->firstName = $data->get('given_name');
$userProfile->firstName = $data->get('given_name');
// $userProfile->middleName = $data->get('middle_name'); // not supported
$userProfile->lastName = $data->get('family_name');
$userProfile->lastName = $data->get('family_name');
if (!empty($userProfile->displayName)) {
$userProfile->displayName = join(' ', array($userProfile->firstName,
// $userProfile->middleName,
$userProfile->lastName));
// $userProfile->middleName,
$userProfile->lastName));
}
$userProfile->email = $data->get('email');
$userProfile->email = $data->get('email');
$userProfile->emailVerified = $data->get('email_verified') ? $userProfile->email : '';
$userProfile->phone = $data->get('phone');
$userProfile->phone = $data->get('phone');
// $userProfile->phoneVerified = $data->get('phone_verified') ? $userProfile->phone : ''; // not supported
$userProfile->profileURL = $data->get('profile');
$userProfile->webSiteURL = $data->get('website');
$userProfile->photoURL = $data->get('picture');
$userProfile->gender = $data->get('gender');
$userProfile->address = $data->filter('address')->get('street_address');
$userProfile->city = $data->filter('address')->get('locality');
$userProfile->country = $data->filter('address')->get('country');
$userProfile->region = $data->filter('address')->get('region');
$userProfile->zip = $data->filter('address')->get('postal_code');
$userProfile->profileURL = $data->get('profile');
$userProfile->webSiteURL = $data->get('website');
$userProfile->photoURL = $data->get('picture');
$userProfile->gender = $data->get('gender');
$userProfile->address = $data->filter('address')->get('street_address');
$userProfile->city = $data->filter('address')->get('locality');
$userProfile->country = $data->filter('address')->get('country');
$userProfile->region = $data->filter('address')->get('region');
$userProfile->zip = $data->filter('address')->get('postal_code');
return $userProfile;
}

View File

@@ -12,62 +12,67 @@ use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Set up your OAuth2 at https://bitbucket.org/<yourusername>/workspace/settings/api
*/
/**
* BitBucket OAuth2 provider adapter.
*/
class BitBucket extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'email';
* {@inheritdoc}
*/
protected $scope = 'email';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.bitbucket.org/2.0/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://bitbucket.org/site/oauth2/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://bitbucket.org/site/oauth2/access_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.atlassian.com/bitbucket/concepts/oauth2.html';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('user');
$data = new Data\Collection($response);
if (! $data->exists('uuid')) {
if (!$data->exists('uuid')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('uuid');
$userProfile->identifier = $data->get('uuid');
$userProfile->profileURL = 'https://bitbucket.org/' . $data->get('username') . '/';
$userProfile->displayName = $data->get('display_name');
$userProfile->email = $data->get('email');
$userProfile->webSiteURL = $data->get('website');
$userProfile->region = $data->get('location');
$userProfile->email = $data->get('email');
$userProfile->webSiteURL = $data->get('website');
$userProfile->region = $data->get('location');
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');
if (empty($userProfile->email) && strpos($this->scope, 'email') !== false) {
try {
// user email is not mandatory so keep it quite
// user email is not mandatory so keep it quiet
$userProfile = $this->requestUserEmail($userProfile);
} catch (\Exception $e) {
}
@@ -90,10 +95,10 @@ class BitBucket extends OAuth2
$response = $this->apiRequest('user/emails');
foreach ($response->values as $idx => $item) {
if (! empty($item->is_primary) && $item->is_primary == true) {
if (!empty($item->is_primary) && $item->is_primary == true) {
$userProfile->email = $item->email;
if (! empty($item->is_confirmed) && $item->is_confirmed == true) {
if (!empty($item->is_confirmed) && $item->is_confirmed == true) {
$userProfile->emailVerified = $userProfile->email;
}

View File

@@ -20,7 +20,7 @@ class Blizzard extends OAuth2
/**
* {@inheritdoc}
*/
public $scope = '';
protected $scope = '';
/**
* {@inheritdoc}
@@ -57,7 +57,7 @@ class Blizzard extends OAuth2
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('battletag') ?: $data->get('login');
return $userProfile;

View File

@@ -17,11 +17,10 @@ use Hybridauth\User;
*/
class Discord extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'identify email';
protected $scope = 'identify email';
/**
* {@inheritdoc}
@@ -50,10 +49,12 @@ class Discord extends OAuth2
{
parent::initialize();
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**

View File

@@ -18,33 +18,33 @@ use Hybridauth\User;
class Disqus extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $scope = 'read,email';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://disqus.com/api/3.0/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://disqus.com/api/oauth/2.0/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://disqus.com/api/oauth/2.0/access_token/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://disqus.com/api/docs/auth/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
@@ -55,15 +55,15 @@ class Disqus extends OAuth2
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('users/details');
$data = new Data\Collection($response);
if (! $data->filter('response')->exists('id')) {
if (!$data->filter('response')->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -71,15 +71,15 @@ class Disqus extends OAuth2
$data = $data->filter('response');
$userProfile->identifier = $data->get('id');
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('name');
$userProfile->description = $data->get('bio');
$userProfile->profileURL = $data->get('profileUrl');
$userProfile->email = $data->get('email');
$userProfile->region = $data->get('location');
$userProfile->profileURL = $data->get('profileUrl');
$userProfile->email = $data->get('email');
$userProfile->region = $data->get('location');
$userProfile->description = $data->get('about');
$userProfile->photoURL = $data->filter('avatar')->get('permalink');
$userProfile->photoURL = $data->filter('avatar')->get('permalink');
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');

View File

@@ -18,50 +18,50 @@ use Hybridauth\User;
class Dribbble extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.dribbble.com/v2/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://dribbble.com/oauth/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://dribbble.com/oauth/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'http://developer.dribbble.com/v2/oauth/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('user');
$data = new Data\Collection($response);
if (! $data->exists('id')) {
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->profileURL = $data->get('html_url');
$userProfile->photoURL = $data->get('avatar_url');
$userProfile->identifier = $data->get('id');
$userProfile->profileURL = $data->get('html_url');
$userProfile->photoURL = $data->get('avatar_url');
$userProfile->description = $data->get('bio');
$userProfile->region = $data->get('location');
$userProfile->region = $data->get('location');
$userProfile->displayName = $data->get('name');
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');
$userProfile->webSiteURL = $data->filter('links')->get('web');
$userProfile->webSiteURL = $data->filter('links')->get('web');
return $userProfile;
}

View File

@@ -16,15 +16,22 @@ use Hybridauth\User;
/**
* Facebook OAuth2 provider adapter.
*
* Facebook doesn't use standard OAuth refresh tokens.
* Instead it has a "token exchange" system. You exchange the token prior to
* expiry, to push back expiry. You start with a short-lived token and each
* exchange gives you a long-lived one (90 days).
* We control this with the 'exchange_by_expiry_days' option.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [ 'id' => '', 'secret' => '' ],
* 'scope' => 'email, user_status, user_posts'
* 'keys' => ['id' => '', 'secret' => ''],
* 'scope' => 'email, user_status, user_posts',
* 'exchange_by_expiry_days' => 45, // null for no token exchange
* ];
*
* $adapter = new Hybridauth\Provider\Facebook( $config );
* $adapter = new Hybridauth\Provider\Facebook($config);
*
* try {
* $adapter->authenticate();
@@ -32,8 +39,7 @@ use Hybridauth\User;
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* $response = $adapter->setUserStatus("Hybridauth test message..");
* }
* catch( Exception $e ){
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
@@ -47,7 +53,7 @@ class Facebook extends OAuth2
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://graph.facebook.com/v6.0/';
protected $apiBaseUrl = 'https://graph.facebook.com/v8.0/';
/**
* {@inheritdoc}
@@ -83,6 +89,53 @@ class Facebook extends OAuth2
}
}
/**
* {@inheritdoc}
*/
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
// Handle token exchange prior to the standard handler for an API request
$exchange_by_expiry_days = $this->config->get('exchange_by_expiry_days') ?: 45;
if ($exchange_by_expiry_days !== null) {
$projected_timestamp = time() + 60 * 60 * 24 * $exchange_by_expiry_days;
if (!$this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
$this->exchangeAccessToken();
}
}
return parent::apiRequest($url, $method, $parameters, $headers, $multipart);
}
/**
* Exchange the Access Token with one that expires further in the future.
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
public function exchangeAccessToken()
{
$exchangeTokenParameters = [
'grant_type' => 'fb_exchange_token',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'fb_exchange_token' => $this->getStoredData('access_token'),
];
$response = $this->httpClient->request(
$this->accessTokenUrl,
'GET',
$exchangeTokenParameters
);
$this->validateApiResponse('Unable to exchange the access token');
$this->validateAccessTokenExchange($response);
return $response;
}
/**
* {@inheritdoc}
*/
@@ -93,16 +146,28 @@ class Facebook extends OAuth2
'name',
'first_name',
'last_name',
'link',
'website',
'gender',
'locale',
'about',
'email',
'hometown',
'birthday',
];
$response = $this->apiRequest('me?fields=' . implode(',', $fields));
if (strpos($this->scope, 'user_link') !== false) {
$fields[] = 'link';
}
if (strpos($this->scope, 'user_gender') !== false) {
$fields[] = 'gender';
}
// Note that en_US is needed for gender fields to match convention.
$locale = $this->config->get('locale') ?: 'en_US';
$response = $this->apiRequest('me', 'GET', [
'fields' => implode(',', $fields),
'locale' => $locale,
]);
$data = new Data\Collection($response);
@@ -279,8 +344,8 @@ class Facebook extends OAuth2
// Refresh proof for API call.
$parameters = $status + [
'appsecret_proof' => hash_hmac('sha256', $page->access_token, $this->clientSecret),
];
'appsecret_proof' => hash_hmac('sha256', $page->access_token, $this->clientSecret),
];
$response = $this->apiRequest("{$pageId}/feed", 'POST', $parameters, $headers);

View File

@@ -18,33 +18,33 @@ use Hybridauth\User;
class Foursquare extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.foursquare.com/v2/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://foursquare.com/oauth2/authenticate';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://foursquare.com/oauth2/access_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenName = 'oauth_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.foursquare.com/overview/auth';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
@@ -58,15 +58,15 @@ class Foursquare extends OAuth2
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('users/self');
$data = new Data\Collection($response);
if (! $data->exists('response')) {
if (!$data->exists('response')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -74,15 +74,15 @@ class Foursquare extends OAuth2
$data = $data->filter('response')->filter('user');
$userProfile->identifier = $data->get('id');
$userProfile->firstName = $data->get('firstName');
$userProfile->lastName = $data->get('lastName');
$userProfile->gender = $data->get('gender');
$userProfile->city = $data->get('homeCity');
$userProfile->email = $data->filter('contact')->get('email');
$userProfile->identifier = $data->get('id');
$userProfile->firstName = $data->get('firstName');
$userProfile->lastName = $data->get('lastName');
$userProfile->gender = $data->get('gender');
$userProfile->city = $data->get('homeCity');
$userProfile->email = $data->filter('contact')->get('email');
$userProfile->emailVerified = $userProfile->email;
$userProfile->profileURL = 'https://www.foursquare.com/user/' . $userProfile->identifier;
$userProfile->displayName = trim($userProfile->firstName . ' ' . $userProfile->lastName);
$userProfile->profileURL = 'https://www.foursquare.com/user/' . $userProfile->identifier;
$userProfile->displayName = trim($userProfile->firstName . ' ' . $userProfile->lastName);
if ($data->exists('photo')) {
$photoSize = $this->config->get('photo_size') ?: '150x150';
@@ -95,15 +95,15 @@ class Foursquare extends OAuth2
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserContacts()
{
$response = $this->apiRequest('users/self/friends');
$data = new Data\Collection($response);
if (! $data->exists('response')) {
if (!$data->exists('response')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}

View File

@@ -17,11 +17,10 @@ use Hybridauth\User;
*/
class GitHub extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'user:email';
protected $scope = 'user:email';
/**
* {@inheritdoc}

View File

@@ -18,52 +18,52 @@ use Hybridauth\User;
class GitLab extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'api';
* {@inheritdoc}
*/
protected $scope = 'api';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://gitlab.com/api/v3/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://gitlab.com/oauth/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://gitlab.com/oauth/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://docs.gitlab.com/ee/api/oauth2.html';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('user');
$data = new Data\Collection($response);
if (! $data->exists('id')) {
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('name');
$userProfile->description = $data->get('bio');
$userProfile->photoURL = $data->get('avatar_url');
$userProfile->profileURL = $data->get('web_url');
$userProfile->email = $data->get('email');
$userProfile->webSiteURL = $data->get('website_url');
$userProfile->photoURL = $data->get('avatar_url');
$userProfile->profileURL = $data->get('web_url');
$userProfile->email = $data->get('email');
$userProfile->webSiteURL = $data->get('website_url');
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');

View File

@@ -19,20 +19,20 @@ use Hybridauth\User;
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [ 'id' => '', 'secret' => '' ],
* 'scope' => 'https://www.googleapis.com/auth/userinfo.profile',
* 'keys' => ['id' => '', 'secret' => ''],
* 'scope' => 'https://www.googleapis.com/auth/userinfo.profile',
*
* // google's custom auth url params
* 'authorize_url_parameters' => [
* 'approval_prompt' => 'force', // to pass only when you need to acquire a new refresh token.
* 'access_type' => .., // is set to 'offline' by default
* 'hd' => ..,
* 'state' => ..,
* 'access_type' => .., // is set to 'offline' by default
* 'hd' => ..,
* 'state' => ..,
* // etc.
* ]
* ];
*
* $adapter = new Hybridauth\Provider\Google( $config );
* $adapter = new Hybridauth\Provider\Google($config);
*
* try {
* $adapter->authenticate();
@@ -40,41 +40,41 @@ use Hybridauth\User;
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* $contacts = $adapter->getUserContacts(['max-results' => 75]);
* }
* catch( Exception $e ){
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
class Google extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
* {@inheritdoc}
*/
// phpcs:ignore
protected $scope = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://www.googleapis.com/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://accounts.google.com/o/oauth2/auth';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://accounts.google.com/o/oauth2/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developers.google.com/identity/protocols/OAuth2';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
@@ -83,38 +83,40 @@ class Google extends OAuth2
'access_type' => 'offline'
];
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret
];
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret
];
}
}
/**
* {@inheritdoc}
*
* See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo
*/
* {@inheritdoc}
*
* See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo
*/
public function getUserProfile()
{
$response = $this->apiRequest('oauth2/v3/userinfo');
$data = new Data\Collection($response);
if (! $data->exists('sub')) {
if (!$data->exists('sub')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('sub');
$userProfile->firstName = $data->get('given_name');
$userProfile->lastName = $data->get('family_name');
$userProfile->identifier = $data->get('sub');
$userProfile->firstName = $data->get('given_name');
$userProfile->lastName = $data->get('family_name');
$userProfile->displayName = $data->get('name');
$userProfile->photoURL = $data->get('picture');
$userProfile->profileURL = $data->get('profile');
$userProfile->gender = $data->get('gender');
$userProfile->language = $data->get('locale');
$userProfile->email = $data->get('email');
$userProfile->photoURL = $data->get('picture');
$userProfile->profileURL = $data->get('profile');
$userProfile->gender = $data->get('gender');
$userProfile->language = $data->get('locale');
$userProfile->email = $data->get('email');
$userProfile->emailVerified = $data->get('email_verified') ? $userProfile->email : '';
@@ -126,8 +128,8 @@ class Google extends OAuth2
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserContacts($parameters = [])
{
$parameters = ['max-results' => 500] + $parameters;
@@ -152,11 +154,11 @@ class Google extends OAuth2
protected function getGmailContacts($parameters = [])
{
$url = 'https://www.google.com/m8/feeds/contacts/default/full?'
. http_build_query(array_replace([ 'alt' => 'json', 'v' => '3.0' ], (array)$parameters));
. http_build_query(array_replace(['alt' => 'json', 'v' => '3.0'], (array)$parameters));
$response = $this->apiRequest($url);
if (! $response) {
if (!$response) {
return [];
}
@@ -167,11 +169,11 @@ class Google extends OAuth2
$uc = new User\Contact();
$uc->email = isset($entry->{'gd$email'}[0]->address)
? (string) $entry->{'gd$email'}[0]->address
: '';
? (string)$entry->{'gd$email'}[0]->address
: '';
$uc->displayName = isset($entry->title->{'$t'}) ? (string) $entry->title->{'$t'} : '';
$uc->identifier = ($uc->email != '') ? $uc->email : '';
$uc->displayName = isset($entry->title->{'$t'}) ? (string)$entry->title->{'$t'} : '';
$uc->identifier = ($uc->email != '') ? $uc->email : '';
$uc->description = '';
if (property_exists($response, 'website')) {

View File

@@ -20,7 +20,7 @@ class LinkedIn extends OAuth2
/**
* {@inheritdoc}
*/
public $scope = 'r_liteprofile r_emailaddress w_member_social';
protected $scope = 'r_liteprofile r_emailaddress w_member_social';
/**
* {@inheritdoc}
@@ -55,8 +55,8 @@ class LinkedIn extends OAuth2
];
$response = $this->apiRequest('me?projection=(' . implode(',', $fields) . ')');
$data = new Data\Collection($response);
$response = $this->apiRequest('me', 'GET', ['projection' => '(' . implode(',', $fields) . ')']);
$data = new Data\Collection($response);
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
@@ -66,14 +66,14 @@ class LinkedIn extends OAuth2
// Handle localized names.
$userProfile->firstName = $data
->filter('firstName')
->filter('localized')
->get($this->getPreferredLocale($data, 'firstName'));
->filter('firstName')
->filter('localized')
->get($this->getPreferredLocale($data, 'firstName'));
$userProfile->lastName = $data
->filter('lastName')
->filter('localized')
->get($this->getPreferredLocale($data, 'lastName'));
->filter('lastName')
->filter('localized')
->get($this->getPreferredLocale($data, 'lastName'));
$userProfile->identifier = $data->get('id');
$userProfile->email = $this->getUserEmail();
@@ -123,8 +123,11 @@ class LinkedIn extends OAuth2
*/
public function getUserEmail()
{
$response = $this->apiRequest('emailAddress?q=members&projection=(elements*(handle~))');
$data = new Data\Collection($response);
$response = $this->apiRequest('emailAddress', 'GET', [
'q' => 'members',
'projection' => '(elements*(handle~))',
]);
$data = new Data\Collection($response);
foreach ($data->filter('elements')->toArray() as $element) {
$item = new Data\Collection($element);
@@ -165,8 +168,8 @@ class LinkedIn extends OAuth2
$headers = [
'Content-Type' => 'application/json',
'x-li-format' => 'json',
'X-Restli-Protocol-Version' => '2.0.0',
'x-li-format' => 'json',
'X-Restli-Protocol-Version' => '2.0.0',
];
$response = $this->apiRequest("ugcPosts", 'POST', $status, $headers);

View File

@@ -13,27 +13,7 @@ use Hybridauth\Data\Collection;
use Hybridauth\User\Profile;
/**
* Mailru provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* ];
*
* $adapter = new Hybridauth\Provider\Mailru($config);
*
* try {
* if (!$adapter->isConnected()) {
* $adapter->authenticate();
* }
*
* $userProfile = $adapter->getUserProfile();
* }
* catch(\Exception $e) {
* print $e->getMessage() ;
* }
* Mailru OAuth2 provider adapter.
*/
class Mailru extends OAuth2
{
@@ -52,6 +32,10 @@ class Mailru extends OAuth2
*/
protected $accessTokenUrl = 'https://connect.mail.ru/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}

View File

@@ -13,14 +13,40 @@ use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\User;
/**
* Microsoft Graph provider adapter.
* Microsoft Graph OAuth2 provider adapter.
*
* Create an "Azure Active Directory" resource at https://portal.azure.com/
* (not from the Visual Studio site).
*
* The "Supported account types" choice maps to the 'tenant' setting, see "Authority" @
* https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-client-application-configuration
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* 'tenant' => 'user',
* // ^ May be 'common', 'organizations' or 'consumers' or a specific tenant ID or a domain
* ];
*
* $adapter = new Hybridauth\Provider\MicrosoftGraph($config);
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
class MicrosoftGraph extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'openid user.read contacts.read';
protected $scope = 'openid user.read contacts.read';
/**
* {@inheritdoc}
@@ -42,6 +68,24 @@ class MicrosoftGraph extends OAuth2
*/
protected $apiDocumentation = 'https://developer.microsoft.com/en-us/graph/docs/concepts/php';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$tenant = $this->config->get('tenant');
if (!empty($tenant)) {
$adjustedEndpoints = [
'authorize_url' => str_replace('/common/', '/' . $tenant . '/', $this->authorizeUrl),
'access_token_url' => str_replace('/common/', '/' . $tenant . '/', $this->accessTokenUrl),
];
$this->setApiEndpoints($adjustedEndpoints);
}
}
/**
* {@inheritdoc}
*/
@@ -57,12 +101,27 @@ class MicrosoftGraph extends OAuth2
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('displayName');
$userProfile->firstName = $data->get('givenName');
$userProfile->lastName = $data->get('surname');
$userProfile->email = $data->get('mail');
$userProfile->language = $data->get('preferredLanguage');
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('displayName');
$userProfile->firstName = $data->get('givenName');
$userProfile->lastName = $data->get('surname');
$userProfile->language = $data->get('preferredLanguage');
$userProfile->phone = $data->get('mobilePhone');
if (empty($userProfile->phone)) {
$businessPhones = $data->get('businessPhones');
if (isset($businessPhones[0])) {
$userProfile->phone = $businessPhones[0];
}
}
$userProfile->email = $data->get('mail');
if (empty($userProfile->email)) {
$email = $data->get('userPrincipalName');
if (strpos($email, '@') !== false) {
$userProfile->email = $email;
}
}
return $userProfile;
}
@@ -72,19 +131,19 @@ class MicrosoftGraph extends OAuth2
*/
public function getUserContacts()
{
$apiUrl = 'me/contacts?$top=50';
$apiUrl = 'me/contacts?$top=50';
$contacts = [];
do {
$response = $this->apiRequest($apiUrl);
$data = new Data\Collection($response);
$data = new Data\Collection($response);
if (!$data->exists('value')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
foreach ($data->filter('value')->toArray() as $entry) {
$entry = new Data\Collection($entry);
$userContact = new User\Contact();
$userContact->identifier = $entry->get('id');
$userContact = new User\Contact();
$userContact->identifier = $entry->get('id');
$userContact->displayName = $entry->get('displayName');
if (!empty($entry->get('emailAddresses'))) {
$userContact->email = $entry->get('emailAddresses')[0]->address;

View File

@@ -18,28 +18,28 @@ use Hybridauth\User;
class ORCID extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $scope = '/authenticate';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://pub.orcid.org/v2.1/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://orcid.org/oauth/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://orcid.org/oauth/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://members.orcid.org/api/';
/**
@@ -53,8 +53,8 @@ class ORCID extends OAuth2
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest($this->getStoredData('orcid') . '/record');
@@ -89,8 +89,8 @@ class ORCID extends OAuth2
{
$data = new Data\Collection($data->get('orcid-identifier'));
$profile->identifier = $data->get('path');
$profile->profileURL = $data->get('uri');
$profile->identifier = $data->get('path');
$profile->profileURL = $data->get('uri');
return $profile;
}
@@ -108,7 +108,7 @@ class ORCID extends OAuth2
$data = new Data\Collection($data->get('person'));
$data = new Data\Collection($data->get('biography'));
$profile->description = $data->get('content');
$profile->description = $data->get('content');
return $profile;
}

View File

@@ -14,65 +14,52 @@ use Hybridauth\User;
/**
* Odnoklassniki OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'key' => '', 'secret' => ''],
* ];
* $adapter = new Hybridauth\Provider\Odnoklassniki($config);
*
* try {
* if (!$adapter->isConnected()) {
* $adapter->authenticate();
* }
*
* $userProfile = $adapter->getUserProfile();
* }
* catch(\Exception $e) {
* print $e->getMessage() ;
* }
*/
class Odnoklassniki extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.ok.ru/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://connect.ok.ru/oauth/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.ok.ru/oauth/token.do';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://apiok.ru/en/ext/oauth/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret
];
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret
];
}
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$fields = array(
'uid', 'locale', 'first_name', 'last_name', 'name', 'gender', 'age', 'birthday',
'has_email', 'current_status', 'current_status_id', 'current_status_date','online',
'has_email', 'current_status', 'current_status_id', 'current_status_date', 'online',
'photo_id', 'pic_1', 'pic_2', 'pic1024x768', 'location', 'email'
);
@@ -84,38 +71,38 @@ class Odnoklassniki extends OAuth2
);
$parameters = [
'access_token' => $this->getStoredData('access_token'),
'access_token' => $this->getStoredData('access_token'),
'application_key' => $this->config->get('keys')['key'],
'method' => 'users.getCurrentUser',
'fields' => implode(',', $fields),
'sig' => $sig,
'method' => 'users.getCurrentUser',
'fields' => implode(',', $fields),
'sig' => $sig,
];
$response = $this->apiRequest('fb.do', 'GET', $parameters);
$data = new Data\Collection($response);
if (! $data->exists('uid')) {
if (!$data->exists('uid')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('uid');
$userProfile->email = $data->get('email');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->identifier = $data->get('uid');
$userProfile->email = $data->get('email');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->displayName = $data->get('name');
$userProfile->photoURL = $data->get('pic1024x768');
$userProfile->profileURL = 'http://ok.ru/profile/' . $data->get('uid');
$userProfile->photoURL = $data->get('pic1024x768');
$userProfile->profileURL = 'http://ok.ru/profile/' . $data->get('uid');
// Handle birthday.
if ($data->get('birthday')) {
$bday = explode('-', $data->get('birthday'));
$userProfile->birthDay = (int)$bday[0];
$bday = explode('-', $data->get('birthday'));
$userProfile->birthDay = (int)$bday[0];
$userProfile->birthMonth = (int)$bday[1];
$userProfile->birthYear = (int)$bday[2];
$userProfile->birthYear = (int)$bday[2];
}
return $userProfile;

View File

@@ -7,7 +7,7 @@
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID as OpenIDAdapter;
use Hybridauth\Adapter;
/**
* Generic OpenID providers adapter.
@@ -29,17 +29,16 @@ use Hybridauth\Adapter\OpenID as OpenIDAdapter;
* // etc.
* ];
*
* $adapter = new Hybridauth\Provider\OpenID( $config );
* $adapter = new Hybridauth\Provider\OpenID($config);
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* }
* catch( \Exception $e ){
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
class OpenID extends OpenIDAdapter
class OpenID extends Adapter\OpenID
{
}

View File

@@ -17,11 +17,10 @@ use Hybridauth\Data\Collection;
*/
class Patreon extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'identity identity[email]';
protected $scope = 'identity identity[email]';
/**
* {@inheritdoc}
@@ -38,6 +37,11 @@ class Patreon extends OAuth2
*/
protected $accessTokenUrl = 'https://www.patreon.com/api/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://docs.patreon.com/#oauth';
/**
* {@inheritdoc}
*/
@@ -45,10 +49,12 @@ class Patreon extends OAuth2
{
parent::initialize();
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**

View File

@@ -14,58 +14,37 @@ use Hybridauth\User;
/**
* Paypal OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [ 'id' => '', 'secret' => '' ],
* 'scope' => 'openid profile email',
* ];
*
* $adapter = new Hybridauth\Provider\Paypal( $config );
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* $profile = $adapter->getUserProfile();
* }
* catch( Exception $e ){
* echo $e->getMessage() ;
* }
*/
class Paypal extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'openid profile email address';
* {@inheritdoc}
*/
protected $scope = 'openid profile email address';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.paypal.com/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.paypal.com/signin/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.paypal.com/v1/oauth2/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.paypal.com/docs/api/overview/#';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
@@ -75,20 +54,20 @@ class Paypal extends OAuth2
];
$this->tokenExchangeHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
$this->tokenRefreshHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
}
/**
* {@inheritdoc}
*
* See: https://developer.paypal.com/docs/api/identity/v1/
* See: https://developer.paypal.com/docs/connect-with-paypal/integrate/
*/
* {@inheritdoc}
*
* See: https://developer.paypal.com/docs/api/identity/v1/
* See: https://developer.paypal.com/docs/connect-with-paypal/integrate/
*/
public function getUserProfile()
{
$headers = [
@@ -102,20 +81,20 @@ class Paypal extends OAuth2
$response = $this->apiRequest('v1/identity/oauth2/userinfo', 'GET', $parameters, $headers);
$data = new Data\Collection($response);
if (! $data->exists('user_id')) {
if (!$data->exists('user_id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('user_id');
$userProfile->firstName = $data->get('given_name');
$userProfile->lastName = $data->get('family_name');
$userProfile->identifier = $data->get('user_id');
$userProfile->firstName = $data->get('given_name');
$userProfile->lastName = $data->get('family_name');
$userProfile->displayName = $data->get('name');
$userProfile->address = $data->filter('address')->get('street_address');
$userProfile->city = $data->filter('address')->get('locality');
$userProfile->country = $data->filter('address')->get('country');
$userProfile->region = $data->filter('address')->get('region');
$userProfile->zip = $data->filter('address')->get('postal_code');
$userProfile->address = $data->filter('address')->get('street_address');
$userProfile->city = $data->filter('address')->get('locality');
$userProfile->country = $data->filter('address')->get('country');
$userProfile->region = $data->filter('address')->get('region');
$userProfile->zip = $data->filter('address')->get('postal_code');
$emails = $data->filter('emails')->toArray();
foreach ($emails as $email) {

View File

@@ -7,27 +7,32 @@
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID as OpenIDAdapter;
use Hybridauth\Adapter\OpenID;
use Hybridauth\HttpClient;
/**
* PayPal OpenID provider adapter.
*/
class PaypalOpenID extends OpenIDAdapter
class PaypalOpenID extends OpenID
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $openidIdentifier = 'https://www.sandbox.paypal.com/webapps/auth/server';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.paypal.com/docs/connect-with-paypal/';
/**
* {@inheritdoc}
*/
public function authenticateBegin()
{
$this->openIdClient->identity = $this->openidIdentifier;
$this->openIdClient->identity = $this->openidIdentifier;
$this->openIdClient->returnUrl = $this->callback;
$this->openIdClient->required = [
$this->openIdClient->required = [
'namePerson/prefix',
'namePerson/first',
'namePerson/last',

View File

@@ -12,7 +12,6 @@ use Hybridauth\User\Profile;
*/
class QQ extends OAuth2
{
/**
* {@inheritdoc}
*/
@@ -54,6 +53,11 @@ class QQ extends OAuth2
*/
protected $tokenRefreshMethod = 'GET';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
@@ -61,12 +65,12 @@ class QQ extends OAuth2
{
parent::initialize();
$this->tokenRefreshParameters = [
'grant_type' => 'refresh_token',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'refresh_token' => $this->getStoredData('refresh_token'),
];
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
$this->apiRequestParameters = [
'access_token' => $this->getStoredData('access_token')

View File

@@ -18,33 +18,33 @@ use Hybridauth\User;
class Reddit extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $scope = 'identity';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://oauth.reddit.com/api/v1/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://ssl.reddit.com/api/v1/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://ssl.reddit.com/api/v1/access_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://github.com/reddit/reddit/wiki/OAuth2';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
@@ -54,36 +54,37 @@ class Reddit extends OAuth2
];
$this->tokenExchangeParameters = [
'client_id' => $this->clientId,
'grant_type' => 'authorization_code',
'client_id' => $this->clientId,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callback
];
$this->tokenExchangeHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
$this->tokenRefreshHeaders = $this->tokenExchangeHeaders;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('me.json');
$data = new Data\Collection($response);
if (! $data->exists('id')) {
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('name');
$userProfile->profileURL = 'https://www.reddit.com/user/' . $data->get('name') . '/';
$userProfile->profileURL = 'https://www.reddit.com/user/' . $data->get('name') . '/';
$userProfile->photoURL = $data->get('icon_img');
return $userProfile;
}

View File

@@ -17,11 +17,10 @@ use Hybridauth\User;
*/
class Slack extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'identity.basic identity.email identity.avatar';
protected $scope = 'identity.basic identity.email identity.avatar';
/**
* {@inheritdoc}

View File

@@ -17,11 +17,10 @@ use Hybridauth\User;
*/
class Spotify extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'user-read-email';
protected $scope = 'user-read-email';
/**
* {@inheritdoc}
@@ -38,6 +37,11 @@ class Spotify extends OAuth2
*/
protected $accessTokenUrl = 'https://accounts.spotify.com/api/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.spotify.com/documentation/general/guides/authorization-guide/';
/**
* {@inheritdoc}
*/

View File

@@ -19,66 +19,74 @@ use Hybridauth\User;
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [ 'id' => '', 'secret' => '' ],
* 'site' => 'stackoverflow'
* 'api_key' => '...' // that thing to receive a higher request quota.
* 'keys' => ['id' => '', 'secret' => ''],
* 'site' => 'stackoverflow' // required parameter to call getUserProfile()
* 'api_key' => '...' // that thing to receive a higher request quota.
* ];
*
* $adapter = new Hybridauth\Provider\StackExchange( $config );
* $adapter = new Hybridauth\Provider\StackExchange($config);
*
* $adapter->authenticate();
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* } catch (\Exception $e ){
* echo $e->getMessage() ;
* }
*/
class StackExchange extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $scope = null;
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.stackexchange.com/2.2/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://stackexchange.com/oauth';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://stackexchange.com/oauth/access_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://api.stackexchange.com/docs/authentication';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$apiKey = $this->config->get('api_key');
$this->apiRequestParameters = [ 'key' => $apiKey];
$this->apiRequestParameters = ['key' => $apiKey];
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$site = $this->config->get('site');
$response = $this->apiRequest('me?site=' . $site);
$response = $this->apiRequest('me', 'GET', [
'site' => $site,
'access_token' => $this->getStoredData('access_token'),
]);
if (! $response || !isset($response->items) || !isset($response->items[0])) {
if (!$response || !isset($response->items) || !isset($response->items[0])) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -86,12 +94,12 @@ class StackExchange extends OAuth2
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->identifier = strval($data->get('user_id'));
$userProfile->displayName = $data->get('display_name');
$userProfile->photoURL = $data->get('profile_image');
$userProfile->profileURL = $data->get('link');
$userProfile->region = $data->get('location');
$userProfile->age = $data->get('age');
$userProfile->photoURL = $data->get('profile_image');
$userProfile->profileURL = $data->get('link');
$userProfile->region = $data->get('location');
$userProfile->age = $data->get('age');
return $userProfile;
}

View File

@@ -7,28 +7,33 @@
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID as OpenIDAdapter;
use Hybridauth\Adapter\OpenID;
/**
* StackExchange OpenID provider adapter.
*/
class StackExchangeOpenID extends OpenIDAdapter
class StackExchangeOpenID extends OpenID
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $openidIdentifier = 'https://openid.stackexchange.com/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://openid.stackexchange.com/';
/**
* {@inheritdoc}
*/
public function authenticateFinish()
{
parent::authenticateFinish();
$userProfile = $this->storage->get($this->providerId . '.user');
$userProfile->identifier = !empty($userProfile->identifier) ? $userProfile->identifier : $userProfile->email;
$userProfile->identifier = !empty($userProfile->identifier) ? $userProfile->identifier : $userProfile->email;
$userProfile->emailVerified = $userProfile->email;
// re store the user profile

View File

@@ -7,7 +7,7 @@
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID as OpenIDAdapter;
use Hybridauth\Adapter\OpenID;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
@@ -19,25 +19,34 @@ use Hybridauth\User;
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [ 'secret' => 'steam-api-key' ]
* 'keys' => ['secret' => 'steam-api-key']
* ];
*
* $adapter = new Hybridauth\Provider\Steam( $config );
* $adapter = new Hybridauth\Provider\Steam($config);
*
* $adapter->authenticate();
* $userProfile = $adapter->getUserProfile();
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
class Steam extends OpenIDAdapter
class Steam extends OpenID
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $openidIdentifier = 'http://steamcommunity.com/openid';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://steamcommunity.com/dev';
/**
* {@inheritdoc}
*/
public function authenticateFinish()
{
parent::authenticateFinish();
@@ -85,7 +94,7 @@ class Steam extends OpenIDAdapter
*/
public function getUserProfileWebAPI($apiKey, $steam64)
{
$q = http_build_query(['key' => $apiKey, 'steamid' => $steam64]);
$q = http_build_query(['key' => $apiKey, 'steamids' => $steam64]);
$apiUrl = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?' . $q;
$response = $this->httpClient->request($apiUrl);
@@ -111,7 +120,7 @@ class Steam extends OpenIDAdapter
* Fetch user profile on community API
* @param $steam64
* @return array
*/
*/
public function getUserProfileLegacyAPI($steam64)
{
libxml_use_internal_errors(false);
@@ -132,8 +141,8 @@ class Steam extends OpenIDAdapter
$userProfile['description'] = (string)$data->get('summary');
$userProfile['region'] = (string)$data->get('location');
$userProfile['profileURL'] = (string)$data->get('customURL')
? 'http://steamcommunity.com/id/' . (string)$data->get('customURL')
: 'http://steamcommunity.com/profiles/' . $steam64;
? 'http://steamcommunity.com/id/' . (string)$data->get('customURL')
: 'http://steamcommunity.com/profiles/' . $steam64;
return $userProfile;
}

View File

@@ -51,7 +51,7 @@ class SteemConnect extends OAuth2
$data = new Data\Collection($response);
if (! $data->exists('result')) {
if (!$data->exists('result')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -59,10 +59,10 @@ class SteemConnect extends OAuth2
$data = $data->filter('result');
$userProfile->identifier = $data->get('id');
$userProfile->identifier = $data->get('id');
$userProfile->description = $data->get('about');
$userProfile->photoURL = $data->get('profile_image');
$userProfile->webSiteURL = $data->get('website');
$userProfile->photoURL = $data->get('profile_image');
$userProfile->webSiteURL = $data->get('website');
$userProfile->displayName = $data->get('name');
return $userProfile;

View File

@@ -20,7 +20,7 @@ class Strava extends OAuth2
/**
* {@inheritdoc}
*/
public $scope = 'profile:read_all';
protected $scope = 'profile:read_all';
/**
* {@inheritdoc}
@@ -51,13 +51,13 @@ class Strava extends OAuth2
$data = new Data\Collection($response);
if (! $data->exists('id')) {
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->identifier = $data->get('id');
$userProfile->firstName = $data->get('firstname');
$userProfile->lastName = $data->get('lastname');
$userProfile->gender = $data->get('sex');

View File

@@ -14,11 +14,22 @@ use Hybridauth\Exception\UnexpectedApiResponseException;
/**
* Telegram provider adapter.
*
* To set up Telegram you need to interactively create a bot using the
* Telegram mobile app, talking to botfather. The minimum conversation
* will look like:
*
* /newbot
* My Bot Title
* nameofmynewbot
* /setdomain
* @nameofmynewbot
* mydomain.com
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => 'your_bot_name', 'secret' => 'your_bot_token'],
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => 'your_bot_name', 'secret' => 'your_bot_token'],
* ];
*
* $adapter = new Hybridauth\Provider\Telegram($config);
@@ -27,20 +38,23 @@ use Hybridauth\Exception\UnexpectedApiResponseException;
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* }
* catch(\Exception $e) {
* } catch (\Exception $e) {
* print $e->getMessage();
* }
*/
class Telegram extends AbstractAdapter implements AdapterInterface
{
protected $botId = '';
protected $botSecret = '';
protected $callbackUrl = '';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://core.telegram.org/bots';
/**
* {@inheritdoc}
*/
@@ -79,12 +93,20 @@ class Telegram extends AbstractAdapter implements AdapterInterface
return null;
}
/**
* {@inheritdoc}
*/
public function isConnected()
{
return !empty($this->getStoredData('auth_data'));
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$data = new Collection($this->parseAuthData());
$data = new Collection($this->getStoredData('auth_data'));
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
@@ -92,11 +114,16 @@ class Telegram extends AbstractAdapter implements AdapterInterface
$userProfile = new Profile();
$userProfile->identifier = $data->get('id');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->displayName = $data->get('username');
$userProfile->photoURL = $data->get('photo_url');
$userProfile->identifier = $data->get('id');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->displayName = $data->get('username');
$userProfile->photoURL = $data->get('photo_url');
$username = $data->get('username');
if (!empty($username)) {
// Only some accounts have usernames.
$userProfile->profileURL = "https://t.me/{$username}";
}
return $userProfile;
}
@@ -144,10 +171,14 @@ class Telegram extends AbstractAdapter implements AdapterInterface
{
$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)));
$nonce = $this->config->get('nonce');
$nonce_code = empty($nonce) ? '' : "nonce=\"{$nonce}\"";
exit(
<<<HTML
<center>
<script async src="https://telegram.org/js/telegram-widget.js?7"
{$nonce_code}
data-telegram-login="{$this->botId}"
data-size="large"
data-auth-url="{$this->callbackUrl}"
@@ -164,19 +195,22 @@ HTML
sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
[Util::getCurrentUrl(true)]
);
$this->storeData('auth_data', $this->parseAuthData());
$this->initialize();
}
protected function parseAuthData()
{
return [
'id' => filter_input(INPUT_GET, 'id'),
'first_name' => filter_input(INPUT_GET, 'first_name'),
'last_name' => filter_input(INPUT_GET, 'last_name'),
'username' => filter_input(INPUT_GET, 'username'),
'photo_url' => filter_input(INPUT_GET, 'photo_url'),
'auth_date' => filter_input(INPUT_GET, 'auth_date'),
'hash' => filter_input(INPUT_GET, 'hash'),
'id' => filter_input(INPUT_GET, 'id'),
'first_name' => filter_input(INPUT_GET, 'first_name'),
'last_name' => filter_input(INPUT_GET, 'last_name'),
'username' => filter_input(INPUT_GET, 'username'),
'photo_url' => filter_input(INPUT_GET, 'photo_url'),
'auth_date' => filter_input(INPUT_GET, 'auth_date'),
'hash' => filter_input(INPUT_GET, 'hash'),
];
}
}

View File

@@ -18,40 +18,40 @@ use Hybridauth\User;
class Tumblr extends OAuth1
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.tumblr.com/v2/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.tumblr.com/oauth/authorize';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $requestTokenUrl = 'https://www.tumblr.com/oauth/request_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://www.tumblr.com/oauth/access_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://www.tumblr.com/docs/en/api/v2';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('user/info');
$data = new Data\Collection($response);
if (! $data->exists('response')) {
if (!$data->exists('response')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -63,9 +63,9 @@ class Tumblr extends OAuth1
$blog = new Data\Collection($blog);
if ($blog->get('primary') && $blog->exists('url')) {
$userProfile->identifier = $blog->get('url');
$userProfile->profileURL = $blog->get('url');
$userProfile->webSiteURL = $blog->get('url');
$userProfile->identifier = $blog->get('url');
$userProfile->profileURL = $blog->get('url');
$userProfile->webSiteURL = $blog->get('url');
$userProfile->description = strip_tags($blog->get('description'));
$bloghostname = explode('://', $blog->get('url'));
@@ -82,13 +82,13 @@ class Tumblr extends OAuth1
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function setUserStatus($status)
{
$status = is_string($status)
? [ 'type' => 'text', 'body' => $status ]
: $status;
? ['type' => 'text', 'body' => $status]
: $status;
$response = $this->apiRequest('blog/' . $this->getStoredData('primary_blog') . '/post', 'POST', $status);

View File

@@ -42,6 +42,16 @@ class TwitchTV extends OAuth2
*/
protected $apiDocumentation = 'https://dev.twitch.tv/docs/authentication/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->apiRequestHeaders['Client-ID'] = $this->clientId;
}
/**
* {@inheritdoc}
*/

View File

@@ -13,17 +13,19 @@ use Hybridauth\Data;
use Hybridauth\User;
/**
* Twitter provider adapter.
* Twitter OAuth1 provider adapter.
* Uses OAuth1 not OAuth2 because many Twitter endpoints are built around OAuth1.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [ 'key' => '', 'secret' => '' ], // OAuth1 uses 'key' not 'id'
* 'authorize' => true
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['key' => '', 'secret' => ''], // OAuth1 uses 'key' not 'id'
* 'authorize' => true // Needed to perform actions on behalf of users (see below link)
* // https://developer.twitter.com/en/docs/authentication/oauth-1-0a/obtaining-user-access-tokens
* ];
*
* $adapter = new Hybridauth\Provider\Twitter( $config );
* $adapter = new Hybridauth\Provider\Twitter($config);
*
* try {
* $adapter->authenticate();
@@ -32,8 +34,7 @@ use Hybridauth\User;
* $tokens = $adapter->getAccessToken();
* $contacts = $adapter->getUserContacts(['screen_name' =>'andypiper']); // get those of @andypiper
* $activity = $adapter->getUserActivity('me');
* }
* catch( Exception $e ){
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
@@ -81,7 +82,9 @@ class Twitter extends OAuth1
*/
public function getUserProfile()
{
$response = $this->apiRequest('account/verify_credentials.json?include_email=true');
$response = $this->apiRequest('account/verify_credentials.json', 'GET', [
'include_email' => $this->config->get('include_email') === false ? 'false' : 'true',
]);
$data = new Data\Collection($response);
@@ -91,28 +94,28 @@ class Twitter extends OAuth1
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id_str');
$userProfile->displayName = $data->get('screen_name');
$userProfile->description = $data->get('description');
$userProfile->firstName = $data->get('name');
$userProfile->email = $data->get('email');
$userProfile->identifier = $data->get('id_str');
$userProfile->displayName = $data->get('screen_name');
$userProfile->description = $data->get('description');
$userProfile->firstName = $data->get('name');
$userProfile->email = $data->get('email');
$userProfile->emailVerified = $data->get('email');
$userProfile->webSiteURL = $data->get('url');
$userProfile->region = $data->get('location');
$userProfile->webSiteURL = $data->get('url');
$userProfile->region = $data->get('location');
$userProfile->profileURL = $data->exists('screen_name')
? ('http://twitter.com/' . $data->get('screen_name'))
: '';
$userProfile->profileURL = $data->exists('screen_name')
? ('http://twitter.com/' . $data->get('screen_name'))
: '';
$photoSize = $this->config->get('photo_size') ?: 'original';
$photoSize = $photoSize === 'original' ? '' : "_{$photoSize}";
$userProfile->photoURL = $data->exists('profile_image_url_https')
? str_replace('_normal', $photoSize, $data->get('profile_image_url_https'))
: '';
$userProfile->photoURL = $data->exists('profile_image_url_https')
? str_replace('_normal', $photoSize, $data->get('profile_image_url_https'))
: '';
$userProfile->data = [
'followed_by' => $data->get('followers_count'),
'follows' => $data->get('friends_count'),
'followed_by' => $data->get('followers_count'),
'follows' => $data->get('friends_count'),
];
return $userProfile;
@@ -123,13 +126,13 @@ class Twitter extends OAuth1
*/
public function getUserContacts($parameters = [])
{
$parameters = [ 'cursor' => '-1'] + $parameters;
$parameters = ['cursor' => '-1'] + $parameters;
$response = $this->apiRequest('friends/ids.json', 'GET', $parameters);
$data = new Data\Collection($response);
if (! $data->exists('ids')) {
if (!$data->exists('ids')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -140,10 +143,10 @@ class Twitter extends OAuth1
$contacts = [];
// 75 id per time should be okey
$contactsIds = array_chunk((array) $data->get('ids'), 75);
$contactsIds = array_chunk((array)$data->get('ids'), 75);
foreach ($contactsIds as $chunk) {
$parameters = [ 'user_id' => implode(',', $chunk) ];
$parameters = ['user_id' => implode(',', $chunk)];
try {
$response = $this->apiRequest('users/lookup.json', 'GET', $parameters);
@@ -172,14 +175,14 @@ class Twitter extends OAuth1
$userContact = new User\Contact();
$userContact->identifier = $item->get('id_str');
$userContact->identifier = $item->get('id_str');
$userContact->displayName = $item->get('name');
$userContact->photoURL = $item->get('profile_image_url');
$userContact->photoURL = $item->get('profile_image_url');
$userContact->description = $item->get('description');
$userContact->profileURL = $item->exists('screen_name')
? ('http://twitter.com/' . $item->get('screen_name'))
: '';
$userContact->profileURL = $item->exists('screen_name')
? ('http://twitter.com/' . $item->get('screen_name'))
: '';
return $userContact;
}
@@ -216,8 +219,8 @@ class Twitter extends OAuth1
public function getUserActivity($stream = 'me')
{
$apiUrl = ($stream == 'me')
? 'statuses/user_timeline.json'
: 'statuses/home_timeline.json';
? 'statuses/user_timeline.json'
: 'statuses/home_timeline.json';
$response = $this->apiRequest($apiUrl);
@@ -244,17 +247,17 @@ class Twitter extends OAuth1
$userActivity = new User\Activity();
$userActivity->id = $item->get('id_str');
$userActivity->id = $item->get('id_str');
$userActivity->date = $item->get('created_at');
$userActivity->text = $item->get('text');
$userActivity->user->identifier = $item->filter('user')->get('id_str');
$userActivity->user->displayName = $item->filter('user')->get('name');
$userActivity->user->photoURL = $item->filter('user')->get('profile_image_url');
$userActivity->user->identifier = $item->filter('user')->get('id_str');
$userActivity->user->displayName = $item->filter('user')->get('name');
$userActivity->user->photoURL = $item->filter('user')->get('profile_image_url');
$userActivity->user->profileURL = $item->filter('user')->get('screen_name')
? ('http://twitter.com/' . $item->filter('user')->get('screen_name'))
: '';
$userActivity->user->profileURL = $item->filter('user')->get('screen_name')
? ('http://twitter.com/' . $item->filter('user')->get('screen_name'))
: '';
return $userActivity;
}

View File

@@ -15,13 +15,16 @@ use Hybridauth\Data;
use Hybridauth\User;
/**
* Vkontakte provider adapter.
* Vkontakte OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [
* 'id' => '', // App ID
* 'secret' => '' // Secure key
* ],
* ];
*
* $adapter = new Hybridauth\Provider\Vkontakte($config);
@@ -32,14 +35,12 @@ use Hybridauth\User;
* }
*
* $userProfile = $adapter->getUserProfile();
* }
* catch(\Exception $e) {
* } catch (\Exception $e) {
* print $e->getMessage() ;
* }
*/
class Vkontakte extends OAuth2
{
const API_VERSION = '5.95';
const URL = 'https://vk.com/';
@@ -64,6 +65,11 @@ class Vkontakte extends OAuth2
*/
protected $scope = 'email,offline';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
@@ -92,11 +98,15 @@ class Vkontakte extends OAuth2
/**
* {@inheritdoc}
*/
public function hasAccessTokenExpired()
public function hasAccessTokenExpired($time = null)
{
// As we using offline scope, $expired will be false.
if ($time === null) {
$time = time();
}
// If we are using offline scope, $expired will be false.
$expired = $this->getStoredData('expires_in')
? $this->getStoredData('expires_at') <= time()
? $this->getStoredData('expires_at') <= $time
: false;
return $expired;
@@ -125,19 +135,19 @@ class Vkontakte extends OAuth2
$userProfile = new Profile();
$userProfile->identifier = $data->get('id');
$userProfile->email = $this->getStoredData('email');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->identifier = $data->get('id');
$userProfile->email = $this->getStoredData('email');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->displayName = $data->get('screen_name');
$userProfile->photoURL = $data->get('has_photo') === 1 ? $data->get($photoField) : '';
$userProfile->photoURL = $data->get('has_photo') === 1 ? $data->get($photoField) : '';
// Handle b-date.
if ($data->get('bdate')) {
$bday = explode('.', $data->get('bdate'));
$userProfile->birthDay = (int) $bday[0];
$userProfile->birthMonth = (int) $bday[1];
$userProfile->birthYear = (int) $bday[2];
$userProfile->birthDay = (int)$bday[0];
$userProfile->birthMonth = (int)$bday[1];
$userProfile->birthYear = (int)$bday[2];
}
$userProfile->data = [
@@ -145,7 +155,7 @@ class Vkontakte extends OAuth2
];
$screen_name = static::URL . ($data->get('screen_name') ?: 'id' . $data->get('id'));
$userProfile->profileURL = $screen_name;
$userProfile->profileURL = $screen_name;
switch ($data->get('sex')) {
case 1:

View File

@@ -17,11 +17,10 @@ use Hybridauth\User;
*/
class WeChat extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'snsapi_userinfo';
protected $scope = 'snsapi_login,snsapi_userinfo,scope.userInfo';
/**
* {@inheritdoc}
@@ -60,12 +59,33 @@ class WeChat extends OAuth2
protected $tokenRefreshMethod = 'GET';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->AuthorizeUrlParameters += [
'appid' => $this->clientId
];
unset($this->AuthorizeUrlParameters['client_id']);
$this->tokenExchangeParameters += [
'appid' => $this->clientId,
'secret' => $this->clientSecret
];
unset($this->tokenExchangeParameters['client_id']);
unset($this->tokenExchangeParameters['client_secret']);
$this->tokenRefreshParameters += [
'appid' => $this->clientId
];
$this->apiRequestParameters = [
'appid' => $this->clientId,
'secret' => $this->clientSecret
@@ -80,6 +100,7 @@ class WeChat extends OAuth2
$collection = parent::validateAccessTokenExchange($response);
$this->storeData('openid', $collection->get('openid'));
$this->storeData('access_token', $collection->get('access_token'));
}
/**
@@ -88,8 +109,9 @@ class WeChat extends OAuth2
public function getUserProfile()
{
$openid = $this->getStoredData('openid');
$access_token = $this->getStoredData('access_token');
$response = $this->apiRequest('userinfo', 'GET', ['openid' => $openid]);
$response = $this->apiRequest('userinfo', 'GET', ['openid' => $openid, 'access_token' => $access_token]);
$data = new Data\Collection($response);
@@ -99,13 +121,13 @@ class WeChat extends OAuth2
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('openid');
$userProfile->identifier = $data->get('openid');
$userProfile->displayName = $data->get('nickname');
$userProfile->photoURL = $data->get('headimgurl');
$userProfile->city = $data->get('city');
$userProfile->region = $data->get('province');
$userProfile->country = $data->get('country');
$userProfile->gender = ['', 'male', 'female'][(int)$data->get('sex')];
$userProfile->photoURL = $data->get('headimgurl');
$userProfile->city = $data->get('city');
$userProfile->region = $data->get('province');
$userProfile->country = $data->get('country');
$userProfile->gender = ['', 'male', 'female'][(int)$data->get('sex')];
return $userProfile;
}

View File

@@ -12,7 +12,6 @@ namespace Hybridauth\Provider;
*/
class WeChatChina extends WeChat
{
/**
* {@inheritdoc}
*/

View File

@@ -18,71 +18,71 @@ use Hybridauth\User;
class WindowsLive extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'wl.basic wl.contacts_emails wl.emails wl.signin wl.share wl.birthday';
* {@inheritdoc}
*/
protected $scope = 'wl.basic wl.contacts_emails wl.emails wl.signin wl.share wl.birthday';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://apis.live.net/v5.0/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://login.live.com/oauth20_authorize.srf';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://login.live.com/oauth20_token.srf';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://msdn.microsoft.com/en-us/library/hh243647.aspx';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('me');
$data = new Data\Collection($response);
if (! $data->exists('id')) {
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('name');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->gender = $data->get('gender');
$userProfile->profileURL = $data->get('link');
$userProfile->email = $data->filter('emails')->get('preferred');
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('name');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->gender = $data->get('gender');
$userProfile->profileURL = $data->get('link');
$userProfile->email = $data->filter('emails')->get('preferred');
$userProfile->emailVerified = $data->filter('emails')->get('account');
$userProfile->birthDay = $data->get('birth_day');
$userProfile->birthMonth = $data->get('birth_month');
$userProfile->birthYear = $data->get('birth_year');
$userProfile->language = $data->get('locale');
$userProfile->birthDay = $data->get('birth_day');
$userProfile->birthMonth = $data->get('birth_month');
$userProfile->birthYear = $data->get('birth_year');
$userProfile->language = $data->get('locale');
return $userProfile;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserContacts()
{
$response = $this->apiRequest('me/contacts');
$data = new Data\Collection($response);
if (! $data->exists('data')) {
if (!$data->exists('data')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
@@ -91,9 +91,9 @@ class WindowsLive extends OAuth2
foreach ($data->filter('data')->toArray() as $idx => $entry) {
$userContact = new User\Contact();
$userContact->identifier = $entry->get('id');
$userContact->identifier = $entry->get('id');
$userContact->displayName = $entry->get('name');
$userContact->email = $entry->filter('emails')->get('preferred');
$userContact->email = $entry->filter('emails')->get('preferred');
$contacts[] = $userContact;
}

View File

@@ -18,46 +18,46 @@ use Hybridauth\User;
class WordPress extends OAuth2
{
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://public-api.wordpress.com/rest/v1/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://public-api.wordpress.com/oauth2/authenticate';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://public-api.wordpress.com/oauth2/token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.wordpress.com/docs/api/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('me/');
$data = new Data\Collection($response);
if (! $data->exists('ID')) {
if (!$data->exists('ID')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('ID');
$userProfile->identifier = $data->get('ID');
$userProfile->displayName = $data->get('display_name');
$userProfile->photoURL = $data->get('avatar_URL');
$userProfile->profileURL = $data->get('profile_URL');
$userProfile->email = $data->get('email');
$userProfile->language = $data->get('language');
$userProfile->photoURL = $data->get('avatar_URL');
$userProfile->profileURL = $data->get('profile_URL');
$userProfile->email = $data->get('email');
$userProfile->language = $data->get('language');
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');

View File

@@ -12,123 +12,92 @@ use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* For this provider to work it is necessary to assign the "OpenID Connect Permissions",
* even if you only use basic OAuth2.
*/
/**
* Yahoo OAuth2 provider adapter.
*/
class Yahoo extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'sdpp-w';
* {@inheritdoc}
*/
protected $scope = 'profile';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://social.yahooapis.com/v1/';
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.login.yahoo.com/openid/v1/';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://api.login.yahoo.com/oauth2/request_auth';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.login.yahoo.com/oauth2/get_token';
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.yahoo.com/oauth2/guide/';
/**
* Currently authenticated user
*/
* Currently authenticated user
*/
protected $userId = null;
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->tokenExchangeHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
$this->tokenRefreshHeaders = $this->tokenExchangeHeaders;
}
/**
* Returns current user id
*
* @return int
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws \Hybridauth\Exception\InvalidAccessTokenException
* @throws \Hybridauth\Exception\UnexpectedApiResponseException
* {@inheritdoc}
*/
protected function getCurrentUserId()
{
if ($this->userId) {
return $this->userId;
}
$response = $this->apiRequest('me/guid', 'GET', [ 'format' => 'json']);
$data = new Data\Collection($response);
if (! $data->filter('guid')->exists('value')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
return $this->userId = $data->filter('guid')->get('value');
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
// Retrieve current user guid if needed
$this->getCurrentUserId();
$response = $this->apiRequest('user/' . $this->userId . '/profile', 'GET', [ 'format' => 'json']);
$response = $this->apiRequest('userinfo');
$data = new Data\Collection($response);
if (! $data->exists('profile')) {
if (!$data->exists('sub')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$data = $data->filter('profile');
$userProfile->identifier = $data->get('sub');
$userProfile->firstName = $data->get('given_name');
$userProfile->lastName = $data->get('family_name');
$userProfile->displayName = $data->get('name');
$userProfile->gender = $data->get('gender');
$userProfile->language = $data->get('locale');
$userProfile->email = $data->get('email');
$userProfile->identifier = $data->get('guid');
$userProfile->firstName = $data->get('givenName');
$userProfile->lastName = $data->get('familyName');
$userProfile->displayName = $data->get('nickname');
$userProfile->photoURL = $data->filter('image')->get('imageUrl');
$userProfile->profileURL = $data->get('profileUrl');
$userProfile->language = $data->get('lang');
$userProfile->address = $data->get('location');
$userProfile->emailVerified = $data->get('email_verified') ? $userProfile->email : '';
if ('F' == $data->get('gender')) {
$userProfile->gender = 'female';
} elseif ('M' == $data->get('gender')) {
$userProfile->gender = 'male';
}
// E-mail is returned only with sdpp-w scope ( Read/Write (Public and Private) )
foreach ($data->filter('emails')->toArray() as $item) {
$item = new Data\Collection($item);
if ($item->get('primary')) {
$userProfile->email = $item->get('handle');
$userProfile->emailVerified = $item->get('handle');
}
$profileImages = $data->get('profile_images');
if ($this->config->get('photo_size')) {
$prop = 'image' . $this->config->get('photo_size');
} else {
$prop = 'image192';
}
$userProfile->photoURL = $profileImages->$prop;
return $userProfile;
}

View File

@@ -1,37 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID as OpenIDAdapter;
/**
* Yahoo OpenID provider adapter.
*/
class YahooOpenID extends OpenIDAdapter
{
/**
* {@inheritdoc}
*/
protected $openidIdentifier = 'https://open.login.yahooapis.com/openid20/www.yahoo.com/xrds';
/**
* {@inheritdoc}
*/
public function authenticateFinish()
{
parent::authenticateFinish();
$userProfile = $this->storage->get($this->providerId . '.user');
$userProfile->identifier = $userProfile->email;
$userProfile->emailVerified = $userProfile->email;
// re store the user profile
$this->storage->set($this->providerId . '.user', $userProfile);
}
}

View File

@@ -14,27 +14,7 @@ use Hybridauth\Data\Collection;
use Hybridauth\User\Profile;
/**
* Yandex provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* ];
*
* $adapter = new Hybridauth\Provider\Yandex($config);
*
* try {
* if (!$adapter->isConnected()) {
* $adapter->authenticate();
* }
*
* $userProfile = $adapter->getUserProfile();
* }
* catch(\Exception $e) {
* print $e->getMessage() ;
* }
* Yandex OAuth2 provider adapter.
*/
class Yandex extends OAuth2
{
@@ -53,6 +33,11 @@ class Yandex extends OAuth2
*/
protected $accessTokenUrl = 'https://oauth.yandex.ru/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://yandex.com/dev/oauth/doc/dg/concepts/about-docpage/';
/**
* load the user profile from the IDp api client
*
@@ -60,10 +45,9 @@ class Yandex extends OAuth2
*/
public function getUserProfile()
{
$this->scope = implode(',', []);
$response = $this->apiRequest($this->apiBaseUrl . "?format=json");
$response = $this->apiRequest($this->apiBaseUrl, 'GET', ['format' => 'json']);
if (!isset($response->id)) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');

View File

@@ -10,7 +10,7 @@ namespace Hybridauth\Storage;
use Hybridauth\Exception\RuntimeException;
/**
* HybridAuth storage manager
* Hybridauth storage manager
*/
class Session implements StorageInterface
{
@@ -29,10 +29,10 @@ class Session implements StorageInterface
protected $keyPrefix = '';
/**
* Initiate a new session
*
* @throws RuntimeException
*/
* Initiate a new session
*
* @throws RuntimeException
*/
public function __construct()
{
if (session_id()) {
@@ -44,46 +44,57 @@ class Session implements StorageInterface
throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
}
if (! session_start()) {
if (!session_start()) {
throw new RuntimeException('PHP session failed to start.');
}
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function get($key)
{
$key = $this->keyPrefix . strtolower($key);
if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) {
return $_SESSION[$this->storeNamespace][$key];
$value = $_SESSION[$this->storeNamespace][$key];
if (is_array($value) && array_key_exists('lateObject', $value)) {
$value = unserialize($value['lateObject']);
}
return $value;
}
return null;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function set($key, $value)
{
$key = $this->keyPrefix . strtolower($key);
if (is_object($value)) {
// We encapsulate as our classes may be defined after session is initialized.
$value = ['lateObject' => serialize($value)];
}
$_SESSION[$this->storeNamespace][$key] = $value;
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function clear()
{
$_SESSION[$this->storeNamespace] = [];
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function delete($key)
{
$key = $this->keyPrefix . strtolower($key);
@@ -98,8 +109,8 @@ class Session implements StorageInterface
}
/**
* {@inheritdoc}
*/
* {@inheritdoc}
*/
public function deleteMatch($key)
{
$key = $this->keyPrefix . strtolower($key);
@@ -109,7 +120,7 @@ class Session implements StorageInterface
foreach ($tmp as $k => $v) {
if (strstr($k, $key)) {
unset($tmp[ $k ]);
unset($tmp[$k]);
}
}

View File

@@ -8,43 +8,43 @@
namespace Hybridauth\Storage;
/**
* HybridAuth storage manager interface
* Hybridauth storage manager interface
*/
interface StorageInterface
{
/**
* Retrieve a item from storage
*
* @param string $key
*
* @return mixed
*/
* Retrieve a item from storage
*
* @param string $key
*
* @return mixed
*/
public function get($key);
/**
* Add or Update an item to storage
*
* @param string $key
* @param string $value
*/
* Add or Update an item to storage
*
* @param string $key
* @param string $value
*/
public function set($key, $value);
/**
* Delete an item from storage
*
* @param string $key
*/
* Delete an item from storage
*
* @param string $key
*/
public function delete($key);
/**
* Delete a item from storage
*
* @param string $key
*/
* Delete a item from storage
*
* @param string $key
*/
public function deleteMatch($key);
/**
* Clear all items in storage
*/
* Clear all items in storage
*/
public function clear();
}

View File

@@ -253,7 +253,7 @@ class LightOpenID
protected function get_realm_protocol()
{
if (!empty($_SERVER['HTTPS'])) {
$use_secure_protocol = ($_SERVER['HTTPS'] != 'off');
$use_secure_protocol = ($_SERVER['HTTPS'] !== 'off');
} elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$use_secure_protocol = ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https');
} elseif (isset($_SERVER['HTTP__WSSC'])) {
@@ -1090,14 +1090,8 @@ class LightOpenID
$server = $this->discover($this->claimed_id);
foreach (explode(',', $this->data['openid_signed']) as $item) {
# Checking whether magic_quotes_gpc is turned on, because
# the function may fail if it is. For example, when fetching
# AX namePerson, it might contain an apostrophe, which will be escaped.
# In such case, validation would fail, since we'd send different data than OP
# wants to verify. stripslashes() should solve that problem, but we can't
# use it when magic_quotes is off.
$value = $this->data['openid_' . str_replace('.', '_', $item)];
$params['openid.' . $item] = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ? stripslashes($value) : $value;
$params['openid.' . $item] = $value;
}
$params['openid.mode'] = 'check_authentication';

View File

@@ -15,55 +15,55 @@ use Hybridauth\Exception\UnexpectedValueException;
final class Activity
{
/**
* activity id on the provider side, usually given as integer
*
* @var string
*/
* activity id on the provider side, usually given as integer
*
* @var string
*/
public $id = null;
/**
* activity date of creation
*
* @var string
*/
* activity date of creation
*
* @var string
*/
public $date = null;
/**
* activity content as a string
*
* @var string
*/
* activity content as a string
*
* @var string
*/
public $text = null;
/**
* user who created the activity
*
* @var object
*/
* user who created the activity
*
* @var object
*/
public $user = null;
/**
*
*/
*
*/
public function __construct()
{
$this->user = new \stdClass();
// typically, we should have a few information about the user who created the event from social apis
$this->user->identifier = null;
$this->user->identifier = null;
$this->user->displayName = null;
$this->user->profileURL = null;
$this->user->photoURL = null;
$this->user->profileURL = null;
$this->user->photoURL = null;
}
/**
* Prevent the providers adapters from adding new fields.
*
* @var mixed $value
*
* @throws UnexpectedValueException
* @var string $name
*
* @throws UnexpectedValueException
* @var mixed $value
*
*/
public function __set($name, $value)
{

View File

@@ -15,62 +15,62 @@ use Hybridauth\Exception\UnexpectedValueException;
final class Contact
{
/**
* The Unique contact user ID
*
* @var string
*/
* The Unique contact user ID
*
* @var string
*/
public $identifier = null;
/**
* User website, blog, web page
*
* @var string
*/
* User website, blog, web page
*
* @var string
*/
public $webSiteURL = null;
/**
* URL link to profile page on the IDp web site
*
* @var string
*/
* URL link to profile page on the IDp web site
*
* @var string
*/
public $profileURL = null;
/**
* URL link to user photo or avatar
*
* @var string
*/
* URL link to user photo or avatar
*
* @var string
*/
public $photoURL = null;
/**
* User displayName provided by the IDp or a concatenation of first and last name
*
* @var string
*/
* User displayName provided by the IDp or a concatenation of first and last name
*
* @var string
*/
public $displayName = null;
/**
* A short about_me
*
* @var string
*/
* A short about_me
*
* @var string
*/
public $description = null;
/**
* User email. Not all of IDp grant access to the user email
*
* @var string
*/
* User email. Not all of IDp grant access to the user email
*
* @var string
*/
public $email = null;
/**
* Prevent the providers adapters from adding new fields.
*
* @param string $name
* @param mixed $value
*
* @throws UnexpectedValueException
*/
* Prevent the providers adapters from adding new fields.
*
* @param string $name
* @param mixed $value
*
* @throws UnexpectedValueException
*/
public function __set($name, $value)
{
throw new UnexpectedValueException(sprintf('Adding new property "%s" to %s is not allowed.', $name, __CLASS__));

View File

@@ -15,174 +15,174 @@ use Hybridauth\Exception\UnexpectedValueException;
final class Profile
{
/**
* The Unique user's ID on the connected provider
*
* @var integer
*/
* The Unique user's ID on the connected provider
*
* @var int|null
*/
public $identifier = null;
/**
* User website, blog, web page
*
* @var string
*/
* User website, blog, web page
*
* @var string|null
*/
public $webSiteURL = null;
/**
* URL link to profile page on the IDp web site
*
* @var string
*/
* URL link to profile page on the IDp web site
*
* @var string|null
*/
public $profileURL = null;
/**
* URL link to user photo or avatar
*
* @var string
*/
* URL link to user photo or avatar
*
* @var string|null
*/
public $photoURL = null;
/**
* User displayName provided by the IDp or a concatenation of first and last name.
*
* @var string
*/
* User displayName provided by the IDp or a concatenation of first and last name.
*
* @var string|null
*/
public $displayName = null;
/**
* A short about_me
*
* @var string
*/
* A short about_me
*
* @var string|null
*/
public $description = null;
/**
* User's first name
*
* @var string
*/
* User's first name
*
* @var string|null
*/
public $firstName = null;
/**
* User's last name
*
* @var string
*/
* User's last name
*
* @var string|null
*/
public $lastName = null;
/**
* male or female
*
* @var string
*/
* male or female
*
* @var string|null
*/
public $gender = null;
/**
* Language
*
* @var string
*/
* Language
*
* @var string|null
*/
public $language = null;
/**
* User age, we don't calculate it. we return it as is if the IDp provide it.
*
* @var integer
*/
* User age, we don't calculate it. we return it as is if the IDp provide it.
*
* @var int|null
*/
public $age = null;
/**
* User birth Day
*
* @var integer
*/
* User birth Day
*
* @var int|null
*/
public $birthDay = null;
/**
* User birth Month
*
* @var integer
*/
* User birth Month
*
* @var int|null
*/
public $birthMonth = null;
/**
* User birth Year
*
* @var integer
*/
* User birth Year
*
* @var int|null
*/
public $birthYear = null;
/**
* User email. Note: not all of IDp grant access to the user email
*
* @var string
*/
* User email. Note: not all of IDp grant access to the user email
*
* @var string|null
*/
public $email = null;
/**
* Verified user email. Note: not all of IDp grant access to verified user email
*
* @var string
*/
* Verified user email. Note: not all of IDp grant access to verified user email
*
* @var string|null
*/
public $emailVerified = null;
/**
* Phone number
*
* @var string
*/
* Phone number
*
* @var string|null
*/
public $phone = null;
/**
* Complete user address
*
* @var string
*/
* Complete user address
*
* @var string|null
*/
public $address = null;
/**
* User country
*
* @var string
*/
* User country
*
* @var string|null
*/
public $country = null;
/**
* Region
*
* @var string
*/
* Region
*
* @var string|null
*/
public $region = null;
/**
* City
*
* @var string
*/
* City
*
* @var string|null
*/
public $city = null;
/**
* Postal code
*
* @var string
*/
* Postal code
*
* @var string|null
*/
public $zip = null;
/**
* An extra data which is related to the user
*
* @var array
*/
* An extra data which is related to the user
*
* @var array
*/
public $data = [];
/**
* Prevent the providers adapters from adding new fields.
*
* @var string $name
* @var mixed $value
*
* @throws UnexpectedValueException
*/
* Prevent the providers adapters from adding new fields.
*
* @throws UnexpectedValueException
* @var mixed $value
*
* @var string $name
*/
public function __set($name, $value)
{
throw new UnexpectedValueException(sprintf('Adding new property "%s" to %s is not allowed.', $name, __CLASS__));

View File

@@ -27,8 +27,8 @@ spl_autoload_register(
// base directory for the namespace prefix.
$base_dir = __DIR__; // By default, it points to this same folder.
// You may change this path if having trouble detecting the path to
// the source files.
// You may change this path if having trouble detecting the path to
// the source files.
// does the class use the namespace prefix?
$len = strlen($prefix);
@@ -43,7 +43,7 @@ spl_autoload_register(
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $relative_class).'.php';
$file = $base_dir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {

View File

@@ -1,130 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth\Data;
use Hybridauth\Data\Collection;
class CollectionTest extends \PHPUnit\Framework\TestCase
{
public function some_random_id()
{
return 69;
}
public function some_random_year()
{
return 2020;
}
public function some_random_array()
{
return ['id' => 69, 'slugs' => ['Γεια σας', 'Bonjour', '안녕하세요', 'year' => 2020]];
}
public function some_random_object()
{
$object = new \StdClass();
$object->id = 69;
$object->slugs = ['Γεια σας', 'Bonjour', '안녕하세요', 'year' => 2020];
return $object;
}
public function test_instance_of()
{
$collection = new Collection;
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection);
}
public function test_identity()
{
$array = $this->some_random_array();
$collection = new Collection($array);
$result = $collection->toArray();
$this->assertEquals($result, $array);
}
/**
* @covers Collection::exists
*/
public function test_exists()
{
$array = $this->some_random_array();
$collection = new Collection($array);
$this->assertTrue($collection->exists('id'));
$this->assertFalse($collection->exists('_non_existant_'));
//
$object = $this->some_random_object();
$collection = new Collection($object);
$this->assertTrue($collection->exists('id'));
$this->assertFalse($collection->exists('_non_existant_'));
}
/**
* @covers Collection::get
*/
public function test_get()
{
$array = $this->some_random_array();
$collection = new Collection($array);
$this->assertEquals($collection->get('id'), $this->some_random_id());
$this->assertNull($collection->get('_non_existant_'));
//
$object = $this->some_random_object();
$collection = new Collection($object);
$this->assertEquals($collection->get('id'), $this->some_random_id());
$this->assertNull($collection->get('_non_existant_'));
}
/**
* @covers Collection::filter
*/
public function test_filter()
{
$array = $this->some_random_array();
$collection = new Collection($array);
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('id'));
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('slugs'));
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('_non_existant_'));
$this->assertNull($collection->filter('slugs')->get('_non_existant_'));
$this->assertEquals($collection->filter('slugs')->get('year'), $this->some_random_year());
//
$object = $this->some_random_object();
$collection = new Collection($object);
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('id'));
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('slugs'));
$this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('_non_existant_'));
$this->assertNull($collection->filter('slugs')->get('_non_existant_'));
$this->assertEquals($collection->filter('slugs')->get('year'), $this->some_random_year());
}
}

View File

@@ -1,77 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth\Data;
use Hybridauth\Data\Parser;
class ParserTest extends \PHPUnit\Framework\TestCase
{
public function test_instance_of()
{
$parser = new Parser;
$this->assertInstanceOf('\\Hybridauth\\Data\\Parser', $parser);
}
/**
* @covers Parser::parse
* @covers Parser::parseJson
*/
public function test_parser_json()
{
$parser = new Parser;
$object = new \StdClass();
$object->id = 69;
$object->slugs = ['Γεια σας', 'Bonjour', '안녕하세요'];
$json = json_encode($object);
//
$result = $parser->parse($json);
$this->assertInstanceOf('\\StdClass', $result);
$this->assertEquals($result, $object);
//
$result = $parser->parseJson($json);
$this->assertInstanceOf('\\StdClass', $result);
$this->assertEquals($result, $object);
}
/**
* @covers Parser::parse
* @covers Parser::parseQueryString
*/
public function test_parser_querystring()
{
$parser = new Parser;
$object = new \StdClass();
$object->id = 69;
$object->slug = 'oauth';
$string = 'id=69&slug=oauth';
//
$result = $parser->parse($string);
$this->assertInstanceOf('\\StdClass', $result);
$this->assertEquals($result, $object);
//
$result = $parser->parseQueryString($string);
$this->assertInstanceOf('\\StdClass', $result);
$this->assertEquals($result, $object);
}
}

View File

@@ -1,13 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth;
use Hybridauth\Hybridauth;
class HybridauthTest extends \PHPUnit\Framework\TestCase
{
public function test_pass()
{
$this->assertTrue(true);
}
}

View File

@@ -1,124 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth\Storage;
use Hybridauth\Storage\Session;
session_start(); // they will hate me for this..
class SessionTest extends \PHPUnit\Framework\TestCase
{
public function some_random_session_data()
{
return [
[ 'foo', 'bar' ],
[ 1234, 'bar' ],
[ 'foo', 1234 ],
[ 'Bonjour', '안녕하세요' ],
[ 'ஹலோ' , 'Γεια σας' ],
[ 'array', [ 1, 2, 3 ] ],
[ 'string', json_encode($this) ],
[ 'object', $this ],
[ 'provider.token.request_token', '9DYPEJ&qhvhP3eJ!' ],
[ 'provider.token.oauth_token', '80359084-clg1DEtxQF3wstTcyUdHF3wsdHM' ],
[ 'provider.token.oauth_token_secret', 'qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e' ],
];
}
public function test_instance_of()
{
$storage = new Session;
$this->assertInstanceOf('\\Hybridauth\\Storage\\StorageInterface', $storage);
}
/**
* @dataProvider some_random_session_data
* @covers Session::get
* @covers Session::set
*/
public function test_set_and_get_data($key, $value)
{
$storage = new Session;
$storage->set($key, $value);
$data = $storage->get($key);
$this->assertEquals($value, $data);
}
/**
* @dataProvider some_random_session_data
* @covers Session::delete
*/
public function test_delete_data($key, $value)
{
$storage = new Session;
$storage->set($key, $value);
$storage->delete($key);
$data = $storage->get($key);
$this->assertNull($data);
}
/**
* @dataProvider some_random_session_data
* @covers Session::clear
*/
public function test_clear_data($key, $value)
{
$storage = new Session;
$storage->set($key, $value);
$storage->clear();
$data = $storage->get($key);
$this->assertNull($data);
}
/**
* @covers Session::clear
*/
public function test_clear_data_bulk()
{
$storage = new Session;
foreach ((array) $this->some_random_session_data() as $key => $value) {
$storage->set($key, $value);
}
$storage->clear();
foreach ((array) $this->some_random_session_data() as $key => $value) {
$data = $storage->get($key);
$this->assertNull($data);
}
}
/**
* @dataProvider some_random_session_data
* @covers Session::deleteMatch
*/
public function test_delete_match_data($key, $value)
{
$storage = new Session;
$storage->set($key, $value);
$storage->deleteMatch('provider.token.');
$data = $storage->get('provider.token.request_token');
$this->assertNull($data);
}
}

View File

@@ -1,42 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth\User;
use Hybridauth\User\Activity;
class ActivityTest extends \PHPUnit\Framework\TestCase
{
public function test_instance_of()
{
$activity = new Activity;
$this->assertInstanceOf('\\Hybridauth\\User\\Activity', $activity);
}
public function test_has_attributes()
{
$this->assertClassHasAttribute('id', Activity::class);
$this->assertClassHasAttribute('date', Activity::class);
$this->assertClassHasAttribute('text', Activity::class);
$this->assertClassHasAttribute('user', Activity::class);
}
public function test_set_attributes()
{
$activity = new Activity;
$activity->id = true;
$activity->date = true;
$activity->text = true;
$activity->user = true;
}
/**
* @expectedException \Hybridauth\Exception\UnexpectedValueException
*/
public function test_property_overloading()
{
$activity = new Activity;
$activity->slug = true;
}
}

View File

@@ -1,48 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth\User;
use Hybridauth\User\Contact;
class ContactTest extends \PHPUnit\Framework\TestCase
{
public function test_instance_of()
{
$contact = new Contact;
$this->assertInstanceOf('\\Hybridauth\\User\\Contact', $contact);
}
public function test_has_attributes()
{
$this->assertClassHasAttribute('identifier', Contact::class);
$this->assertClassHasAttribute('webSiteURL', Contact::class);
$this->assertClassHasAttribute('profileURL', Contact::class);
$this->assertClassHasAttribute('photoURL', Contact::class);
$this->assertClassHasAttribute('displayName', Contact::class);
$this->assertClassHasAttribute('description', Contact::class);
$this->assertClassHasAttribute('email', Contact::class);
}
public function test_set_attributes()
{
$contact = new Contact;
$contact->identifier = true;
$contact->webSiteURL = true;
$contact->profileURL = true;
$contact->photoURL = true;
$contact->displayName = true;
$contact->description = true;
$contact->email = true;
}
/**
* @expectedException \Hybridauth\Exception\UnexpectedValueException
*/
public function test_property_overloading()
{
$contact = new Contact;
$contact->slug = true;
}
}

View File

@@ -1,78 +0,0 @@
<?php
namespace HybridauthTest\Hybridauth\User;
use Hybridauth\User\Profile;
class ProfileTest extends \PHPUnit\Framework\TestCase
{
public function test_instance_of()
{
$profile = new Profile;
$this->assertInstanceOf('\\Hybridauth\\User\\Profile', $profile);
}
public function test_has_attributes()
{
$this->assertClassHasAttribute('identifier', Profile::class);
$this->assertClassHasAttribute('webSiteURL', Profile::class);
$this->assertClassHasAttribute('profileURL', Profile::class);
$this->assertClassHasAttribute('photoURL', Profile::class);
$this->assertClassHasAttribute('displayName', Profile::class);
$this->assertClassHasAttribute('firstName', Profile::class);
$this->assertClassHasAttribute('lastName', Profile::class);
$this->assertClassHasAttribute('description', Profile::class);
$this->assertClassHasAttribute('gender', Profile::class);
$this->assertClassHasAttribute('language', Profile::class);
$this->assertClassHasAttribute('age', Profile::class);
$this->assertClassHasAttribute('birthDay', Profile::class);
$this->assertClassHasAttribute('birthMonth', Profile::class);
$this->assertClassHasAttribute('birthYear', Profile::class);
$this->assertClassHasAttribute('email', Profile::class);
$this->assertClassHasAttribute('emailVerified', Profile::class);
$this->assertClassHasAttribute('phone', Profile::class);
$this->assertClassHasAttribute('address', Profile::class);
$this->assertClassHasAttribute('country', Profile::class);
$this->assertClassHasAttribute('region', Profile::class);
$this->assertClassHasAttribute('city', Profile::class);
$this->assertClassHasAttribute('zip', Profile::class);
}
public function test_set_attributes()
{
$profile = new Profile;
$profile->identifier = true;
$profile->webSiteURL = true;
$profile->profileURL = true;
$profile->photoURL = true;
$profile->displayName = true;
$profile->firstName = true;
$profile->lastName = true;
$profile->description = true;
$profile->gender = true;
$profile->language = true;
$profile->age = true;
$profile->birthDay = true;
$profile->birthMonth = true;
$profile->birthYear = true;
$profile->email = true;
$profile->emailVerified = true;
$profile->phone = true;
$profile->address = true;
$profile->country = true;
$profile->region = true;
$profile->city = true;
$profile->zip = true;
}
/**
* @expectedException \Hybridauth\Exception\UnexpectedValueException
*/
public function test_property_overloading()
{
$profile = new Profile;
$profile->slug = true;
}
}

View File

@@ -167,15 +167,9 @@ Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](h
If this isn't passing, is there something you can do to help?
## Security
Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately.
Please disclose any vulnerabilities found responsibly report security issues to the maintainers privately.
PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity.
PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer).
PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a critical remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html).
See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) for more detail on security issues.
See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) for details on security issues.
## Contributing
Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues).

Some files were not shown because too many files have changed in this diff Show More