/addons/plugin/Login/lib/baidu/Baidu.php
PHP | 341 lines | 168 code | 31 blank | 142 comment | 33 complexity | 72b6aeb4dc15ff0b66d484b69cd8d6d7 MD5 | raw file
Possible License(s): LGPL-2.1
- <?php
- /***************************************************************************
- *
- * Copyright (c) 2011 Baidu.com, Inc. All Rights Reserved
- *
- **************************************************************************/
- require_once( 'BaiduStore.php');
- require_once( 'BaiduOAuth2.php');
- require_once( 'BaiduApiClient.php');
- require_once( 'BaiduUtils.php');
- /**
- *
- * @package Baidu
- * @author zhujianting(zhujianting@baidu.com)
- * @version v2.0.0
- */
- class BaiduAPI
- {
- /**
- * The client_id of the app or access_key of the developer.
- * @var string
- */
- protected $clientId;
-
- /**
- * The client_secret of the app or secret_key of the developer.
- * @var string
- */
- protected $clientSecret;
-
- /**
- * Redirect uri of the app, where we will redirect to after user authorization.
- * @var string
- */
- protected $redirectUri;
-
- /**
- * Storage for the user session related datas, like state, authorization code,
- * access token and so on.
- *
- * @var BaiduStore
- */
- protected $store = null;
-
- /**
- * @var string
- */
- protected $state = null;
-
- /**
- * User session info.
- * @var array
- */
- protected $session = null;
-
- /**
- * @var BaiduOAuth2
- */
- protected $oauth2 = null;
-
- /**
- * Constructor
- *
- * @param string $clientId The client_id of the app or access_key of the developer.
- * @param string $clientSecret The client_secret of the app or secret_key of the developer.
- * @param string $redirectUri Redirect uri of the app.
- * @param BaiduStore $store Storage for the user session related datas.
- */
- public function __construct($clientId, $clientSecret, $redirectUri, $store = null)
- {
- $this->clientId = $clientId;
- $this->clientSecret = $clientSecret;
- $this->redirectUri = $redirectUri;
- $this->setStore($store ? $store : new BaiduCookieStore($clientId));
- }
- /**
- * Get an instance of BaiduOAuth2 class.
- *
- * @return BaiduOAuth2
- */
- public function getBaiduOAuth2Service()
- {
- if (!$this->oauth2) {
- $this->oauth2 = new BaiduOAuth2($this->clientId, $this->clientSecret);
- $this->oauth2->setRedirectUri($this->redirectUri);
- }
- return $this->oauth2;
- }
-
- /**
- * Get an instance of BaiduApiClient class.
- *
- * @param string $accessToken Access token for api calls.
- * @return BaiduApiClient
- */
- public function getBaiduApiClientService()
- {
- return new BaiduApiClient($this->clientId, $this->getAccessToken());
- }
-
- /**
- * Get access token for openapi calls.
- *
- * @return string|false Returns access token if user has authorized the app, or false if not.
- */
- public function getAccessToken()
- {
- $session = $this->getSession();
- if (isset($session['access_token'])) {
- return $session['access_token'];
- } else {
- return false;
- }
- }
-
- /**
- * Get refresh token.
- *
- * @return string|false Returns refresh token if app has, or false if not.
- */
- public function getRefreshToken()
- {
- $session = $this->getSession();
- if (isset($session['refresh_token'])) {
- return $session['refresh_token'];
- } else {
- return false;
- }
- }
-
- /**
- * Get currently logged in user's uid.
- *
- * @return uint|false Return uid of the loggedin user, or return
- * false if user isn't loggedin.
- */
- public function getLoggedInUser()
- {
- // Get user from cached data or from access token
- $user = $this->getUser();
-
- // If there's bd_sig & bd_user parameter in query parameters,
- // it must be an inside web app(app on baidu) loading request,
- // then we must check whether the uid passed from baidu is the
- // same as we get from persistent data or from access token,
- // if it's not, we should clear all the persistent data and to
- // get an access token again.
- if (isset($_REQUEST['bd_sig']) && isset($_REQUEST['bd_user'])) {
- $params = array('bd_user' => $_REQUEST['bd_user']);
- $sig = BaiduUtils::generateSign($params, $this->clientSecret, 'bd_sig');
- if ($sig != $_REQUEST['bd_sig'] || $user['uid'] != $_REQUEST['bd_user']) {
- $this->store->remove('session');
- return false;
- }
- }
-
- return $user;
- }
-
- /**
- * Get a Login URL for use with redirects. By default, full page redirect is
- * assumed. If you are using the generated URL with a window.open() call in
- * JavaScript, you can pass in display=popup as part of the $params.
- *
- * @param string $scope blank space separated list of requested extended perms
- * @param string $display Authorization page style, 'page', 'popup', 'touch' or 'mobile'
- * @return string the URL for the login flow
- */
- public function getLoginUrl($scope = '', $display = 'page')
- {
- $oauth2 = $this->getBaiduOAuth2Service();
- return $oauth2->getAuthorizeUrl('code', $scope, $this->state, $display);
- }
-
- /**
- * Get the Logout URL suitable for use with redirects.
- *
- * @param string $next Url to go to after a successful logout.
- *
- * @return string
- */
- public function getLogoutUrl($next)
- {
- $oauth2 = $this->getBaiduOAuth2Service();
- return $oauth2->getLogoutUrl($this->getAccessToken(), $next);
- }
-
- /**
- * Get user session info.
- *
- * @return array
- */
- public function getSession()
- {
- if ($this->session === null) {
- $this->session = $this->doGetSession();
- }
-
- return $this->session;
- }
-
- /**
- * Set user session.
- *
- * @param array $session User session info.
- * @return Baidu
- */
- public function setSession($session)
- {
- $this->session = $session;
- if ($session) {
- $this->store->set('session', $session);
- } else {
- $this->store->remove('session');
- }
- return $this;
- }
-
- /**
- * Get current user's uid and uname.
- *
- * @return array|false array('uid' => xx, 'uname' => xx)
- */
- protected function getUser()
- {
- $session = $this->getSession();
- if (is_array($session) && isset($session['uid']) && isset($session['uname'])) {
- return array('uid' => $session['uid'], 'uname' => $session['uname']);
- } else {
- return false;
- }
- }
-
- /**
- * Set the session data storage instance.
- *
- * @param BaiduStore $store
- * @return Baidu
- */
- protected function setStore($store)
- {
- $this->store = $store;
- if ($this->store) {
- $state = $this->store->get('state');
- if (!empty($state)) {
- $this->state = $state;
- }
- //as the storage engine is changed, we need to get the session again.
- $this->session = null;
- $this->getSession();
- $this->establishCSRFTokenState();
- }
-
- return $this;
- }
-
- /**
- * Get session info from Baidu server or from the store in app server side.
- *
- * @return array|false
- */
- protected function doGetSession()
- {
- // get authorization code from query parameters
- $code = $this->getCode();
- // check whether it is a CSRF attack request
- if ($code && $code != $this->store->get('code')) {
- $oauth2 = $this->getBaiduOAuth2Service();
- $session = $oauth2->getAccessTokenByAuthorizationCode($code);
- if ($session) {
- $this->store->set('code', $code);
- $this->setSession($session);
- $apiClient = new BaiduApiClient($this->clientId, $session['access_token']);
- $user = $apiClient->api('passport/users/getLoggedInUser');
- if ($user) {
- $session = array_merge($session, $user);
- $this->setSession($session);
- }
- return $session;
- }
-
- // code was bogus, so everything based on it should be invalidated.
- $this->store->removeAll();
- return false;
- }
-
- // as a fallback, just return whatever is in the storage
- $session = $this->store->get('session');
- $this->setSession($session);
- if ($session && !isset($session['uid'])) {
- $apiClient = new BaiduApiClient($this->clientId, $session['access_token']);
- $user = $apiClient->api('passport/users/getLoggedInUser');
- if ($user) {
- $session = array_merge($session, $user);
- $this->setSession($session);
- }
- }
-
- return $session;
- }
- /**
- * Get the authorization code from the query parameters, if it exists,
- * otherwise return false to signal no authorization code was discoverable.
- *
- * @return mixed Returns the authorization code, or false if the authorization
- * code could not be determined.
- */
- protected function getCode()
- {
- if (isset($_GET['code'])) {
- if ($this->state && $this->state === $_GET['state']) {
- // CSRF state has done its job, so clear it
- $this->state = null;
- $this->store->remove('state');
- return $_GET['code'];
- } else {
- BaiduUtils::errorLog('CSRF state token does not match one provided.');
- return false;
- }
- }
-
- return false;
- }
- /**
- * Lays down a CSRF state token for this process.
- *
- * @return void
- */
- protected function establishCSRFTokenState()
- {
- if ($this->state === null) {
- $this->state = md5(uniqid(mt_rand(), true));
- $this->store->set('state', $this->state);
- }
- }
- }