PageRenderTime 36ms CodeModel.GetById 6ms app.highlight 10ms RepoModel.GetById 17ms app.codeStats 0ms

/library/Zend/Oauth2.php

https://github.com/A-Shevchenko/oauth-2---facebook---zend-framework-components
PHP | 361 lines | 148 code | 58 blank | 155 comment | 38 complexity | 13d5773a699a20c0f1310fdcfc161e24 MD5 | raw file
  1<?php
  2
  3/**
  4 * Zend Framework
  5 *
  6 * LICENSE
  7 *
  8 * This source file is subject to the new BSD license that is bundled
  9 * with this package in the file LICENSE.txt.
 10 * It is also available through the world-wide-web at this URL:
 11 * http://framework.zend.com/license/new-bsd
 12 * If you did not receive a copy of the license and are unable to
 13 * obtain it through the world-wide-web, please send an email
 14 * to license@zend.com so we can send you a copy immediately.
 15 *
 16 * @category   Zend
 17 * @package    Zend_Oauth2
 18 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: Oauth.php 21071 2010-02-16 14:35:00Z padraic $
 21 */
 22
 23/**
 24 * @see Zend_Oauth2_Config
 25 */
 26require_once 'Zend/Oauth2/Config.php';
 27
 28/**
 29 * @see Zend_Rest_Client
 30 */
 31require_once 'Zend/Rest/Client.php';
 32
 33/**
 34 * @see Zend_Json
 35 */
 36require_once 'Zend/Json.php';
 37
 38class Zend_Oauth2
 39{
 40
 41    const authentification_uri = '/authorize';
 42    const access_token_uri = '/access_token';
 43
 44    /**
 45     *
 46     * @var string
 47     */
 48    protected $_verificationCode = null;
 49
 50    /**
 51     *
 52     * @varmixed
 53     */
 54    protected $_config = null;
 55
 56    /**
 57     *
 58     * @var <type>
 59     */
 60    protected static $_localHttpClient = null;
 61
 62    public function __construct($options = null)
 63    {
 64        $this->_config = new Zend_Oauth2_Config;
 65        if (!is_null($options)) {
 66            if ($options instanceof Zend_Config) {
 67                $options = $options->toArray();
 68            }
 69            $this->_config->setOptions($options);
 70        }
 71    }
 72
 73    /**
 74     *
 75     * redirecting the end user's user-agent to the authorization page
 76     *
 77     * adter accepting or denying user will be redirected to callback page
 78     * if user accepts url will include a parameter "code" and optional a parameter "state"
 79     * if user denies url will include a parameter "error" set to "user_denied"
 80     * and an optional parameter "state"
 81     *
 82     * - type REQUIRED (The type of user delegation authorization flow)
 83     *
 84     * - client_id REQUIRED (The client identifier)
 85     *
 86     * - redirect_uri REQUIRED (An absolute URI to which the authorization server will
 87     * redirect the user-agent to when the end user authorization step is completed)
 88     *
 89     * - state OPTIONAL (An opaque value used by the client to maintain state between
 90     * the request and callback)
 91     *
 92     * - immediate OPTIONAL (The parameter value must be set to "true" or "false"
 93     * (case sensitive).  If set to "true", the authorization server MUST NOT prompt
 94     * the end user to authenticate or approve access. Instead, the authorization
 95     * server attempts to establish the end user's identity via other means (e.g.
 96     * browser cookies) and checks if the end user has previously approved an
 97     * identical access request by the same client and if that access grant is
 98     * still active.  If the authorization server does not support an immediate
 99     * check or if it is unable to establish the end user's identity or approval
100     * status, it MUST deny the request without prompting the end user. Defaults
101     * to "false" if omitted.)
102     *
103     * @param <type> $siteUrl
104     * @param <type> $callbackUrl
105     * @param <type> $clientId
106     * @param <type> $type
107     * @param <type> $state
108     * @param <type> $immediate
109     * @param <type> $requestedRights
110     */
111    public function authorizationRedirect($siteUrl = null, $callbackUrl = null, $clientId = null, $type = null, $state = null, $immediate = null, $requestedRights = null)
112    {
113        if (is_null($siteUrl)) $siteUrl = $this->_config->getSiteUrl();
114        if (is_null($callbackUrl)) $callbackUrl = $this->_config->getCallbackUrl();
115        if (is_null($clientId)) $clientId = $this->_config->getClientId();
116        if (is_null($type)) $type = $this->_config->getType();
117        if (is_null($state)) $state = $this->_config->getState();
118        if (is_null($immediate)) $immediate = $this->_config->getImmediate();
119        if (is_null($requestedRights)) $requestedRights = $this->_config->getRequestedRights();
120
121        $requiredValuesArray = array('siteUrl', 'callbackUrl', 'clientId', 'type');
122
123        // throw exception if one of the required values is missing
124        foreach($requiredValuesArray as $requiredValue) {
125            if (is_null($$requiredValue)) {
126                require_once 'Zend/Oauth2/Exception.php';
127                throw new Zend_Oauth2_Exception('value '. $requiredValue.' is empty, pass '.ucfirst($requiredValue).' as parameter when calling the '.__METHOD__.' method or add it to the options array you pass when creating an instance of the '.get_class($this).' class');
128            }
129        }
130
131        // convert rights array to string
132        $scope = '';
133        if (is_array($requestedRights)) {
134            $requestedRightsString = implode(',', $requestedRights);
135            $scope = $requestedRightsString;
136        } else {
137            $scope = $requestedRights;
138        }
139
140        // construct request url with required values
141        if (substr($siteUrl, -1) == '/') $siteUrl = substr($siteUrl, 0, strlen($siteUrl)-1);
142        $requestUrl = $siteUrl.self::authentification_uri.'?client_id='.$clientId.'&redirect_uri='.$callbackUrl.'&type='.$type;
143
144        //Zend_Debug::dump($requestUrl);
145        //exit;
146
147        // add optional values to request url
148        if (!empty($scope)) $requestUrl .= '&scope='.$scope;
149        if (!empty($state)) $requestUrl .= '&state='.$state;
150        if (!empty($immediate)) $requestUrl .= '&immediate='.$immediate;
151
152        //Zend_Debug::dump($requestUrl);
153        //exit;
154
155        header('Location: '.$requestUrl);
156        exit(1);
157
158    }
159
160    /**
161     *
162     * @param string $right
163     */
164    public function addRequestedRight($right) {
165
166        $rights = $this->getRequestedRights();
167
168        if (is_array($rights)) {
169            $rights[] = $right;
170        } elseif (is_string($rights)) {
171            $rightsArray = array();
172            $rightsArray[] = $rights;
173            $rightsArray[] = $right;
174            $rights = $rightsArray;
175        } else {
176            $rights = $right;
177        }
178
179        $this->setRequestedRights($rights);
180    }
181
182    /**
183     *
184     * @param string $right
185     */
186    public function removeRequestedRight($right) {
187
188        $rights = $this->getRequestedRights();
189
190        $key = array_search($right, $rights);
191        
192        if ($key !== false) { 
193            unset($rights[$key]);
194        }
195        
196        $this->setRequestedRights($rights);
197
198    }
199
200    /**
201     * Set verification code
202     *
203     * @param  string $verificationCode
204     * @return Zend_Oauth2
205     */
206    public function setVerificationCode($verificationCode)
207    {
208        $this->_verificationCode = $verificationCode;
209        return $this;
210    }
211
212    /**
213     * Get verification code
214     *
215     * @return string
216     */
217    public function getVerificationCode()
218    {
219        return $this->_verificationCode;
220    }
221
222    /**
223     * Set local HTTP client as distinct from the static HTTP client
224     * as inherited from Zend_Rest_Client.
225     *
226     * @param Zend_Http_Client $client
227     * @return self
228     */
229    public static function setLocalHttpClient(Zend_Http_Client $httpClient)
230    {
231        self::$_localHttpClient = $httpClient;
232    }
233
234    /**
235     *
236     * @return <type>
237     */
238    public static function getLocalHttpClient()
239    {
240        if (!isset(self::$_localHttpClient)) {
241            self::$_localHttpClient = new Zend_Http_Client;
242        }
243
244        return self::$_localHttpClient;
245    }
246
247    /**
248     * Simple mechanism to delete the entire singleton HTTP Client instance
249     * which forces an new instantiation for subsequent requests.
250     *
251     * @return void
252     */
253    public static function clearHttpClient()
254    {
255        self::$httpClient = null;
256    }
257    
258    /**
259     *
260     * requests an access token from the authorization server
261     * 
262     * The client obtains an access token from the authorization server by
263     * making an HTTP "POST" request to the token endpoint. The client
264     * constructs a request URI by adding the following parameters to the
265     * request:
266     *
267     * - type REQUIRED (The type of user delegation authorization flow)
268     *
269     * - client_id REQUIRED (The client identifier)
270     *
271     * - client_secret REQUIRED (The matching client secret)
272     *
273     * - code REQUIRED (The verification code received from the authorization server)
274     *
275     * - redirect_uri REQUIRED (The redirection URI used in the initial request)
276     *
277     * - secret_type OPTIONAL (The access token secret type. If omitted, the authorization
278     * server will issue a bearer token (an access token without a matching secret))
279     * 
280     * @param string $verificationCode
281     * @return string
282     */
283    public function requestAccessToken($verificationCode = null, $siteUrl = null, $callbackUrl = null, $clientId = null, $clientSecret = null, $type = null, $secretTtype = null)
284    {
285        if (is_null($verificationCode)) $verificationCode = $this->getVerificationCode();
286        if (is_null($siteUrl)) $siteUrl = $this->_config->getSiteUrl();
287        if (is_null($callbackUrl)) $callbackUrl = $this->_config->getCallbackUrl();
288        if (is_null($clientId)) $clientId = $this->_config->getClientId();
289        if (is_null($clientSecret)) $clientSecret = $this->_config->getClientSecret();
290        if (is_null($type)) $type = $this->_config->getType();
291        if (is_null($secretTtype)) $secretTtype = $this->_config->getSecretType();
292        if (is_null(self::$_localHttpClient)) $this->setLocalHttpClient($this->getLocalHttpClient());
293
294        $requiredValuesArray = array('verificationCode', 'type', 'clientId', 'clientSecret', 'callbackUrl');
295
296        // throw exception if one of the required values is missing
297        foreach($requiredValuesArray as $requiredValue) {
298            if (is_null($$requiredValue)) {
299                require_once 'Zend/Oauth2/Exception.php';
300                throw new Zend_Oauth2_Exception('value '. $requiredValue.' is empty, pass the '.ucfirst($requiredValue).' as parameter when calling the '.__METHOD__.' method or add it to the options array you pass when creating an instance of the '.get_class($this).' class');
301            }
302        }
303
304        if (substr($siteUrl, -1) == '/') $siteUrl = substr($siteUrl, 0, strlen($siteUrl)-1);
305
306        self::$_localHttpClient ->resetParameters()
307                                ->setHeaders('Accept-Charset', 'ISO-8859-1,utf-8')
308                                ->setUri($siteUrl.self::access_token_uri)
309                                ->setParameterPost(array(
310                                    'type'  => $type,
311                                    'client_id'   => $clientId,
312                                    'client_secret' => $clientSecret,
313                                    'code' => $verificationCode,
314                                    'redirect_uri' => $callbackUrl,
315                                    'secret_type' => $secretTtype
316                                ));
317
318        //Zend_Debug::dump(self::$_localHttpClient->getUri());
319        //exit;
320
321        $response = self::$_localHttpClient->request('POST');
322
323        //Zend_Debug::dump($body, 'body');
324        //Zend_Debug::dump($status, 'status');
325        //exit;
326
327        if (!is_null($response)) {
328            $body   = $response->getBody();
329            $status = $response->getStatus();
330        } else {
331
332            require_once 'Zend/Oauth2/Exception.php';
333            throw new Zend_Oauth2_Exception('the response we recieved is emtpy');
334
335        }
336
337        //Zend_Debug::dump($body, 'body');
338        //exit;
339
340        if ($status != '200') {
341
342            $errorArray = Zend_Json::decode($body);
343            require_once 'Zend/Oauth2/Exception.php';
344            throw new Zend_Oauth2_Exception('we recieved an error ('.$status.') as response: '.$errorArray['error']['type'].' => '.$errorArray['error']['message']);
345
346        }
347
348        $explodedBody = explode('=', $body);
349
350        if ($explodedBody[0] != 'access_token') {
351
352            require_once 'Zend/Oauth2/Exception.php';
353            throw new Zend_Oauth2_Exception('WTF?');
354
355        }
356        
357        return $explodedBody[1];
358        
359    }
360
361}