Paul Klimov
11 years ago
21 changed files with 2398 additions and 0 deletions
@ -0,0 +1,32 @@ |
|||||||
|
The Yii framework is free software. It is released under the terms of |
||||||
|
the following BSD License. |
||||||
|
|
||||||
|
Copyright © 2008-2013 by Yii Software LLC (http://www.yiisoft.com) |
||||||
|
All rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without |
||||||
|
modification, are permitted provided that the following conditions |
||||||
|
are met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer. |
||||||
|
* Redistributions in binary form must reproduce the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer in |
||||||
|
the documentation and/or other materials provided with the |
||||||
|
distribution. |
||||||
|
* Neither the name of Yii Software LLC nor the names of its |
||||||
|
contributors may be used to endorse or promote products derived |
||||||
|
from this software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||||||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||||
|
POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,30 @@ |
|||||||
|
AuthClient Extension for Yii 2 |
||||||
|
============================== |
||||||
|
|
||||||
|
This extension adds [OpenID](http://openid.net/), [OAuth](http://oauth.net/) and [OAuth2](http://oauth.net/2/) consumers for the Yii 2 framework. |
||||||
|
|
||||||
|
|
||||||
|
Installation |
||||||
|
------------ |
||||||
|
|
||||||
|
The preferred way to install this extension is through [composer](http://getcomposer.org/download/). |
||||||
|
|
||||||
|
Either run |
||||||
|
|
||||||
|
``` |
||||||
|
php composer.phar require yiisoft/yii2-authclient "*" |
||||||
|
``` |
||||||
|
|
||||||
|
or add |
||||||
|
|
||||||
|
```json |
||||||
|
"yiisoft/yii2-authclient": "*" |
||||||
|
``` |
||||||
|
|
||||||
|
to the require section of your composer.json. |
||||||
|
|
||||||
|
|
||||||
|
Usage & Documentation |
||||||
|
--------------------- |
||||||
|
|
||||||
|
This extension... |
@ -0,0 +1,28 @@ |
|||||||
|
{ |
||||||
|
"name": "yiisoft/yii2-authclient", |
||||||
|
"description": "External authentication via OAuth and OpenID for the Yii framework", |
||||||
|
"keywords": ["yii", "OAuth", "OpenID", "auth"], |
||||||
|
"type": "yii2-extension", |
||||||
|
"license": "BSD-3-Clause", |
||||||
|
"support": { |
||||||
|
"issues": "https://github.com/yiisoft/yii2/issues?state=open", |
||||||
|
"forum": "http://www.yiiframework.com/forum/", |
||||||
|
"wiki": "http://www.yiiframework.com/wiki/", |
||||||
|
"irc": "irc://irc.freenode.net/yii", |
||||||
|
"source": "https://github.com/yiisoft/yii2" |
||||||
|
}, |
||||||
|
"authors": [ |
||||||
|
{ |
||||||
|
"name": "Paul Klimov", |
||||||
|
"email": "klimov.paul@gmail.com" |
||||||
|
} |
||||||
|
], |
||||||
|
"require": { |
||||||
|
"yiisoft/yii2": "*", |
||||||
|
"ext-curl": "*" |
||||||
|
}, |
||||||
|
"autoload": { |
||||||
|
"psr-0": { "yii\\authclient\\": "" } |
||||||
|
}, |
||||||
|
"target-dir": "yii/authclient" |
||||||
|
} |
@ -0,0 +1,504 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth; |
||||||
|
|
||||||
|
use yii\base\Component; |
||||||
|
use yii\base\Exception; |
||||||
|
use yii\base\InvalidParamException; |
||||||
|
use Yii; |
||||||
|
use yii\helpers\Json; |
||||||
|
|
||||||
|
/** |
||||||
|
* BaseClient is a base class for the OAuth clients. |
||||||
|
* |
||||||
|
* @see http://oauth.net/ |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
abstract class BaseClient extends Component |
||||||
|
{ |
||||||
|
const CONTENT_TYPE_JSON = 'json'; // JSON format |
||||||
|
const CONTENT_TYPE_URLENCODED = 'urlencoded'; // urlencoded query string, like name1=value1&name2=value2 |
||||||
|
const CONTENT_TYPE_XML = 'xml'; // XML format |
||||||
|
const CONTENT_TYPE_AUTO = 'auto'; // attempts to determine format automatically |
||||||
|
|
||||||
|
/** |
||||||
|
* @var string protocol version. |
||||||
|
*/ |
||||||
|
public $version = '1.0'; |
||||||
|
/** |
||||||
|
* @var string URL, which user will be redirected after authentication at the OAuth provider web site. |
||||||
|
* Note: this should be absolute URL (with http:// or https:// leading). |
||||||
|
* By default current URL will be used. |
||||||
|
*/ |
||||||
|
private $_returnUrl = ''; |
||||||
|
/** |
||||||
|
* @var string API base URL. |
||||||
|
*/ |
||||||
|
public $apiBaseUrl = ''; |
||||||
|
/** |
||||||
|
* @var string authorize URL. |
||||||
|
*/ |
||||||
|
public $authUrl = ''; |
||||||
|
/** |
||||||
|
* @var string auth request scope. |
||||||
|
*/ |
||||||
|
public $scope = ''; |
||||||
|
/** |
||||||
|
* @var array cURL request options. Option values from this field will overwrite corresponding |
||||||
|
* values from {@link defaultCurlOptions()}. |
||||||
|
*/ |
||||||
|
private $_curlOptions = []; |
||||||
|
/** |
||||||
|
* @var Token|array access token instance or its array configuration. |
||||||
|
*/ |
||||||
|
private $_accessToken = null; |
||||||
|
/** |
||||||
|
* @var signature\BaseMethod|array signature method instance or its array configuration. |
||||||
|
*/ |
||||||
|
private $_signatureMethod = []; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $returnUrl return URL |
||||||
|
*/ |
||||||
|
public function setReturnUrl($returnUrl) |
||||||
|
{ |
||||||
|
$this->_returnUrl = $returnUrl; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return string return URL. |
||||||
|
*/ |
||||||
|
public function getReturnUrl() |
||||||
|
{ |
||||||
|
if (empty($this->_returnUrl)) { |
||||||
|
$this->_returnUrl = $this->defaultReturnUrl(); |
||||||
|
} |
||||||
|
return $this->_returnUrl; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param array $curlOptions cURL options. |
||||||
|
*/ |
||||||
|
public function setCurlOptions(array $curlOptions) |
||||||
|
{ |
||||||
|
$this->_curlOptions = $curlOptions; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return array cURL options. |
||||||
|
*/ |
||||||
|
public function getCurlOptions() |
||||||
|
{ |
||||||
|
return $this->_curlOptions; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param array|Token $token |
||||||
|
*/ |
||||||
|
public function setAccessToken($token) |
||||||
|
{ |
||||||
|
if (!is_object($token)) { |
||||||
|
$token = $this->createToken($token); |
||||||
|
} |
||||||
|
$this->_accessToken = $token; |
||||||
|
$this->saveAccessToken($token); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return Token auth token instance. |
||||||
|
*/ |
||||||
|
public function getAccessToken() |
||||||
|
{ |
||||||
|
if (!is_object($this->_accessToken)) { |
||||||
|
$this->_accessToken = $this->restoreAccessToken(); |
||||||
|
} |
||||||
|
return $this->_accessToken; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param array|signature\BaseMethod $signatureMethod signature method instance or its array configuration. |
||||||
|
* @throws InvalidParamException on wrong argument. |
||||||
|
*/ |
||||||
|
public function setSignatureMethod($signatureMethod) |
||||||
|
{ |
||||||
|
if (!is_object($signatureMethod) && !is_array($signatureMethod)) { |
||||||
|
throw new InvalidParamException('"'.get_class($this).'::signatureMethod" should be instance of "\yii\autclient\oauth\signature\BaseMethod" or its array configuration. "' . gettype($signatureMethod) . '" has been given.'); |
||||||
|
} |
||||||
|
$this->_signatureMethod = $signatureMethod; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return signature\BaseMethod signature method instance. |
||||||
|
*/ |
||||||
|
public function getSignatureMethod() |
||||||
|
{ |
||||||
|
if (!is_object($this->_signatureMethod)) { |
||||||
|
$this->_signatureMethod = $this->createSignatureMethod($this->_signatureMethod); |
||||||
|
} |
||||||
|
return $this->_signatureMethod; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes default {@link returnUrl} value. |
||||||
|
* @return string return URL. |
||||||
|
*/ |
||||||
|
protected function defaultReturnUrl() |
||||||
|
{ |
||||||
|
return Yii::$app->getRequest()->getAbsoluteUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sends HTTP request. |
||||||
|
* @param string $method request type. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return array response. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
protected function sendRequest($method, $url, array $params = []) |
||||||
|
{ |
||||||
|
$curlOptions = $this->mergeCurlOptions( |
||||||
|
$this->defaultCurlOptions(), |
||||||
|
$this->getCurlOptions(), |
||||||
|
array( |
||||||
|
CURLOPT_RETURNTRANSFER => true, |
||||||
|
CURLOPT_URL => $url, |
||||||
|
), |
||||||
|
$this->composeRequestCurlOptions(strtoupper($method), $url, $params) |
||||||
|
); |
||||||
|
$curlResource = curl_init(); |
||||||
|
foreach ($curlOptions as $option => $value) { |
||||||
|
curl_setopt($curlResource, $option, $value); |
||||||
|
} |
||||||
|
$response = curl_exec($curlResource); |
||||||
|
$responseHeaders = curl_getinfo($curlResource); |
||||||
|
|
||||||
|
// check cURL error |
||||||
|
$errorNumber = curl_errno($curlResource); |
||||||
|
$errorMessage = curl_error($curlResource); |
||||||
|
|
||||||
|
curl_close($curlResource); |
||||||
|
|
||||||
|
if ($errorNumber > 0) { |
||||||
|
throw new Exception('Curl error requesting "' . $url . '": #' . $errorNumber . ' - ' . $errorMessage); |
||||||
|
} |
||||||
|
if ($responseHeaders['http_code'] != 200) { |
||||||
|
throw new Exception('Request failed with code: ' . $responseHeaders['http_code'] . ', message: ' . $response); |
||||||
|
} |
||||||
|
return $this->processResponse($response, $this->determineContentTypeByHeaders($responseHeaders)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Merge CUrl options. |
||||||
|
* If each options array has an element with the same key value, the latter |
||||||
|
* will overwrite the former. |
||||||
|
* @param array $options1 options to be merged to. |
||||||
|
* @param array $options2 options to be merged from. You can specify additional |
||||||
|
* arrays via third argument, fourth argument etc. |
||||||
|
* @return array merged options (the original options are not changed.) |
||||||
|
*/ |
||||||
|
protected function mergeCurlOptions($options1, $options2) |
||||||
|
{ |
||||||
|
$args = func_get_args(); |
||||||
|
$res = array_shift($args); |
||||||
|
while (!empty($args)) { |
||||||
|
$next = array_shift($args); |
||||||
|
foreach ($next as $k => $v) { |
||||||
|
$res[$k]=$v; |
||||||
|
} |
||||||
|
} |
||||||
|
return $res; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns default cURL options. |
||||||
|
* @return array cURL options. |
||||||
|
*/ |
||||||
|
protected function defaultCurlOptions() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
CURLOPT_USERAGENT => Yii::$app->name . ' OAuth Client', |
||||||
|
CURLOPT_CONNECTTIMEOUT => 30, |
||||||
|
CURLOPT_TIMEOUT => 30, |
||||||
|
CURLOPT_SSL_VERIFYPEER => false, |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes raw response converting it to actual data. |
||||||
|
* @param string $rawResponse raw response. |
||||||
|
* @param string $contentType response content type. |
||||||
|
* @throws Exception on failure. |
||||||
|
* @return array actual response. |
||||||
|
*/ |
||||||
|
protected function processResponse($rawResponse, $contentType = self::CONTENT_TYPE_AUTO) |
||||||
|
{ |
||||||
|
if (empty($rawResponse)) { |
||||||
|
return []; |
||||||
|
} |
||||||
|
switch ($contentType) { |
||||||
|
case self::CONTENT_TYPE_AUTO: { |
||||||
|
$contentType = $this->determineContentTypeByRaw($rawResponse); |
||||||
|
if ($contentType == self::CONTENT_TYPE_AUTO) { |
||||||
|
throw new Exception('Unable to determine response content type automatically.'); |
||||||
|
} |
||||||
|
$response = $this->processResponse($rawResponse, $contentType); |
||||||
|
break; |
||||||
|
} |
||||||
|
case self::CONTENT_TYPE_JSON: { |
||||||
|
$response = Json::decode($rawResponse, true); |
||||||
|
if (isset($response['error'])) { |
||||||
|
throw new Exception('Response error: ' . $response['error']); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case self::CONTENT_TYPE_URLENCODED: { |
||||||
|
$response = []; |
||||||
|
parse_url($rawResponse, $response); |
||||||
|
break; |
||||||
|
} |
||||||
|
case self::CONTENT_TYPE_XML: { |
||||||
|
$response = $this->convertXmlToArray($rawResponse); |
||||||
|
break; |
||||||
|
} |
||||||
|
default: { |
||||||
|
throw new Exception('Unknown response type "' . $contentType . '".'); |
||||||
|
} |
||||||
|
} |
||||||
|
return $response; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts XML document to array. |
||||||
|
* @param string|\SimpleXMLElement $xml xml to process. |
||||||
|
* @return array XML array representation. |
||||||
|
*/ |
||||||
|
protected function convertXmlToArray($xml) |
||||||
|
{ |
||||||
|
if (!is_object($xml)) { |
||||||
|
$xml = simplexml_load_string($xml); |
||||||
|
} |
||||||
|
$result = (array)$xml; |
||||||
|
foreach ($result as $key => $value) { |
||||||
|
if (is_object($value)) { |
||||||
|
$result[$key] = $this->convertXmlToArray($value); |
||||||
|
} |
||||||
|
} |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Attempts to determine HTTP request content type by headers. |
||||||
|
* @param array $headers request headers. |
||||||
|
* @return string content type. |
||||||
|
*/ |
||||||
|
protected function determineContentTypeByHeaders(array $headers) |
||||||
|
{ |
||||||
|
if (isset($headers['content_type'])) { |
||||||
|
if (stripos($headers['content_type'], 'json') !== false) { |
||||||
|
return self::CONTENT_TYPE_JSON; |
||||||
|
} |
||||||
|
if (stripos($headers['content_type'], 'urlencoded') !== false) { |
||||||
|
return self::CONTENT_TYPE_URLENCODED; |
||||||
|
} |
||||||
|
if (stripos($headers['content_type'], 'xml') !== false) { |
||||||
|
return self::CONTENT_TYPE_XML; |
||||||
|
} |
||||||
|
} |
||||||
|
return self::CONTENT_TYPE_AUTO; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Attempts to determine the content type from raw content. |
||||||
|
* @param string $rawContent raw response content. |
||||||
|
* @return string response type. |
||||||
|
*/ |
||||||
|
protected function determineContentTypeByRaw($rawContent) |
||||||
|
{ |
||||||
|
if (preg_match('/^\\{.*\\}$/is', $rawContent)) { |
||||||
|
return self::CONTENT_TYPE_JSON; |
||||||
|
} |
||||||
|
if (preg_match('/^[^=|^&]+=[^=|^&]+(&[^=|^&]+=[^=|^&]+)*$/is', $rawContent)) { |
||||||
|
return self::CONTENT_TYPE_URLENCODED; |
||||||
|
} |
||||||
|
if (preg_match('/^<.*>$/is', $rawContent)) { |
||||||
|
return self::CONTENT_TYPE_XML; |
||||||
|
} |
||||||
|
return self::CONTENT_TYPE_AUTO; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates signature method instance from its configuration. |
||||||
|
* @param array $signatureMethodConfig signature method configuration. |
||||||
|
* @return signature\BaseMethod signature method instance. |
||||||
|
*/ |
||||||
|
protected function createSignatureMethod(array $signatureMethodConfig) |
||||||
|
{ |
||||||
|
if (!array_key_exists('class', $signatureMethodConfig)) { |
||||||
|
$signatureMethodConfig['class'] = signature\HmacSha1::className(); |
||||||
|
} |
||||||
|
return Yii::createObject($signatureMethodConfig); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates token from its configuration. |
||||||
|
* @param array $tokenConfig token configuration. |
||||||
|
* @return Token token instance. |
||||||
|
*/ |
||||||
|
protected function createToken(array $tokenConfig = []) |
||||||
|
{ |
||||||
|
if (!array_key_exists('class', $tokenConfig)) { |
||||||
|
$tokenConfig['class'] = Token::className(); |
||||||
|
} |
||||||
|
return Yii::createObject($tokenConfig); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes URL from base URL and GET params. |
||||||
|
* @param string $url base URL. |
||||||
|
* @param array $params GET params. |
||||||
|
* @return string composed URL. |
||||||
|
*/ |
||||||
|
protected function composeUrl($url, array $params = []) |
||||||
|
{ |
||||||
|
if (strpos($url, '?') === false) { |
||||||
|
$url .= '?'; |
||||||
|
} else { |
||||||
|
$url .= '&'; |
||||||
|
} |
||||||
|
$url .= http_build_query($params, '', '&', PHP_QUERY_RFC3986); |
||||||
|
return $url; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Saves token as persistent state. |
||||||
|
* @param Token $token auth token |
||||||
|
* @return static self reference. |
||||||
|
*/ |
||||||
|
protected function saveAccessToken(Token $token) |
||||||
|
{ |
||||||
|
return $this->setState('token', $token); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Restores access token. |
||||||
|
* @return Token auth token. |
||||||
|
*/ |
||||||
|
protected function restoreAccessToken() |
||||||
|
{ |
||||||
|
$token = $this->getState('token'); |
||||||
|
if (is_object($token)) { |
||||||
|
/* @var $token Token */ |
||||||
|
if ($token->getIsExpired()) { |
||||||
|
$token = $this->refreshAccessToken($token); |
||||||
|
} |
||||||
|
} |
||||||
|
return $token; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets persistent state. |
||||||
|
* @param string $key state key. |
||||||
|
* @param mixed $value state value |
||||||
|
* @return static self reference. |
||||||
|
*/ |
||||||
|
protected function setState($key, $value) |
||||||
|
{ |
||||||
|
$session = Yii::$app->getSession(); |
||||||
|
$key = $this->getStateKeyPrefix() . $key; |
||||||
|
$session->set($key, $value); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns persistent state value. |
||||||
|
* @param string $key state key. |
||||||
|
* @return mixed state value. |
||||||
|
*/ |
||||||
|
protected function getState($key) |
||||||
|
{ |
||||||
|
$session = Yii::$app->getSession(); |
||||||
|
$key = $this->getStateKeyPrefix() . $key; |
||||||
|
$value = $session->get($key); |
||||||
|
return $value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Removes persistent state value. |
||||||
|
* @param string $key state key. |
||||||
|
* @return boolean success. |
||||||
|
*/ |
||||||
|
protected function removeState($key) |
||||||
|
{ |
||||||
|
$session = Yii::$app->getSession(); |
||||||
|
$key = $this->getStateKeyPrefix() . $key; |
||||||
|
$session->remove($key); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns session key prefix, which is used to store internal states. |
||||||
|
* @return string session key prefix. |
||||||
|
*/ |
||||||
|
protected function getStateKeyPrefix() |
||||||
|
{ |
||||||
|
return get_class($this) . '_' . sha1($this->authUrl) . '_'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Performs request to the OAuth API. |
||||||
|
* @param string $apiSubUrl API sub URL, which will be append to [[apiBaseUrl]], or absolute API URL. |
||||||
|
* @param string $method request method. |
||||||
|
* @param array $params request parameters. |
||||||
|
* @return array API response |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
public function api($apiSubUrl, $method = 'GET', array $params = []) |
||||||
|
{ |
||||||
|
if (preg_match('/^https?:\\/\\//is', $apiSubUrl)) { |
||||||
|
$url = $apiSubUrl; |
||||||
|
} else { |
||||||
|
$url = $this->apiBaseUrl . '/' . $apiSubUrl; |
||||||
|
} |
||||||
|
$accessToken = $this->getAccessToken(); |
||||||
|
if (!is_object($accessToken) || !$accessToken->getIsValid()) { |
||||||
|
throw new Exception('Invalid access token.'); |
||||||
|
} |
||||||
|
return $this->apiInternal($accessToken, $url, $method, $params); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes HTTP request CUrl options, which will be merged with the default ones. |
||||||
|
* @param string $method request type. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return array CUrl options. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
abstract protected function composeRequestCurlOptions($method, $url, array $params); |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets new auth token to replace expired one. |
||||||
|
* @param Token $token expired auth token. |
||||||
|
* @return Token new auth token. |
||||||
|
*/ |
||||||
|
abstract public function refreshAccessToken(Token $token); |
||||||
|
|
||||||
|
/** |
||||||
|
* Performs request to the OAuth API. |
||||||
|
* @param Token $accessToken actual access token. |
||||||
|
* @param string $url absolute API URL. |
||||||
|
* @param string $method request method. |
||||||
|
* @param array $params request parameters. |
||||||
|
* @return array API response. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
abstract protected function apiInternal($accessToken, $url, $method, array $params); |
||||||
|
} |
@ -0,0 +1,353 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth; |
||||||
|
|
||||||
|
use yii\base\Exception; |
||||||
|
use Yii; |
||||||
|
|
||||||
|
/** |
||||||
|
* Client1 serves as a client for the OAuth 1/1.0a flow. |
||||||
|
* |
||||||
|
* In oder to acquire access token perform following sequence: |
||||||
|
* |
||||||
|
* ~~~ |
||||||
|
* use yii\authclient\oauth\Client1; |
||||||
|
* |
||||||
|
* $oauthClient = new Client1(); |
||||||
|
* $requestToken = $oauthClient->fetchRequestToken(); // Get request token |
||||||
|
* $url = $oauthClient->buildAuthUrl($requestToken); // Get authorization URL |
||||||
|
* Yii::$app->getResponse()->redirect($url); // Redirect to authorization URL |
||||||
|
* // After user returns at our site: |
||||||
|
* $accessToken = $oauthClient->fetchAccessToken($requestToken); // Upgrade to access token |
||||||
|
* ~~~ |
||||||
|
* |
||||||
|
* @see http://oauth.net/ |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class Client1 extends BaseClient |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string protocol version. |
||||||
|
*/ |
||||||
|
public $version = '1.0'; |
||||||
|
/** |
||||||
|
* @var string OAuth consumer key. |
||||||
|
*/ |
||||||
|
public $consumerKey = ''; |
||||||
|
/** |
||||||
|
* @var string OAuth consumer secret. |
||||||
|
*/ |
||||||
|
public $consumerSecret = ''; |
||||||
|
/** |
||||||
|
* @var string OAuth request token URL. |
||||||
|
*/ |
||||||
|
public $requestTokenUrl = ''; |
||||||
|
/** |
||||||
|
* @var string request token HTTP method. |
||||||
|
*/ |
||||||
|
public $requestTokenMethod = 'GET'; |
||||||
|
/** |
||||||
|
* @var string OAuth access token URL. |
||||||
|
*/ |
||||||
|
public $accessTokenUrl = ''; |
||||||
|
/** |
||||||
|
* @var string access token HTTP method. |
||||||
|
*/ |
||||||
|
public $accessTokenMethod = 'GET'; |
||||||
|
|
||||||
|
/** |
||||||
|
* Fetches the OAuth request token. |
||||||
|
* @param array $params additional request params. |
||||||
|
* @return Token request token. |
||||||
|
*/ |
||||||
|
public function fetchRequestToken(array $params = []) |
||||||
|
{ |
||||||
|
$this->removeState('token'); |
||||||
|
$defaultParams = [ |
||||||
|
'oauth_consumer_key' => $this->consumerKey, |
||||||
|
'oauth_callback' => $this->getReturnUrl(), |
||||||
|
//'xoauth_displayname' => Yii::$app->name, |
||||||
|
]; |
||||||
|
if (!empty($this->scope)) { |
||||||
|
$defaultParams['scope'] = $this->scope; |
||||||
|
} |
||||||
|
$response = $this->sendSignedRequest($this->requestTokenMethod, $this->requestTokenUrl, array_merge($defaultParams, $params)); |
||||||
|
$token = $this->createToken([ |
||||||
|
'params' => $response |
||||||
|
]); |
||||||
|
$this->setState('requestToken', $token); |
||||||
|
return $token; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes user authorization URL. |
||||||
|
* @param Token $requestToken OAuth request token. |
||||||
|
* @param array $params additional request params. |
||||||
|
* @return string authorize URL |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
public function buildAuthUrl(Token $requestToken = null, array $params = []) |
||||||
|
{ |
||||||
|
if (!is_object($requestToken)) { |
||||||
|
$requestToken = $this->getState('requestToken'); |
||||||
|
if (!is_object($requestToken)) { |
||||||
|
throw new Exception('Request token is required to build authorize URL!'); |
||||||
|
} |
||||||
|
} |
||||||
|
$params['oauth_token'] = $requestToken->getToken(); |
||||||
|
return $this->composeUrl($this->authUrl, $params); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Fetches OAuth access token. |
||||||
|
* @param Token $requestToken OAuth request token. |
||||||
|
* @param string $oauthVerifier OAuth verifier. |
||||||
|
* @param array $params additional request params. |
||||||
|
* @return Token OAuth access token. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
public function fetchAccessToken(Token $requestToken = null, $oauthVerifier = null, array $params = []) |
||||||
|
{ |
||||||
|
if (!is_object($requestToken)) { |
||||||
|
$requestToken = $this->getState('requestToken'); |
||||||
|
if (!is_object($requestToken)) { |
||||||
|
throw new Exception('Request token is required to fetch access token!'); |
||||||
|
} |
||||||
|
} |
||||||
|
$this->removeState('requestToken'); |
||||||
|
$defaultParams = [ |
||||||
|
'oauth_consumer_key' => $this->consumerKey, |
||||||
|
'oauth_token' => $requestToken->getToken() |
||||||
|
]; |
||||||
|
if ($oauthVerifier === null) { |
||||||
|
if (isset($_REQUEST['oauth_verifier'])) { |
||||||
|
$oauthVerifier = $_REQUEST['oauth_verifier']; |
||||||
|
} |
||||||
|
} |
||||||
|
if (!empty($oauthVerifier)) { |
||||||
|
$defaultParams['oauth_verifier'] = $oauthVerifier; |
||||||
|
} |
||||||
|
$response = $this->sendSignedRequest($this->accessTokenMethod, $this->accessTokenUrl, array_merge($defaultParams, $params)); |
||||||
|
|
||||||
|
$token = $this->createToken([ |
||||||
|
'params' => $response |
||||||
|
]); |
||||||
|
$this->setAccessToken($token); |
||||||
|
return $token; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sends HTTP request, signed by {@link signatureMethod}. |
||||||
|
* @param string $method request type. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return array response. |
||||||
|
*/ |
||||||
|
protected function sendSignedRequest($method, $url, array $params = []) |
||||||
|
{ |
||||||
|
$params = array_merge($params, $this->generateCommonRequestParams()); |
||||||
|
$params = $this->signRequest($method, $url, $params); |
||||||
|
return $this->sendRequest($method, $url, $params); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes HTTP request CUrl options, which will be merged with the default ones. |
||||||
|
* @param string $method request type. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return array CUrl options. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
protected function composeRequestCurlOptions($method, $url, array $params) |
||||||
|
{ |
||||||
|
$curlOptions = []; |
||||||
|
switch ($method) { |
||||||
|
case 'GET': { |
||||||
|
$curlOptions[CURLOPT_URL] = $this->composeUrl($url, $params); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'POST': { |
||||||
|
$curlOptions[CURLOPT_POST] = true; |
||||||
|
if (!empty($params)){ |
||||||
|
$curlOptions[CURLOPT_POSTFIELDS] = $params; |
||||||
|
} |
||||||
|
$authorizationHeader = $this->composeAuthorizationHeader($params); |
||||||
|
if (!empty($authorizationHeader)/* && $this->curlAuthHeader*/) { |
||||||
|
$curlOptions[CURLOPT_HTTPHEADER] = ['Content-Type: application/atom+xml', $authorizationHeader]; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'HEAD': |
||||||
|
case 'PUT': |
||||||
|
case 'DELETE': { |
||||||
|
$curlOptions[CURLOPT_CUSTOMREQUEST] = $method; |
||||||
|
if (!empty($params)) { |
||||||
|
$curlOptions[CURLOPT_URL] = $this->composeUrl($url, $params); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
default: { |
||||||
|
throw new Exception("Unknown request method '{$method}'."); |
||||||
|
} |
||||||
|
} |
||||||
|
return $curlOptions; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Performs request to the OAuth API. |
||||||
|
* @param Token $accessToken actual access token. |
||||||
|
* @param string $url absolute API URL. |
||||||
|
* @param string $method request method. |
||||||
|
* @param array $params request parameters. |
||||||
|
* @return array API response. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
protected function apiInternal($accessToken, $url, $method, array $params) |
||||||
|
{ |
||||||
|
$params['oauth_consumer_key'] = $this->consumerKey; |
||||||
|
$params['oauth_token'] = $accessToken->getToken(); |
||||||
|
$response = $this->sendSignedRequest($method, $url, $params); |
||||||
|
return $response; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets new auth token to replace expired one. |
||||||
|
* @param Token $token expired auth token. |
||||||
|
* @return Token new auth token. |
||||||
|
*/ |
||||||
|
public function refreshAccessToken(Token $token) |
||||||
|
{ |
||||||
|
// @todo |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes default {@link returnUrl} value. |
||||||
|
* @return string return URL. |
||||||
|
*/ |
||||||
|
protected function defaultReturnUrl() |
||||||
|
{ |
||||||
|
$params = $_GET; |
||||||
|
unset($params['oauth_token']); |
||||||
|
return Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->controller->getRoute(), $params); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates nonce value. |
||||||
|
* @return string nonce value. |
||||||
|
*/ |
||||||
|
protected function generateNonce() |
||||||
|
{ |
||||||
|
return md5(microtime() . mt_rand()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates timestamp. |
||||||
|
* @return integer timestamp. |
||||||
|
*/ |
||||||
|
protected function generateTimestamp() |
||||||
|
{ |
||||||
|
return time(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generate common request params like version, timestamp etc. |
||||||
|
* @return array common request params. |
||||||
|
*/ |
||||||
|
protected function generateCommonRequestParams() |
||||||
|
{ |
||||||
|
$params = [ |
||||||
|
'oauth_version' => $this->version, |
||||||
|
'oauth_nonce' => $this->generateNonce(), |
||||||
|
'oauth_timestamp' => $this->generateTimestamp(), |
||||||
|
]; |
||||||
|
return $params; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sign request with {@link signatureMethod}. |
||||||
|
* @param string $method request method. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return array signed request params. |
||||||
|
*/ |
||||||
|
protected function signRequest($method, $url, array $params) |
||||||
|
{ |
||||||
|
$signatureMethod = $this->getSignatureMethod(); |
||||||
|
$params['oauth_signature_method'] = $signatureMethod->getName(); |
||||||
|
$signatureBaseString = $this->composeSignatureBaseString($method, $url, $params); |
||||||
|
$signatureKey = $this->composeSignatureKey(); |
||||||
|
$params['oauth_signature'] = $signatureMethod->generateSignature($signatureBaseString, $signatureKey); |
||||||
|
return $params; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates signature base string, which will be signed by {@link signatureMethod}. |
||||||
|
* @param string $method request method. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return string base signature string. |
||||||
|
*/ |
||||||
|
protected function composeSignatureBaseString($method, $url, array $params) |
||||||
|
{ |
||||||
|
unset($params['oauth_signature']); |
||||||
|
$parts = [ |
||||||
|
strtoupper($method), |
||||||
|
$url, |
||||||
|
http_build_query($params, '', '&', PHP_QUERY_RFC3986) |
||||||
|
]; |
||||||
|
$parts = array_map('rawurlencode', $parts); |
||||||
|
return implode('&', $parts); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes request signature key. |
||||||
|
* @return string signature key. |
||||||
|
*/ |
||||||
|
protected function composeSignatureKey() |
||||||
|
{ |
||||||
|
$signatureKeyParts = [ |
||||||
|
$this->consumerSecret |
||||||
|
]; |
||||||
|
$accessToken = $this->getAccessToken(); |
||||||
|
if (is_object($accessToken)) { |
||||||
|
$signatureKeyParts[] = $accessToken->getTokenSecret(); |
||||||
|
} else { |
||||||
|
$signatureKeyParts[] = ''; |
||||||
|
} |
||||||
|
$signatureKeyParts = array_map('rawurlencode', $signatureKeyParts); |
||||||
|
return implode('&', $signatureKeyParts); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes authorization header content. |
||||||
|
* @param array $params request params. |
||||||
|
* @param string $realm authorization realm. |
||||||
|
* @return string authorization header content. |
||||||
|
*/ |
||||||
|
protected function composeAuthorizationHeader(array $params, $realm = '') |
||||||
|
{ |
||||||
|
$header = 'Authorization: OAuth'; |
||||||
|
$headerParams = []; |
||||||
|
if (!empty($realm)) { |
||||||
|
$headerParams[] = 'realm="' . rawurlencode($realm) . '"'; |
||||||
|
} |
||||||
|
foreach ($params as $key => $value) { |
||||||
|
if (substr($key, 0, 5) != 'oauth') { |
||||||
|
continue; |
||||||
|
} |
||||||
|
$headerParams[] = rawurlencode($key) . '="' . rawurlencode($value) . '"'; |
||||||
|
} |
||||||
|
if (!empty($headerParams)) { |
||||||
|
$header .= ' ' . implode(', ', $headerParams); |
||||||
|
} |
||||||
|
return $header; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,184 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth; |
||||||
|
|
||||||
|
use Yii; |
||||||
|
use yii\base\Exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* Client2 serves as a client for the OAuth 2 flow. |
||||||
|
* |
||||||
|
* In oder to acquire access token perform following sequence: |
||||||
|
* |
||||||
|
* ~~~ |
||||||
|
* use yii\authclient\oauth\Client2; |
||||||
|
* |
||||||
|
* $oauthClient = new Client2(); |
||||||
|
* $url = $oauthClient->buildAuthUrl(); // Build authorization URL |
||||||
|
* Yii::$app->getResponse()->redirect($url); // Redirect to authorization URL. |
||||||
|
* // After user returns at our site: |
||||||
|
* $code = $_GET['code']; |
||||||
|
* $accessToken = $oauthClient->fetchAccessToken($code); // Get access token |
||||||
|
* ~~~ |
||||||
|
* |
||||||
|
* @see http://oauth.net/2/ |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class Client2 extends BaseClient |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string protocol version. |
||||||
|
*/ |
||||||
|
public $version = '2.0'; |
||||||
|
/** |
||||||
|
* @var string OAuth client ID. |
||||||
|
*/ |
||||||
|
public $clientId = ''; |
||||||
|
/** |
||||||
|
* @var string OAuth client secret. |
||||||
|
*/ |
||||||
|
public $clientSecret = ''; |
||||||
|
/** |
||||||
|
* @var string token request URL endpoint. |
||||||
|
*/ |
||||||
|
public $tokenUrl = ''; |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes user authorization URL. |
||||||
|
* @param array $params additional auth GET params. |
||||||
|
* @return string authorization URL. |
||||||
|
*/ |
||||||
|
public function buildAuthUrl(array $params = []) |
||||||
|
{ |
||||||
|
$defaultParams = [ |
||||||
|
'client_id' => $this->clientId, |
||||||
|
'response_type' => 'code', |
||||||
|
'redirect_uri' => $this->getReturnUrl(), |
||||||
|
'xoauth_displayname' => Yii::$app->name, |
||||||
|
]; |
||||||
|
if (!empty($this->scope)) { |
||||||
|
$defaultParams['scope'] = $this->scope; |
||||||
|
} |
||||||
|
return $this->composeUrl($this->authUrl, array_merge($defaultParams, $params)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Fetches access token from authorization code. |
||||||
|
* @param string $authCode authorization code, usually comes at $_GET['code']. |
||||||
|
* @param array $params additional request params. |
||||||
|
* @return Token access token. |
||||||
|
*/ |
||||||
|
public function fetchAccessToken($authCode, array $params = []) |
||||||
|
{ |
||||||
|
$defaultParams = [ |
||||||
|
'client_id' => $this->clientId, |
||||||
|
'client_secret' => $this->clientSecret, |
||||||
|
'code' => $authCode, |
||||||
|
'grant_type' => 'authorization_code', |
||||||
|
'redirect_uri' => $this->getReturnUrl(), |
||||||
|
]; |
||||||
|
$response = $this->sendRequest('POST', $this->tokenUrl, array_merge($defaultParams, $params)); |
||||||
|
$token = $this->createToken(['params' => $response]); |
||||||
|
$this->setAccessToken($token); |
||||||
|
return $token; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes HTTP request CUrl options, which will be merged with the default ones. |
||||||
|
* @param string $method request type. |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params. |
||||||
|
* @return array CUrl options. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
protected function composeRequestCurlOptions($method, $url, array $params) |
||||||
|
{ |
||||||
|
$curlOptions = []; |
||||||
|
switch ($method) { |
||||||
|
case 'GET': { |
||||||
|
$curlOptions[CURLOPT_URL] = $this->composeUrl($url, $params); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'POST': { |
||||||
|
$curlOptions[CURLOPT_POST] = true; |
||||||
|
$curlOptions[CURLOPT_HTTPHEADER] = ['Content-type: application/x-www-form-urlencoded']; |
||||||
|
$curlOptions[CURLOPT_POSTFIELDS] = http_build_query($params, '', '&', PHP_QUERY_RFC3986); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'HEAD': |
||||||
|
case 'PUT': |
||||||
|
case 'DELETE': { |
||||||
|
$curlOptions[CURLOPT_CUSTOMREQUEST] = $method; |
||||||
|
if (!empty($params)) { |
||||||
|
$curlOptions[CURLOPT_URL] = $this->composeUrl($url, $params); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
default: { |
||||||
|
throw new Exception("Unknown request method '{$method}'."); |
||||||
|
} |
||||||
|
} |
||||||
|
return $curlOptions; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Performs request to the OAuth API. |
||||||
|
* @param Token $accessToken actual access token. |
||||||
|
* @param string $url absolute API URL. |
||||||
|
* @param string $method request method. |
||||||
|
* @param array $params request parameters. |
||||||
|
* @return array API response. |
||||||
|
* @throws Exception on failure. |
||||||
|
*/ |
||||||
|
protected function apiInternal($accessToken, $url, $method, array $params) |
||||||
|
{ |
||||||
|
$params['access_token'] = $accessToken->getToken(); |
||||||
|
return $this->sendRequest($method, $url, $params); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets new auth token to replace expired one. |
||||||
|
* @param Token $token expired auth token. |
||||||
|
* @return Token new auth token. |
||||||
|
*/ |
||||||
|
public function refreshAccessToken(Token $token) |
||||||
|
{ |
||||||
|
$params = [ |
||||||
|
'client_id' => $this->clientId, |
||||||
|
'client_secret' => $this->clientSecret, |
||||||
|
'grant_type' => 'refresh_token' |
||||||
|
]; |
||||||
|
$params = array_merge($token->getParams(), $params); |
||||||
|
$response = $this->sendRequest('POST', $this->tokenUrl, $params); |
||||||
|
return $response; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes default {@link returnUrl} value. |
||||||
|
* @return string return URL. |
||||||
|
*/ |
||||||
|
protected function defaultReturnUrl() |
||||||
|
{ |
||||||
|
$params = $_GET; |
||||||
|
unset($params['code']); |
||||||
|
return Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->controller->getRoute(), $params); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates token from its configuration. |
||||||
|
* @param array $tokenConfig token configuration. |
||||||
|
* @return Token token instance. |
||||||
|
*/ |
||||||
|
protected function createToken(array $tokenConfig = []) |
||||||
|
{ |
||||||
|
$tokenConfig['tokenParamKey'] = 'access_token'; |
||||||
|
return parent::createToken($tokenConfig); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,186 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth; |
||||||
|
|
||||||
|
use yii\base\Object; |
||||||
|
|
||||||
|
/** |
||||||
|
* Token represents OAuth token. |
||||||
|
* |
||||||
|
* @property array $params token parameters. |
||||||
|
* @property string $token token value. |
||||||
|
* @property string $tokenSecret token secret value. |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class Token extends Object |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string key in {@link _params} array, which stores token key. |
||||||
|
*/ |
||||||
|
public $tokenParamKey = 'oauth_token'; |
||||||
|
/** |
||||||
|
* @var string key in {@link _params} array, which stores token secret key. |
||||||
|
*/ |
||||||
|
public $tokenSecretParamKey = 'oauth_token_secret'; |
||||||
|
/** |
||||||
|
* @var string key in {@link _params} array, which stores token expiration duration. |
||||||
|
* If not set will attempt to fetch its value automatically. |
||||||
|
*/ |
||||||
|
private $_expireDurationParamKey; |
||||||
|
/** |
||||||
|
* @var array token parameters. |
||||||
|
*/ |
||||||
|
private $_params = []; |
||||||
|
/** |
||||||
|
* @var integer object creation timestamp. |
||||||
|
*/ |
||||||
|
public $createTimestamp; |
||||||
|
|
||||||
|
public function init() |
||||||
|
{ |
||||||
|
if ($this->createTimestamp === null) { |
||||||
|
$this->createTimestamp = time(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $expireDurationParamKey expire duration param key. |
||||||
|
*/ |
||||||
|
public function setExpireDurationParamKey($expireDurationParamKey) { |
||||||
|
$this->_expireDurationParamKey = $expireDurationParamKey; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return string expire duration param key. |
||||||
|
*/ |
||||||
|
public function getExpireDurationParamKey() { |
||||||
|
if ($this->_expireDurationParamKey === null) { |
||||||
|
$this->_expireDurationParamKey = $this->defaultExpireDurationParamKey(); |
||||||
|
} |
||||||
|
return $this->_expireDurationParamKey; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function getParams() { |
||||||
|
return $this->_params; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param array $params |
||||||
|
*/ |
||||||
|
public function setParams(array $params) { |
||||||
|
$this->_params = $params; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets param by name. |
||||||
|
* @param string $name param name. |
||||||
|
* @param mixed $value param value, |
||||||
|
*/ |
||||||
|
public function setParam($name, $value) { |
||||||
|
$this->_params[$name] = $value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns param by name. |
||||||
|
* @param string $name param name. |
||||||
|
* @return mixed param value. |
||||||
|
*/ |
||||||
|
public function getParam($name) { |
||||||
|
return isset($this->_params[$name]) ? $this->_params[$name] : null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets token value. |
||||||
|
* @param string $token token value. |
||||||
|
* @return static self reference. |
||||||
|
*/ |
||||||
|
public function setToken($token) { |
||||||
|
$this->setParam($this->tokenParamKey, $token); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns token value. |
||||||
|
* @return string token value. |
||||||
|
*/ |
||||||
|
public function getToken() { |
||||||
|
return $this->getParam($this->tokenParamKey); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the token secret value. |
||||||
|
* @param string $tokenSecret token secret. |
||||||
|
*/ |
||||||
|
public function setTokenSecret($tokenSecret) { |
||||||
|
$this->setParam($this->tokenSecretParamKey, $tokenSecret); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the token secret value. |
||||||
|
* @return string token secret value. |
||||||
|
*/ |
||||||
|
public function getTokenSecret() { |
||||||
|
return $this->getParam($this->tokenSecretParamKey); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets token expire duration. |
||||||
|
* @param string $expireDuration token expiration duration. |
||||||
|
*/ |
||||||
|
public function setExpireDuration($expireDuration) { |
||||||
|
$this->setParam($this->getExpireDurationParamKey(), $expireDuration); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the token expiration duration. |
||||||
|
* @return integer token expiration duration. |
||||||
|
*/ |
||||||
|
public function getExpireDuration() { |
||||||
|
return $this->getParam($this->getExpireDurationParamKey()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Fetches default expire duration param key. |
||||||
|
* @return string expire duration param key. |
||||||
|
*/ |
||||||
|
protected function defaultExpireDurationParamKey() { |
||||||
|
$expireDurationParamKey = 'expires_in'; |
||||||
|
foreach ($this->getParams() as $name => $value) { |
||||||
|
if (strpos($name, 'expir') !== false) { |
||||||
|
$expireDurationParamKey = $name; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return $expireDurationParamKey; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Checks if token has expired. |
||||||
|
* @return boolean is token expired. |
||||||
|
*/ |
||||||
|
public function getIsExpired() { |
||||||
|
$expirationDuration = $this->getExpireDuration(); |
||||||
|
if (empty($expirationDuration)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return (time() >= ($this->createTimestamp + $expirationDuration)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Checks if token is valid. |
||||||
|
* @return boolean is token valid. |
||||||
|
*/ |
||||||
|
public function getIsValid() { |
||||||
|
$token = $this->getToken(); |
||||||
|
return (!empty($token) && !$this->getIsExpired()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yii\base\Object; |
||||||
|
|
||||||
|
/** |
||||||
|
* BaseMethod is a base class for the OAuth signature methods. |
||||||
|
* |
||||||
|
* @property string $name method canonical name. This property is read-only. |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
abstract class BaseMethod extends Object |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Return the canonical name of the Signature Method. |
||||||
|
* @return string method name. |
||||||
|
*/ |
||||||
|
abstract public function getName(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates OAuth request signature. |
||||||
|
* @param string $baseString signature base string. |
||||||
|
* @param string $key signature key. |
||||||
|
* @return string signature string. |
||||||
|
*/ |
||||||
|
abstract public function generateSignature($baseString, $key); |
||||||
|
|
||||||
|
/** |
||||||
|
* Verifies given OAuth request. |
||||||
|
* @param string $signature signature to be verified. |
||||||
|
* @param string $baseString signature base string. |
||||||
|
* @param string $key signature key. |
||||||
|
* @return boolean success. |
||||||
|
*/ |
||||||
|
public function verify($signature, $baseString, $key) |
||||||
|
{ |
||||||
|
$expectedSignature = $this->generateSignature($baseString, $key); |
||||||
|
if (empty($signature) || empty($expectedSignature)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return (strcmp($expectedSignature, $signature) === 0); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yii\base\NotSupportedException; |
||||||
|
|
||||||
|
/** |
||||||
|
* HmacSha1 represents 'HMAC-SHA1' signature method. |
||||||
|
* |
||||||
|
* Note: This class require PHP "Hash" extension({@link http://php.net/manual/en/book.hash.php}). |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class HmacSha1 extends BaseMethod |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
if (!function_exists('hash_hmac')) { |
||||||
|
throw new NotSupportedException('PHP "Hash" extension is required.'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function getName() |
||||||
|
{ |
||||||
|
return 'HMAC-SHA1'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function generateSignature($baseString, $key) |
||||||
|
{ |
||||||
|
return base64_encode(hash_hmac('sha1', $baseString, $key, true)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth\signature; |
||||||
|
|
||||||
|
/** |
||||||
|
* PlainText represents 'PLAINTEXT' signature method. |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class PlainText extends BaseMethod |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function getName() |
||||||
|
{ |
||||||
|
return 'PLAINTEXT'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function generateSignature($baseString, $key) |
||||||
|
{ |
||||||
|
return $key; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,168 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yii\base\InvalidConfigException; |
||||||
|
use yii\base\NotSupportedException; |
||||||
|
|
||||||
|
/** |
||||||
|
* RsaSha1 represents 'RSA-SHA1' signature method. |
||||||
|
* |
||||||
|
* Note: This class require PHP "OpenSSL" extension({@link http://php.net/manual/en/book.openssl.php}). |
||||||
|
* |
||||||
|
* @property string $privateCertificate OpenSSL private key certificate content. |
||||||
|
* @property string $publicCertificate OpenSSL public key certificate content. |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class RsaSha1 extends BaseMethod |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string OpenSSL private key certificate content. |
||||||
|
* This value can be fetched from file specified by {@link privateCertificateFile}. |
||||||
|
*/ |
||||||
|
protected $_privateCertificate; |
||||||
|
/** |
||||||
|
* @var string OpenSSL public key certificate content. |
||||||
|
* This value can be fetched from file specified by {@link publicCertificateFile}. |
||||||
|
*/ |
||||||
|
protected $_publicCertificate; |
||||||
|
/** |
||||||
|
* @var string path to the file, which holds private key certificate. |
||||||
|
*/ |
||||||
|
public $privateCertificateFile = ''; |
||||||
|
/** |
||||||
|
* @var string path to the file, which holds public key certificate. |
||||||
|
*/ |
||||||
|
public $publicCertificateFile = ''; |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
if (!function_exists('openssl_sign')) { |
||||||
|
throw new NotSupportedException('PHP "OpenSSL" extension is required.'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $publicCertificate public key certificate content. |
||||||
|
*/ |
||||||
|
public function setPublicCertificate($publicCertificate) |
||||||
|
{ |
||||||
|
$this->_publicCertificate = $publicCertificate; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return string public key certificate content. |
||||||
|
*/ |
||||||
|
public function getPublicCertificate() |
||||||
|
{ |
||||||
|
if ($this->_publicCertificate === null) { |
||||||
|
$this->_publicCertificate = $this->initPublicCertificate(); |
||||||
|
} |
||||||
|
return $this->_publicCertificate; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $privateCertificate private key certificate content. |
||||||
|
*/ |
||||||
|
public function setPrivateCertificate($privateCertificate) |
||||||
|
{ |
||||||
|
$this->_privateCertificate = $privateCertificate; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return string private key certificate content. |
||||||
|
*/ |
||||||
|
public function getPrivateCertificate() |
||||||
|
{ |
||||||
|
if ($this->_privateCertificate === null) { |
||||||
|
$this->_privateCertificate = $this->initPrivateCertificate(); |
||||||
|
} |
||||||
|
return $this->_privateCertificate; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function getName() |
||||||
|
{ |
||||||
|
return 'RSA-SHA1'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates initial value for {@link publicCertificate}. |
||||||
|
* This method will attempt to fetch the certificate value from {@link publicCertificateFile} file. |
||||||
|
* @throws InvalidConfigException on failure. |
||||||
|
* @return string public certificate content. |
||||||
|
*/ |
||||||
|
protected function initPublicCertificate() |
||||||
|
{ |
||||||
|
if (!empty($this->publicCertificateFile)) { |
||||||
|
if (!file_exists($this->publicCertificateFile)) { |
||||||
|
throw new InvalidConfigException("Public certificate file '{$this->publicCertificateFile}' does not exist!"); |
||||||
|
} |
||||||
|
return file_get_contents($this->publicCertificateFile); |
||||||
|
} else { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates initial value for {@link privateCertificate}. |
||||||
|
* This method will attempt to fetch the certificate value from {@link privateCertificateFile} file. |
||||||
|
* @throws InvalidConfigException on failure. |
||||||
|
* @return string private certificate content. |
||||||
|
*/ |
||||||
|
protected function initPrivateCertificate() |
||||||
|
{ |
||||||
|
if (!empty($this->privateCertificateFile)) { |
||||||
|
if (!file_exists($this->privateCertificateFile)) { |
||||||
|
throw new InvalidConfigException("Private certificate file '{$this->privateCertificateFile}' does not exist!"); |
||||||
|
} |
||||||
|
return file_get_contents($this->privateCertificateFile); |
||||||
|
} else { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function generateSignature($baseString, $key) |
||||||
|
{ |
||||||
|
$privateCertificateContent = $this->getPrivateCertificate(); |
||||||
|
// Pull the private key ID from the certificate |
||||||
|
$privateKeyId = openssl_pkey_get_private($privateCertificateContent); |
||||||
|
// Sign using the key |
||||||
|
openssl_sign($baseString, $signature, $privateKeyId); |
||||||
|
// Release the key resource |
||||||
|
openssl_free_key($privateKeyId); |
||||||
|
return base64_encode($signature); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @inheritdoc |
||||||
|
*/ |
||||||
|
public function verify($signature, $baseString, $key) |
||||||
|
{ |
||||||
|
$decodedSignature = base64_decode($signature); |
||||||
|
// Fetch the public key cert based on the request |
||||||
|
$publicCertificate = $this->getPublicCertificate(); |
||||||
|
// Pull the public key ID from the certificate |
||||||
|
$publicKeyId = openssl_pkey_get_public($publicCertificate); |
||||||
|
// Check the computed signature against the one passed in the query |
||||||
|
$verificationResult = openssl_verify($baseString, $decodedSignature, $publicKeyId); |
||||||
|
// Release the key resource |
||||||
|
openssl_free_key($publicKeyId); |
||||||
|
return ($verificationResult == 1); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\authclient\openid; |
||||||
|
|
||||||
|
use yii\base\Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class Client |
||||||
|
* |
||||||
|
* @see http://openid.net/ |
||||||
|
* |
||||||
|
* @author Paul Klimov <klimov.paul@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class Client extends Component |
||||||
|
{ |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient; |
||||||
|
|
||||||
|
use yii\helpers\FileHelper; |
||||||
|
use Yii; |
||||||
|
|
||||||
|
/** |
||||||
|
* TestCase for "authclient" extension. |
||||||
|
*/ |
||||||
|
class TestCase extends \yiiunit\TestCase |
||||||
|
{ |
||||||
|
public static function setUpBeforeClass() |
||||||
|
{ |
||||||
|
static::loadClassMap(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds sphinx extension files to [[Yii::$classPath]], |
||||||
|
* avoiding the necessity of usage Composer autoloader. |
||||||
|
*/ |
||||||
|
protected static function loadClassMap() |
||||||
|
{ |
||||||
|
$baseNameSpace = 'yii/authclient'; |
||||||
|
$basePath = realpath(__DIR__. '/../../../../extensions/yii/authclient'); |
||||||
|
$files = FileHelper::findFiles($basePath); |
||||||
|
foreach ($files as $file) { |
||||||
|
$classRelativePath = str_replace($basePath, '', $file); |
||||||
|
$classFullName = str_replace(['/', '.php'], ['\\', ''], $baseNameSpace . $classRelativePath); |
||||||
|
Yii::$classMap[$classFullName] = $file; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,251 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth; |
||||||
|
|
||||||
|
use yii\authclient\oauth\signature\PlainText; |
||||||
|
use yii\authclient\oauth\Token; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
use yii\authclient\oauth\BaseClient; |
||||||
|
|
||||||
|
class BaseClientTest extends TestCase |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Creates test OAuth client instance. |
||||||
|
* @return BaseClient oauth client. |
||||||
|
*/ |
||||||
|
protected function createOAuthClient() |
||||||
|
{ |
||||||
|
$oauthClient = $this->getMock(BaseClient::className(), ['setState', 'getState', 'composeRequestCurlOptions', 'refreshAccessToken', 'apiInternal']); |
||||||
|
$oauthClient->expects($this->any())->method('setState')->will($this->returnValue($oauthClient)); |
||||||
|
$oauthClient->expects($this->any())->method('getState')->will($this->returnValue(null)); |
||||||
|
return $oauthClient; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Invokes the OAuth client method even if it is protected. |
||||||
|
* @param BaseClient $oauthClient OAuth client instance. |
||||||
|
* @param string $methodName name of the method to be invoked. |
||||||
|
* @param array $arguments method arguments. |
||||||
|
* @return mixed method invoke result. |
||||||
|
*/ |
||||||
|
protected function invokeOAuthClientMethod($oauthClient, $methodName, array $arguments = []) |
||||||
|
{ |
||||||
|
$classReflection = new \ReflectionClass(get_class($oauthClient)); |
||||||
|
$methodReflection = $classReflection->getMethod($methodName); |
||||||
|
$methodReflection->setAccessible(true); |
||||||
|
$result = $methodReflection->invokeArgs($oauthClient, $arguments); |
||||||
|
$methodReflection->setAccessible(false); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
// Tests : |
||||||
|
|
||||||
|
public function testSetGet() |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
|
||||||
|
$returnUrl = 'http://test.return.url'; |
||||||
|
$oauthClient->setReturnUrl($returnUrl); |
||||||
|
$this->assertEquals($returnUrl, $oauthClient->getReturnUrl(), 'Unable to setup return URL!'); |
||||||
|
|
||||||
|
$curlOptions = [ |
||||||
|
'option1' => 'value1', |
||||||
|
'option2' => 'value2', |
||||||
|
]; |
||||||
|
$oauthClient->setCurlOptions($curlOptions); |
||||||
|
$this->assertEquals($curlOptions, $oauthClient->getCurlOptions(), 'Unable to setup cURL options!'); |
||||||
|
} |
||||||
|
|
||||||
|
public function testSetupComponents() |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
|
||||||
|
$oauthToken = new Token(); |
||||||
|
$oauthClient->setAccessToken($oauthToken); |
||||||
|
$this->assertEquals($oauthToken, $oauthClient->getAccessToken(), 'Unable to setup token!'); |
||||||
|
|
||||||
|
$oauthSignatureMethod = new PlainText(); |
||||||
|
$oauthClient->setSignatureMethod($oauthSignatureMethod); |
||||||
|
$this->assertEquals($oauthSignatureMethod, $oauthClient->getSignatureMethod(), 'Unable to setup signature method!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testSetupComponents |
||||||
|
*/ |
||||||
|
public function testSetupComponentsByConfig() |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
|
||||||
|
$oauthToken = [ |
||||||
|
'token' => 'test_token', |
||||||
|
'tokenSecret' => 'test_token_secret', |
||||||
|
]; |
||||||
|
$oauthClient->setAccessToken($oauthToken); |
||||||
|
$this->assertEquals($oauthToken['token'], $oauthClient->getAccessToken()->getToken(), 'Unable to setup token as config!'); |
||||||
|
|
||||||
|
$oauthSignatureMethod = [ |
||||||
|
'class' => 'yii\authclient\oauth\signature\PlainText' |
||||||
|
]; |
||||||
|
$oauthClient->setSignatureMethod($oauthSignatureMethod); |
||||||
|
$returnedSignatureMethod = $oauthClient->getSignatureMethod(); |
||||||
|
$this->assertEquals($oauthSignatureMethod['class'], get_class($returnedSignatureMethod), 'Unable to setup signature method as config!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Data provider for [[testComposeUrl()]]. |
||||||
|
* @return array test data. |
||||||
|
*/ |
||||||
|
public function composeUrlDataProvider() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
[ |
||||||
|
'http://test.url', |
||||||
|
[ |
||||||
|
'param1' => 'value1', |
||||||
|
'param2' => 'value2', |
||||||
|
], |
||||||
|
'http://test.url?param1=value1¶m2=value2', |
||||||
|
], |
||||||
|
[ |
||||||
|
'http://test.url?with=some', |
||||||
|
[ |
||||||
|
'param1' => 'value1', |
||||||
|
'param2' => 'value2', |
||||||
|
], |
||||||
|
'http://test.url?with=some¶m1=value1¶m2=value2', |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dataProvider composeUrlDataProvider |
||||||
|
* |
||||||
|
* @param string $url request URL. |
||||||
|
* @param array $params request params |
||||||
|
* @param string $expectedUrl expected composed URL. |
||||||
|
*/ |
||||||
|
public function testComposeUrl($url, array $params, $expectedUrl) |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
$composedUrl = $this->invokeOAuthClientMethod($oauthClient, 'composeUrl', [$url, $params]); |
||||||
|
$this->assertEquals($expectedUrl, $composedUrl); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Data provider for {@link testDetermineContentTypeByHeaders}. |
||||||
|
* @return array test data. |
||||||
|
*/ |
||||||
|
public function determineContentTypeByHeadersDataProvider() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
[ |
||||||
|
['content_type' => 'application/json'], |
||||||
|
'json' |
||||||
|
], |
||||||
|
[ |
||||||
|
['content_type' => 'application/x-www-form-urlencoded'], |
||||||
|
'urlencoded' |
||||||
|
], |
||||||
|
[ |
||||||
|
['content_type' => 'application/xml'], |
||||||
|
'xml' |
||||||
|
], |
||||||
|
[ |
||||||
|
['some_header' => 'some_header_value'], |
||||||
|
'auto' |
||||||
|
], |
||||||
|
[ |
||||||
|
['content_type' => 'unknown'], |
||||||
|
'auto' |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dataProvider determineContentTypeByHeadersDataProvider |
||||||
|
* |
||||||
|
* @param array $headers request headers. |
||||||
|
* @param string $expectedResponseType expected response type. |
||||||
|
*/ |
||||||
|
public function testDetermineContentTypeByHeaders(array $headers, $expectedResponseType) |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
$responseType = $this->invokeOAuthClientMethod($oauthClient, 'determineContentTypeByHeaders', [$headers]); |
||||||
|
$this->assertEquals($expectedResponseType, $responseType); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Data provider for [[testDetermineContentTypeByRaw]]. |
||||||
|
* @return array test data. |
||||||
|
*/ |
||||||
|
public function determineContentTypeByRawDataProvider() |
||||||
|
{ |
||||||
|
return array( |
||||||
|
['{name: value}', 'json'], |
||||||
|
['name=value', 'urlencoded'], |
||||||
|
['name1=value1&name2=value2', 'urlencoded'], |
||||||
|
['<?xml version="1.0" encoding="UTF-8"?><tag>Value</tag>', 'xml'],
|
||||||
|
['<tag>Value</tag>', 'xml'], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dataProvider determineContentTypeByRawDataProvider |
||||||
|
* |
||||||
|
* @param string $rawResponse raw response content. |
||||||
|
* @param string $expectedResponseType expected response type. |
||||||
|
*/ |
||||||
|
public function testDetermineContentTypeByRaw($rawResponse, $expectedResponseType) |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
$responseType = $this->invokeOAuthClientMethod($oauthClient, 'determineContentTypeByRaw', [$rawResponse]); |
||||||
|
$this->assertEquals($expectedResponseType, $responseType); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Data provider for [[testApiUrl]]. |
||||||
|
* @return array test data. |
||||||
|
*/ |
||||||
|
public function apiUrlDataProvider() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
[ |
||||||
|
'http://api.base.url', |
||||||
|
'sub/url', |
||||||
|
'http://api.base.url/sub/url', |
||||||
|
], |
||||||
|
[ |
||||||
|
'http://api.base.url', |
||||||
|
'http://api.base.url/sub/url', |
||||||
|
'http://api.base.url/sub/url', |
||||||
|
], |
||||||
|
[ |
||||||
|
'http://api.base.url', |
||||||
|
'https://api.base.url/sub/url', |
||||||
|
'https://api.base.url/sub/url', |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dataProvider apiUrlDataProvider |
||||||
|
* |
||||||
|
* @param $apiBaseUrl |
||||||
|
* @param $apiSubUrl |
||||||
|
* @param $expectedApiFullUrl |
||||||
|
*/ |
||||||
|
public function testApiUrl($apiBaseUrl, $apiSubUrl, $expectedApiFullUrl) |
||||||
|
{ |
||||||
|
$oauthClient = $this->createOAuthClient(); |
||||||
|
$oauthClient->expects($this->any())->method('apiInternal')->will($this->returnArgument(1)); |
||||||
|
|
||||||
|
$accessToken = new Token(); |
||||||
|
$accessToken->setToken('test_access_token'); |
||||||
|
$accessToken->setExpireDuration(1000); |
||||||
|
$oauthClient->setAccessToken($accessToken); |
||||||
|
|
||||||
|
$oauthClient->apiBaseUrl = $apiBaseUrl; |
||||||
|
|
||||||
|
$this->assertEquals($expectedApiFullUrl, $oauthClient->api($apiSubUrl)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth; |
||||||
|
|
||||||
|
use yii\authclient\oauth\Client1; |
||||||
|
use yii\authclient\oauth\signature\PlainText; |
||||||
|
use yii\authclient\oauth\Token; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class Client1Test extends TestCase |
||||||
|
{ |
||||||
|
protected function setUp() |
||||||
|
{ |
||||||
|
$this->mockApplication([], '\yii\web\Application'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Invokes the OAuth client method even if it is protected. |
||||||
|
* @param Client1 $oauthClient OAuth client instance. |
||||||
|
* @param string $methodName name of the method to be invoked. |
||||||
|
* @param array $arguments method arguments. |
||||||
|
* @return mixed method invoke result. |
||||||
|
*/ |
||||||
|
protected function invokeOAuthClientMethod($oauthClient, $methodName, array $arguments = []) |
||||||
|
{ |
||||||
|
$classReflection = new \ReflectionClass(get_class($oauthClient)); |
||||||
|
$methodReflection = $classReflection->getMethod($methodName); |
||||||
|
$methodReflection->setAccessible(true); |
||||||
|
$result = $methodReflection->invokeArgs($oauthClient, $arguments); |
||||||
|
$methodReflection->setAccessible(false); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
// Tests : |
||||||
|
|
||||||
|
public function testSignRequest() |
||||||
|
{ |
||||||
|
$oauthClient = new Client1(); |
||||||
|
|
||||||
|
$oauthSignatureMethod = new PlainText(); |
||||||
|
$oauthClient->setSignatureMethod($oauthSignatureMethod); |
||||||
|
|
||||||
|
$signedParams = $this->invokeOAuthClientMethod($oauthClient, 'signRequest', ['GET', 'http://test.url', []]); |
||||||
|
$this->assertNotEmpty($signedParams['oauth_signature'], 'Unable to sign request!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Data provider for [[testComposeAuthorizationHeader()]]. |
||||||
|
* @return array test data. |
||||||
|
*/ |
||||||
|
public function composeAuthorizationHeaderDataProvider() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
[ |
||||||
|
'', |
||||||
|
[ |
||||||
|
'oauth_test_name_1' => 'oauth_test_value_1', |
||||||
|
'oauth_test_name_2' => 'oauth_test_value_2', |
||||||
|
], |
||||||
|
'Authorization: OAuth oauth_test_name_1="oauth_test_value_1", oauth_test_name_2="oauth_test_value_2"' |
||||||
|
], |
||||||
|
[ |
||||||
|
'test_realm', |
||||||
|
[ |
||||||
|
'oauth_test_name_1' => 'oauth_test_value_1', |
||||||
|
'oauth_test_name_2' => 'oauth_test_value_2', |
||||||
|
], |
||||||
|
'Authorization: OAuth realm="test_realm", oauth_test_name_1="oauth_test_value_1", oauth_test_name_2="oauth_test_value_2"' |
||||||
|
], |
||||||
|
[ |
||||||
|
'', |
||||||
|
[ |
||||||
|
'oauth_test_name_1' => 'oauth_test_value_1', |
||||||
|
'test_name_2' => 'test_value_2', |
||||||
|
], |
||||||
|
'Authorization: OAuth oauth_test_name_1="oauth_test_value_1"' |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dataProvider composeAuthorizationHeaderDataProvider |
||||||
|
* |
||||||
|
* @param string $realm authorization realm. |
||||||
|
* @param array $params request params. |
||||||
|
* @param string $expectedAuthorizationHeader expected authorization header. |
||||||
|
*/ |
||||||
|
public function testComposeAuthorizationHeader($realm, array $params, $expectedAuthorizationHeader) |
||||||
|
{ |
||||||
|
$oauthClient = new Client1(); |
||||||
|
$authorizationHeader = $this->invokeOAuthClientMethod($oauthClient, 'composeAuthorizationHeader', [$params, $realm]); |
||||||
|
$this->assertEquals($expectedAuthorizationHeader, $authorizationHeader); |
||||||
|
} |
||||||
|
|
||||||
|
public function testBuildAuthUrl() { |
||||||
|
$oauthClient = new Client1(); |
||||||
|
$authUrl = 'http://test.auth.url'; |
||||||
|
$oauthClient->authUrl = $authUrl; |
||||||
|
|
||||||
|
$requestTokenToken = 'test_request_token'; |
||||||
|
$requestToken = new Token(); |
||||||
|
$requestToken->setToken($requestTokenToken); |
||||||
|
|
||||||
|
$builtAuthUrl = $oauthClient->buildAuthUrl($requestToken); |
||||||
|
|
||||||
|
$this->assertContains($authUrl, $builtAuthUrl, 'No auth URL present!'); |
||||||
|
$this->assertContains($requestTokenToken, $builtAuthUrl, 'No token present!'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth; |
||||||
|
|
||||||
|
use yii\authclient\oauth\Client2; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class Client2Test extends TestCase |
||||||
|
{ |
||||||
|
protected function setUp() |
||||||
|
{ |
||||||
|
$this->mockApplication([], '\yii\web\Application'); |
||||||
|
} |
||||||
|
|
||||||
|
// Tests : |
||||||
|
|
||||||
|
public function testBuildAuthUrl() |
||||||
|
{ |
||||||
|
$oauthClient = new Client2(); |
||||||
|
$authUrl = 'http://test.auth.url'; |
||||||
|
$oauthClient->authUrl = $authUrl; |
||||||
|
$clientId = 'test_client_id'; |
||||||
|
$oauthClient->clientId = $clientId; |
||||||
|
$returnUrl = 'http://test.return.url'; |
||||||
|
$oauthClient->setReturnUrl($returnUrl); |
||||||
|
|
||||||
|
$builtAuthUrl = $oauthClient->buildAuthUrl(); |
||||||
|
|
||||||
|
$this->assertContains($authUrl, $builtAuthUrl, 'No auth URL present!'); |
||||||
|
$this->assertContains($clientId, $builtAuthUrl, 'No client id present!'); |
||||||
|
$this->assertContains(rawurlencode($returnUrl), $builtAuthUrl, 'No return URL present!'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth; |
||||||
|
|
||||||
|
use yii\authclient\oauth\Token; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class TokenTest extends TestCase |
||||||
|
{ |
||||||
|
public function testCreate() |
||||||
|
{ |
||||||
|
$config = [ |
||||||
|
'tokenParamKey' => 'test_token_param_key', |
||||||
|
'tokenSecretParamKey' => 'test_token_secret_param_key', |
||||||
|
]; |
||||||
|
$oauthToken = new Token($config); |
||||||
|
$this->assertTrue(is_object($oauthToken), 'Unable to create access token!'); |
||||||
|
foreach ($config as $name => $value) { |
||||||
|
$this->assertEquals($value, $oauthToken->$name, 'Unable to setup attributes by constructor!'); |
||||||
|
} |
||||||
|
$this->assertTrue($oauthToken->createTimestamp > 0, 'Unable to fill create timestamp!'); |
||||||
|
} |
||||||
|
|
||||||
|
public function testSetupParams() |
||||||
|
{ |
||||||
|
$oauthToken = new Token(); |
||||||
|
|
||||||
|
$params = [ |
||||||
|
'name_1' => 'value_1', |
||||||
|
'name_2' => 'value_2', |
||||||
|
]; |
||||||
|
$oauthToken->setParams($params); |
||||||
|
$this->assertEquals($params, $oauthToken->getParams(), 'Unable to setup params!'); |
||||||
|
|
||||||
|
$newParamName = 'new_param_name'; |
||||||
|
$newParamValue = 'new_param_value'; |
||||||
|
$oauthToken->setParam($newParamName, $newParamValue); |
||||||
|
$this->assertEquals($newParamValue, $oauthToken->getParam($newParamName), 'Unable to setup param by name!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testSetupParams |
||||||
|
*/ |
||||||
|
public function testSetupParamsShortcuts() |
||||||
|
{ |
||||||
|
$oauthToken = new Token(); |
||||||
|
|
||||||
|
$token = 'test_token_value'; |
||||||
|
$oauthToken->setToken($token); |
||||||
|
$this->assertEquals($token, $oauthToken->getToken(), 'Unable to setup token!'); |
||||||
|
|
||||||
|
$tokenSecret = 'test_token_secret'; |
||||||
|
$oauthToken->setTokenSecret($tokenSecret); |
||||||
|
$this->assertEquals($tokenSecret, $oauthToken->getTokenSecret(), 'Unable to setup token secret!'); |
||||||
|
|
||||||
|
$tokenExpireDuration = rand(1000, 2000); |
||||||
|
$oauthToken->setExpireDuration($tokenExpireDuration); |
||||||
|
$this->assertEquals($tokenExpireDuration, $oauthToken->getExpireDuration(), 'Unable to setup expire duration!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Data provider for {@link testAutoFetchExpireDuration}. |
||||||
|
* @return array test data. |
||||||
|
*/ |
||||||
|
public function autoFetchExpireDurationDataProvider() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
[ |
||||||
|
['expire_in' => 123345], |
||||||
|
123345 |
||||||
|
], |
||||||
|
[ |
||||||
|
['expire' => 233456], |
||||||
|
233456 |
||||||
|
], |
||||||
|
[ |
||||||
|
['expiry_in' => 34567], |
||||||
|
34567 |
||||||
|
], |
||||||
|
[ |
||||||
|
['expiry' => 45678], |
||||||
|
45678 |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testSetupParamsShortcuts |
||||||
|
* @dataProvider autoFetchExpireDurationDataProvider |
||||||
|
* |
||||||
|
* @param array $params |
||||||
|
* @param $expectedExpireDuration |
||||||
|
*/ |
||||||
|
public function testAutoFetchExpireDuration(array $params, $expectedExpireDuration) |
||||||
|
{ |
||||||
|
$oauthToken = new Token(); |
||||||
|
$oauthToken->setParams($params); |
||||||
|
$this->assertEquals($expectedExpireDuration, $oauthToken->getExpireDuration()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testSetupParamsShortcuts |
||||||
|
*/ |
||||||
|
public function testGetIsExpired() |
||||||
|
{ |
||||||
|
$oauthToken = new Token(); |
||||||
|
$expireDuration = 3600; |
||||||
|
$oauthToken->setExpireDuration($expireDuration); |
||||||
|
|
||||||
|
$this->assertFalse($oauthToken->getIsExpired(), 'Not expired token check fails!'); |
||||||
|
|
||||||
|
$oauthToken->createTimestamp = $oauthToken->createTimestamp - ($expireDuration +1); |
||||||
|
$this->assertTrue($oauthToken->getIsExpired(), 'Expired token check fails!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testGetIsExpired |
||||||
|
*/ |
||||||
|
public function testGetIsValid() |
||||||
|
{ |
||||||
|
$oauthToken = new Token(); |
||||||
|
$expireDuration = 3600; |
||||||
|
$oauthToken->setExpireDuration($expireDuration); |
||||||
|
|
||||||
|
$this->assertFalse($oauthToken->getIsValid(), 'Empty token is valid!'); |
||||||
|
|
||||||
|
$oauthToken->setToken('test_token'); |
||||||
|
$this->assertTrue($oauthToken->getIsValid(), 'Filled up token is invalid!'); |
||||||
|
|
||||||
|
$oauthToken->createTimestamp = $oauthToken->createTimestamp - ($expireDuration +1); |
||||||
|
$this->assertFalse($oauthToken->getIsValid(), 'Expired token is valid!'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class BaseMethodTest extends TestCase |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Creates test signature method instance. |
||||||
|
* @return \yii\authclient\oauth\signature\BaseMethod |
||||||
|
*/ |
||||||
|
protected function createTestSignatureMethod() |
||||||
|
{ |
||||||
|
$signatureMethod = $this->getMock('\yii\authclient\oauth\signature\BaseMethod', ['getName', 'generateSignature']); |
||||||
|
$signatureMethod->expects($this->any())->method('getName')->will($this->returnValue('testMethodName')); |
||||||
|
$signatureMethod->expects($this->any())->method('generateSignature')->will($this->returnValue('testSignature')); |
||||||
|
return $signatureMethod; |
||||||
|
} |
||||||
|
|
||||||
|
// Tests : |
||||||
|
|
||||||
|
public function testGenerateSignature() |
||||||
|
{ |
||||||
|
$signatureMethod = $this->createTestSignatureMethod(); |
||||||
|
|
||||||
|
$baseString = 'test_base_string'; |
||||||
|
$key = 'test_key'; |
||||||
|
|
||||||
|
$signature = $signatureMethod->generateSignature($baseString, $key); |
||||||
|
|
||||||
|
$this->assertNotEmpty($signature, 'Unable to generate signature!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testGenerateSignature |
||||||
|
*/ |
||||||
|
public function testVerify() |
||||||
|
{ |
||||||
|
$signatureMethod = $this->createTestSignatureMethod(); |
||||||
|
|
||||||
|
$baseString = 'test_base_string'; |
||||||
|
$key = 'test_key'; |
||||||
|
$signature = 'unsigned'; |
||||||
|
$this->assertFalse($signatureMethod->verify($signature, $baseString, $key), 'Unsigned signature is valid!'); |
||||||
|
|
||||||
|
$generatedSignature = $signatureMethod->generateSignature($baseString, $key); |
||||||
|
$this->assertTrue($signatureMethod->verify($generatedSignature, $baseString, $key), 'Generated signature is invalid!'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yii\authclient\oauth\signature\HmacSha1; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class HmacSha1Test extends TestCase |
||||||
|
{ |
||||||
|
public function testGenerateSignature() |
||||||
|
{ |
||||||
|
$signatureMethod = new HmacSha1(); |
||||||
|
|
||||||
|
$baseString = 'test_base_string'; |
||||||
|
$key = 'test_key'; |
||||||
|
|
||||||
|
$signature = $signatureMethod->generateSignature($baseString, $key); |
||||||
|
$this->assertNotEmpty($signature, 'Unable to generate signature!'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yii\authclient\oauth\signature\PlainText; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class PlainTextTest extends TestCase |
||||||
|
{ |
||||||
|
public function testGenerateSignature() |
||||||
|
{ |
||||||
|
$signatureMethod = new PlainText(); |
||||||
|
|
||||||
|
$baseString = 'test_base_string'; |
||||||
|
$key = 'test_key'; |
||||||
|
|
||||||
|
$signature = $signatureMethod->generateSignature($baseString, $key); |
||||||
|
$this->assertNotEmpty($signature, 'Unable to generate signature!'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace yiiunit\extensions\authclient\oauth\signature; |
||||||
|
|
||||||
|
use yii\authclient\oauth\signature\RsaSha1; |
||||||
|
use yiiunit\extensions\authclient\TestCase; |
||||||
|
|
||||||
|
class RsaSha1Test extends TestCase |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Returns test public certificate string. |
||||||
|
* @return string public certificate string. |
||||||
|
*/ |
||||||
|
protected function getTestPublicCertificate() |
||||||
|
{ |
||||||
|
return '-----BEGIN CERTIFICATE----- |
||||||
|
MIIDJDCCAo2gAwIBAgIJALCFAl3nj1ibMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD |
||||||
|
VQQGEwJOTDESMBAGA1UECAwJQW1zdGVyZGFtMRIwEAYDVQQHDAlBbXN0ZXJkYW0x |
||||||
|
DzANBgNVBAoMBlBpbVRpbTEPMA0GA1UECwwGUGltVGltMSswKQYDVQQDDCJkZXY1 |
||||||
|
My5xdWFydHNvZnQuY29tL3BrbGltb3YvcGltdGltMSQwIgYJKoZIhvcNAQkBFhVw |
||||||
|
a2xpbW92QHF1YXJ0c29mdC5jb20wHhcNMTIxMTA2MTQxNjUzWhcNMTMxMTA2MTQx |
||||||
|
NjUzWjCBqjELMAkGA1UEBhMCTkwxEjAQBgNVBAgMCUFtc3RlcmRhbTESMBAGA1UE |
||||||
|
BwwJQW1zdGVyZGFtMQ8wDQYDVQQKDAZQaW1UaW0xDzANBgNVBAsMBlBpbVRpbTEr |
||||||
|
MCkGA1UEAwwiZGV2NTMucXVhcnRzb2Z0LmNvbS9wa2xpbW92L3BpbXRpbTEkMCIG |
||||||
|
CSqGSIb3DQEJARYVcGtsaW1vdkBxdWFydHNvZnQuY29tMIGfMA0GCSqGSIb3DQEB |
||||||
|
AQUAA4GNADCBiQKBgQDE0d63YwpBLxzxQAW887JALcGruAHkHu7Ui1oc7bCIMy+u |
||||||
|
d6rPgNmbFLw3GoGzQ8xhMmksZHsS07IfWRTDeisPHAqfgcApOZbyMyZUAL6+1ko4 |
||||||
|
xAIPnQSia7l8M4nWgtgqifDCbFKAoPXuWSrYDOFtgSkBLH5xYyFPRc04nnHpoQID |
||||||
|
AQABo1AwTjAdBgNVHQ4EFgQUE2oxXYDFRNtgvn8tyXldepRFWzYwHwYDVR0jBBgw |
||||||
|
FoAUE2oxXYDFRNtgvn8tyXldepRFWzYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B |
||||||
|
AQUFAAOBgQB1/S46dWBECaOs4byCysFhzXw8qx8znJkSZcIdDilmg1kkfusXKi2S |
||||||
|
DiiFw5gDrc6Qp6WtPmVhxHUWl6O5bOG8lG0Dcppeed9454CGvBShmYdwC6vk0s7/ |
||||||
|
gVdK2V4fYsUeT6u49ONshvJ/8xhHz2gGXeLWaqHwtK3Dl3S6TIDuoQ== |
||||||
|
-----END CERTIFICATE-----'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns test private certificate string. |
||||||
|
* @return string private certificate string. |
||||||
|
*/ |
||||||
|
protected function getTestPrivateCertificate() |
||||||
|
{ |
||||||
|
return '-----BEGIN RSA PRIVATE KEY----- |
||||||
|
MIICXAIBAAKBgQDE0d63YwpBLxzxQAW887JALcGruAHkHu7Ui1oc7bCIMy+ud6rP |
||||||
|
gNmbFLw3GoGzQ8xhMmksZHsS07IfWRTDeisPHAqfgcApOZbyMyZUAL6+1ko4xAIP |
||||||
|
nQSia7l8M4nWgtgqifDCbFKAoPXuWSrYDOFtgSkBLH5xYyFPRc04nnHpoQIDAQAB |
||||||
|
AoGAPm1e2gYE86Xw5ShsaYFWcXrR6hiEKQoSsMG+hFxz2M97eTglqolw+/p4tHWo |
||||||
|
2+ZORioKJ/V6//67iavkpRfz3dloUlNE9ZzlvqvPjHePt3BI22GI8D84dcqnxWW5 |
||||||
|
4okEAfDfXk2B4UNOpVNU5FZjg4XvBEbbhRVrsBWAPMduDX0CQQDtFgLLLWr50F3z |
||||||
|
lGuFy68Y1d01sZsyf7xUPaLcDWbrnVMIjZIs60BbLg9PZ6sYcwV2RwL/WaJU0Ap/ |
||||||
|
KKjHW51zAkEA1IWBicQtt6yGaUqydq+ifX8/odFjIrlZklwckLl65cImyxqDYMnA |
||||||
|
m+QdbZznSH96BHjduhJAEAtfYx5CVMrXmwJAHKiWedzpm3z2fmUoginW5pejf8QS |
||||||
|
UI5kQ4KX1yW/lSeVS+lhDBD73Im6zAxqADCXLm7zC87X8oybWDef/0kxxQJAebRX |
||||||
|
AalKMSRo+QVg/F0Kpenoa+f4aNtSc2GyriK6QbeU9b0iPZxsZBoXzD0NqlPucX8y |
||||||
|
IyvuagHJR379p4dePwJBAMCkYSATGdhYbeDfySWUro5K0QAvBNj8FuNJQ4rqUxz8 |
||||||
|
8b+OXIyd5WlmuDRTDGJBTxAYeaioTuMCFWaZm4jG0I4= |
||||||
|
-----END RSA PRIVATE KEY-----'; |
||||||
|
} |
||||||
|
|
||||||
|
// Tests : |
||||||
|
|
||||||
|
public function testGenerateSignature() |
||||||
|
{ |
||||||
|
$signatureMethod = new RsaSha1(); |
||||||
|
$signatureMethod->setPrivateCertificate($this->getTestPrivateCertificate()); |
||||||
|
$signatureMethod->setPublicCertificate($this->getTestPublicCertificate()); |
||||||
|
|
||||||
|
$baseString = 'test_base_string'; |
||||||
|
$key = 'test_key'; |
||||||
|
|
||||||
|
$signature = $signatureMethod->generateSignature($baseString, $key); |
||||||
|
$this->assertNotEmpty($signature, 'Unable to generate signature!'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @depends testGenerateSignature |
||||||
|
*/ |
||||||
|
public function testVerify() |
||||||
|
{ |
||||||
|
$signatureMethod = new RsaSha1(); |
||||||
|
$signatureMethod->setPrivateCertificate($this->getTestPrivateCertificate()); |
||||||
|
$signatureMethod->setPublicCertificate($this->getTestPublicCertificate()); |
||||||
|
|
||||||
|
$baseString = 'test_base_string'; |
||||||
|
$key = 'test_key'; |
||||||
|
$signature = 'unsigned'; |
||||||
|
$this->assertFalse($signatureMethod->verify($signature, $baseString, $key), 'Unsigned signature is valid!'); |
||||||
|
|
||||||
|
$generatedSignature = $signatureMethod->generateSignature($baseString, $key); |
||||||
|
$this->assertTrue($signatureMethod->verify($generatedSignature, $baseString, $key), 'Generated signature is invalid!'); |
||||||
|
} |
||||||
|
|
||||||
|
public function testInitPrivateCertificate() |
||||||
|
{ |
||||||
|
$signatureMethod = new RsaSha1(); |
||||||
|
|
||||||
|
$certificateFileName = __FILE__; |
||||||
|
$signatureMethod->privateCertificateFile = $certificateFileName; |
||||||
|
$this->assertEquals(file_get_contents($certificateFileName), $signatureMethod->getPrivateCertificate(), 'Unable to fetch private certificate from file!'); |
||||||
|
} |
||||||
|
|
||||||
|
public function testInitPublicCertificate() |
||||||
|
{ |
||||||
|
$signatureMethod = new RsaSha1(); |
||||||
|
|
||||||
|
$certificateFileName = __FILE__; |
||||||
|
$signatureMethod->publicCertificateFile = $certificateFileName; |
||||||
|
$this->assertEquals(file_get_contents($certificateFileName), $signatureMethod->getPublicCertificate(), 'Unable to fetch public certificate from file!'); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue