├── controllers └── connect.php ├── libraries ├── auth │ ├── client.php │ ├── strategy │ │ ├── exception.php │ │ ├── oauth2.php │ │ └── oauth.php │ ├── controller.php │ ├── core.php │ └── strategy.php ├── oauth2 │ ├── response.php │ ├── request │ │ ├── resource.php │ │ └── access.php │ ├── token │ │ ├── authorize.php │ │ └── access.php │ ├── provider │ │ ├── github.php │ │ ├── foursquare.php │ │ ├── facebook.php │ │ ├── soundcloud.php │ │ ├── paypal.php │ │ ├── instagram.php │ │ ├── windowlive.php │ │ ├── basecamp.php │ │ └── google.php │ ├── token.php │ ├── exception.php │ ├── core.php │ ├── provider.php │ └── request.php └── oauth │ ├── exception.php │ ├── request │ ├── credentials.php │ ├── authorize.php │ ├── resource.php │ ├── access.php │ └── token.php │ ├── token │ ├── access.php │ └── request.php │ ├── response.php │ ├── provider │ ├── dropbox.php │ ├── tumblr.php │ ├── flickr.php │ ├── vimeo.php │ ├── twitter.php │ └── linkedin.php │ ├── signature │ ├── plaintext.php │ └── hmac │ │ └── sha1.php │ ├── signature.php │ ├── consumer.php │ ├── token.php │ ├── provider.php │ ├── core.php │ └── request.php ├── docs ├── README.md ├── general │ ├── providers.md │ ├── overwriting-auth-driver.md │ ├── quick-installation.md │ └── events.md ├── contents.md ├── home.md └── changes.md ├── config ├── urls.php └── api.php ├── orchestra.json ├── migrations └── 2012_05_26_151608_create_clients.php ├── LICENSE ├── README.md ├── start.php ├── orchestra.php ├── orchestra └── configure.php └── vendor └── ca_chain_bundle.crt /controllers/connect.php: -------------------------------------------------------------------------------- 1 | 'auth/register', 5 | 'login' => 'auth/login', 6 | 'callback' => 'auth/callback', 7 | 8 | 'registered' => 'auth/account', 9 | 'logged_in' => 'auth/account', 10 | ); -------------------------------------------------------------------------------- /libraries/auth/strategy/exception.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | class Exception extends \Exception {} -------------------------------------------------------------------------------- /orchestra.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "OneAuth", 3 | "description" : "OAuth, OAuth2 and OpenID Auth bundle for Laravel", 4 | "author" : "Mior Muhammad Zaki", 5 | "url" : "http://bundles.laravel.com/bundle/oneauth", 6 | "version" : "0.1.0", 7 | "config" : { 8 | "handles" : "oneauth" 9 | } 10 | } -------------------------------------------------------------------------------- /docs/general/providers.md: -------------------------------------------------------------------------------- 1 | # Supported Provider 2 | 3 | * OAuth 4 | - Dropbox 5 | - Flickr 6 | - LinkedIn 7 | - Twitter 8 | - Vimeo 9 | * OAuth2 10 | - Basecamp 11 | - Facebook 12 | - Foursquare 13 | - Github 14 | - Google 15 | - Instagram 16 | - Paypal 17 | - SoundCloud 18 | - WindowsLice 19 | * OpenID *(To be added)* -------------------------------------------------------------------------------- /libraries/oauth/exception.php: -------------------------------------------------------------------------------- 1 | array('auto' => true), 15 | 16 | ### Run the migration 17 | 18 | php artisan migrate 19 | 20 | ## Contributors 21 | 22 | This bundle is a port from `Kohana\OAuth`, `OAuth2 Package for FuelPHP` and `NinjAuth Package for FuelPHP`. Original license is reserved to the contributors. 23 | -------------------------------------------------------------------------------- /libraries/oauth2/request/access.php: -------------------------------------------------------------------------------- 1 | true, 22 | ); 23 | 24 | public function execute(array $options = null) 25 | { 26 | return \Redirect::to($this->as_url()); 27 | } 28 | } -------------------------------------------------------------------------------- /libraries/oauth/request/resource.php: -------------------------------------------------------------------------------- 1 | true, 22 | 'oauth_token' => true, 23 | 'oauth_signature_method' => true, 24 | 'oauth_signature' => true, 25 | 'oauth_timestamp' => true, 26 | 'oauth_nonce' => true, 27 | 'oauth_version' => true, 28 | ); 29 | } -------------------------------------------------------------------------------- /libraries/oauth/token/request.php: -------------------------------------------------------------------------------- 1 | verifier($key); 28 | * 29 | * @param string new verifier 30 | * @return $this 31 | */ 32 | public function verifier($verifier) 33 | { 34 | $this->verifier = $verifier; 35 | 36 | return $this; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libraries/oauth/request/access.php: -------------------------------------------------------------------------------- 1 | true, 22 | 'oauth_token' => true, 23 | 'oauth_signature_method' => true, 24 | 'oauth_signature' => true, 25 | 'oauth_timestamp' => true, 26 | 'oauth_nonce' => true, 27 | 'oauth_version' => true, 28 | ); 29 | 30 | public function execute(array $options = null) 31 | { 32 | return OAuth_Response::make(parent::execute($options)); 33 | } 34 | } -------------------------------------------------------------------------------- /migrations/2012_05_26_151608_create_clients.php: -------------------------------------------------------------------------------- 1 | increments('id'); 14 | $table->integer('user_id')->unsigned(); 15 | $table->string('provider', 50); 16 | $table->string('uid', 255); 17 | $table->string('access_token', 500)->nullable(); 18 | $table->string('secret', 500)->nullable(); 19 | $table->string('refresh_token', 500)->nullable(); 20 | $table->integer('expires')->defaults(0)->nullable(); 21 | 22 | $table->timestamps(); 23 | $table->index('access_token'); 24 | $table->index('user_id'); 25 | $table->unique(array('provider', 'uid')); 26 | }); 27 | } 28 | 29 | /** 30 | * Revert the changes to the database. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::drop('oneauth_clients'); 37 | } 38 | } -------------------------------------------------------------------------------- /libraries/oauth/request/token.php: -------------------------------------------------------------------------------- 1 | true, 23 | 'oauth_consumer_key' => true, 24 | 'oauth_signature_method' => true, 25 | 'oauth_signature' => true, 26 | 'oauth_timestamp' => true, 27 | 'oauth_nonce' => true, 28 | 'oauth_version' => true, 29 | ); 30 | 31 | public function execute(array $options = null) 32 | { 33 | return OAuth_Response::make(parent::execute($options)); 34 | } 35 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /docs/general/overwriting-auth-driver.md: -------------------------------------------------------------------------------- 1 | OneAuth by default utilize `Laravel\Auth` for user authentication, however if you need to use other authentication 2 | bundle such as **Sentry**, following snippet shows exactly all you need. 3 | 4 | params = Core::parse_params($body); 30 | } 31 | } 32 | 33 | /** 34 | * Return the value of any protected class variable. 35 | * 36 | * // Get the response parameters 37 | * $params = $response->params; 38 | * 39 | * @param string variable name 40 | * @return mixed 41 | */ 42 | public function __get($key) 43 | { 44 | return $this->$key; 45 | } 46 | 47 | public function param($name, $default = NULL) 48 | { 49 | return array_get($this->params, $name, $default); 50 | } 51 | } -------------------------------------------------------------------------------- /docs/changes.md: -------------------------------------------------------------------------------- 1 | # OneAuth Change Log 2 | 3 | ## Contents 4 | 5 | - [OneAuth 0.1.2](#0.1.2) 6 | - [OneAuth 0.1.1](#0.1.1) 7 | 8 | 9 | ## OneAuth 0.1.2 10 | 11 | - Fixed API changes on Dropbox Provider. 12 | - Fixed [#15](https://github.com/codenitive/laravel-oneauth/pull/15) where OAuth*\Token\Access return incomplete PHP class from database session, by serialize it first we should avoid such issue and at the same time enable this instance to be reuse to retrieve or send to the provider. 13 | - Fixed [#16](https://github.com/codenitive/laravel-oneauth/pull/16) Access and Refresh token string length over 255. Increase access token, refresh token and secret length to 500. 14 | - Add Basecamp OAuth2 Provider. 15 | 16 | 17 | ## OneAuth 0.1.1 18 | 19 | - Improved OneAuth\Auth\Controller::action_error() support on displaying error message from OAuth and OAuth2. 20 | - Integration with [Orchestra bundle](http://bundles.laravel.com/bundle/orchestra). 21 | - Offline documentation using [Bundocs bundle](http://bundles.laravel.com/bundle/bundocs). 22 | - Fixed odd structure on Paypal OAuth2 Provider, CURLOPT_POSTFIELD require string instead of normal array. 23 | - Add Laravel\Auth call to use IoC. 24 | - Comply with Laravel standard on using unsigned for foreign key. -------------------------------------------------------------------------------- /libraries/auth/strategy/oauth2.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | use OneAuth\Auth\Strategy as Auth_Strategy, 11 | OneAuth\OAuth2\Provider, 12 | OneAuth\OAuth2\Exception as OAuth2_Exception; 13 | 14 | class Oauth2 extends Auth_Strategy 15 | { 16 | public $name = 'oauth2'; 17 | public $provider; 18 | 19 | public function authenticate() 20 | { 21 | // Load the provider 22 | $provider = Provider::make($this->provider, $this->config); 23 | 24 | // Grab a callback from the config 25 | if ($provider->callback === null) 26 | { 27 | $callback = \URL::to(\Config::get('oneauth::urls.callback', 'connect/callback')); 28 | $callback = rtrim($callback, '/').'/'.$this->provider; 29 | $provider->callback = $callback; 30 | } 31 | 32 | return $provider->authorize(array( 33 | 'redirect_uri' => $provider->callback 34 | )); 35 | } 36 | 37 | public function callback() 38 | { 39 | try { 40 | // Load the provider 41 | $this->provider = Provider::make($this->provider, $this->config); 42 | 43 | return $this->provider->access(\Input::get('code')); 44 | } 45 | catch (OAuth2_Exception $e) 46 | { 47 | throw new Exception($e->getMessage()); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /docs/general/quick-installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Installation with Laravel Artisan 4 | 5 | php artisan bundle:install oneauth 6 | 7 | ## Bundle Registration 8 | 9 | 'oneauth' => array('auto' => true), 10 | 11 | ## Run the migration 12 | 13 | php artisan migrate 14 | 15 | ## Configuration 16 | 17 | First update `oneauth/config/api.php` with application key and secret from respective provider. 18 | 19 | /** 20 | * Providers 21 | * 22 | * Providers such as Facebook, Twitter, etc all use different Strategies such as oAuth, oAuth2, etc. 23 | * oAuth takes a key and a secret, oAuth2 takes a (client) id and a secret, optionally a scope. 24 | */ 25 | 'providers' => array( 26 | 27 | 'dropbox' => array( 28 | 'key' => '', 29 | 'secret' => '', 30 | ), 31 | 32 | … 33 | 34 | Once you're done, the only thing you need to do is create a controller 35 | 36 | 'connect/callback', 54 | ); 55 | -------------------------------------------------------------------------------- /libraries/oauth2/token/authorize.php: -------------------------------------------------------------------------------- 1 | 'Required option not passed: code')); 38 | } 39 | 40 | elseif ( ! isset($options['redirect_uri'])) 41 | { 42 | throw new Exception(array('message' => 'Required option not passed: redirect_uri')); 43 | } 44 | 45 | $this->code = $options['code']; 46 | $this->redirect_uri = $options['redirect_uri']; 47 | } 48 | 49 | /** 50 | * Returns the token key. 51 | * 52 | * @return string 53 | */ 54 | public function __toString() 55 | { 56 | return (string) $this->code; 57 | } 58 | 59 | } // End Token_Access 60 | -------------------------------------------------------------------------------- /docs/general/events.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | OneAuth use two events, one during login with OAuth/OAuth2 and another to synchronize user login/register with OAuth/OAuth2 database. 4 | 5 | This is to ensure authentication between 3rd party providers and your own application authentication works synchronously. 6 | 7 | ## oneauth.logged 8 | 9 | This event will be triggered once user logged in with OAuth or OAuth2, this would be good if you need to get extra information from providers including name, personal information or even profile picture. 10 | 11 | /** 12 | * @param OneAuth\Auth\Client $client (instanceof Eloquent) 13 | * @param array $user_data users' data from provider 14 | */ 15 | Event::listen('oauth.logged', function ($client, $user_data) 16 | { 17 | // do something cool with those information 18 | }); 19 | 20 | ## oneauth.sync 21 | 22 | This event should be fired when the user actually create an account in your application. For example, you may have `User` Eloquent Model and authenticate using `Auth`. 23 | 24 | $login = array('username' => Input::get('username'), 'password' => Input::get('password')); 25 | 26 | if (Auth::attempt($login)) 27 | { 28 | // get logged user id. 29 | $user_id = Auth::user()->id; 30 | 31 | // Synced it with oneauth, this will create a relationship between 32 | // `oneauth_clients` table with `users` table. 33 | Event::fire('oneauth.sync', array($user_id)); 34 | } -------------------------------------------------------------------------------- /libraries/oauth2/provider/github.php: -------------------------------------------------------------------------------- 1 | $token->access_token, 38 | )); 39 | 40 | $request = Request::make('resource', 'GET', 'https://api.github.com/user', array( 41 | 'access_token' => $token->access_token, 42 | )); 43 | 44 | $user = json_decode($request->execute()); 45 | 46 | // Create a response from the request 47 | return array( 48 | 'uid' => $user->id, 49 | 'nickname' => $user->login, 50 | 'name' => $user->name, 51 | 'email' => $user->email, 52 | 'urls' => array( 53 | 'github' => 'http://github.com/'.$user->login, 54 | 'blog' => $user->blog, 55 | ), 56 | ); 57 | } 58 | } -------------------------------------------------------------------------------- /libraries/oauth2/provider/foursquare.php: -------------------------------------------------------------------------------- 1 | $token->access_token, 43 | )); 44 | 45 | $response = json_decode($request->execute()); 46 | 47 | $user = $response->response->user; 48 | 49 | // Create a response from the request 50 | return array( 51 | 'uid' => $user->id, 52 | 'name' => sprintf('%s %s', $user->firstName, $user->lastName), 53 | 'email' => $user->contact->email, 54 | 'image' => $user->photo, 55 | 'location' => $user->homeCity, 56 | ); 57 | } 58 | } -------------------------------------------------------------------------------- /libraries/oauth2/token.php: -------------------------------------------------------------------------------- 1 | secret; 41 | * 42 | * @param string variable name 43 | * @return mixed 44 | */ 45 | public function __get($key) 46 | { 47 | return $this->$key; 48 | } 49 | 50 | /** 51 | * Return a boolean if the property is set 52 | * 53 | * // Get the token secret 54 | * if ($token->secret) exit('YAY SECRET'); 55 | * 56 | * @param string variable name 57 | * @return bool 58 | */ 59 | public function __isset($key) 60 | { 61 | return isset($this->$key); 62 | } 63 | 64 | /** 65 | * Returns the token key. 66 | * 67 | * @return string 68 | */ 69 | public function __toString() 70 | { 71 | return (string) $this->access_token; 72 | } 73 | } -------------------------------------------------------------------------------- /libraries/oauth2/exception.php: -------------------------------------------------------------------------------- 1 | . 7 | * @author Update to draft v10 by Edison Wong . 8 | * 9 | * Ported from FuelPHP \OAuth2 package 10 | * 11 | * @package FuelPHP/OAuth2 12 | * @category Provider 13 | * @author Phil Sturgeon 14 | * @copyright (c) 2012 HappyNinjas Ltd 15 | * @license http://philsturgeon.co.uk/code/dbad-license 16 | */ 17 | 18 | class Exception extends \Exception 19 | { 20 | /** 21 | * The result from the API server that represents the exception information. 22 | */ 23 | protected $result; 24 | 25 | /** 26 | * Make a new API Exception with the given result. 27 | * 28 | * @param $result 29 | * The result from the API server. 30 | */ 31 | public function __construct($result) 32 | { 33 | $this->result = $result; 34 | 35 | $code = isset($result['code']) ? $result['code'] : 0; 36 | 37 | // OAuth 2.0 Draft 10 style 38 | if (isset($result['error'])) $message = $result['error']; 39 | // cURL style 40 | elseif (isset($result['message'])) $message = $result['message']; 41 | else $message = 'Unknown Error.'; 42 | 43 | parent::__construct($message, (int) $code); 44 | } 45 | 46 | /** 47 | * To make debugging easier. 48 | * 49 | * @returns 50 | * The string representation of the error. 51 | */ 52 | public function __toString() 53 | { 54 | $str = $this->getType() . ': '; 55 | 56 | if ($this->code != 0) $str .= $this->code . ': '; 57 | 58 | return $str . $this->message; 59 | } 60 | } -------------------------------------------------------------------------------- /libraries/oauth2/provider/facebook.php: -------------------------------------------------------------------------------- 1 | $token->access_token, 40 | )); 41 | 42 | $user = json_decode($request->execute()); 43 | 44 | // Create a response from the request 45 | return array( 46 | 'uid' => $user->id, 47 | 'name' => $user->name, 48 | 'nickname' => isset($user->username) ? $user->username : null, 49 | 'email' => isset($user->email) ? $user->email : null, 50 | 'image' => 'https://graph.facebook.com/me/picture?type=normal&access_token='.$token->access_token, 51 | 'urls' => array( 52 | 'facebook' => $user->link, 53 | ), 54 | ); 55 | } 56 | } -------------------------------------------------------------------------------- /config/api.php: -------------------------------------------------------------------------------- 1 | array( 11 | 12 | 'basecamp' => array( 13 | 'id' => '', 14 | 'secret' => '', 15 | ), 16 | 17 | 'dropbox' => array( 18 | 'key' => '', 19 | 'secret' => '', 20 | ), 21 | 22 | 'facebook' => array( 23 | 'id' => '', 24 | 'secret' => '', 25 | 'scope' => 'email,offline_access', 26 | ), 27 | 28 | 'flickr' => array( 29 | 'key' => '', 30 | 'secret' => '', 31 | ), 32 | 33 | 'foursquare' => array( 34 | 'id' => '', 35 | 'secret' => '', 36 | ), 37 | 38 | 'github' => array( 39 | 'id' => '', 40 | 'secret' => '', 41 | ), 42 | 43 | 'google' => array( 44 | 'id' => '', 45 | 'secret' => '', 46 | ), 47 | 48 | 'instagram' => array( 49 | 'id' => '', 50 | 'secret' => '', 51 | ), 52 | 53 | 'linkedin' => array( 54 | 'key' => '', 55 | 'secret' => '', 56 | ), 57 | 58 | 'paypal' => array( 59 | 'id' => '', 60 | 'secret' => '', 61 | ), 62 | 63 | 'soundcloud' => array( 64 | 'id' => '', 65 | 'secret' => '', 66 | ), 67 | 68 | 'tumblr' => array( 69 | 'key' => '', 70 | 'secret' => '', 71 | ), 72 | 73 | 'twitter' => array( 74 | 'key' => '', 75 | 'secret' => '', 76 | ), 77 | 78 | 'vimeo' => array( 79 | 'key' => '', 80 | 'secret' => '', 81 | ), 82 | 83 | 'windowlive' => array( 84 | 'id' => '', 85 | 'secret' => '', 86 | ), 87 | 88 | ), 89 | ); -------------------------------------------------------------------------------- /libraries/oauth2/provider/soundcloud.php: -------------------------------------------------------------------------------- 1 | $token->access_token, 43 | )); 44 | 45 | $user = json_decode($request->execute()); 46 | 47 | // Create a response from the request 48 | return array( 49 | 'uid' => $user->id, 50 | 'nickname' => $user->username, 51 | 'name' => $user->full_name, 52 | 'location' => $user->country.' ,'.$user->country, 53 | 'description' => $user->description, 54 | 'image' => $user->avatar_url, 55 | 'urls' => array( 56 | 'myspace' => $user->myspace_name, 57 | 'website' => $user->website, 58 | ), 59 | ); 60 | } 61 | } -------------------------------------------------------------------------------- /libraries/auth/controller.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | class Controller extends \Controller 11 | { 12 | /** 13 | * Start a session request 14 | * 15 | * @access public 16 | * @param array $provider 17 | * @return Response 18 | * @throws Strategy\Exception 19 | */ 20 | public function action_session($provider = null) 21 | { 22 | // if provider data is somehow empty, it might not came from a provider. 23 | if (empty($provider)) 24 | { 25 | return \Response::error('404'); 26 | } 27 | 28 | try 29 | { 30 | return Strategy::make($provider)->authenticate(); 31 | } 32 | catch (Strategy\Exception $e) 33 | { 34 | return $this->action_error($provider, $e->getMessage()); 35 | } 36 | } 37 | 38 | /** 39 | * Get authorization code from callback and fetch user access_token and other information 40 | * 41 | * @access public 42 | * @param string $provider 43 | * @return Response 44 | * @throws Strategy\Exception 45 | */ 46 | public function action_callback($provider = null) 47 | { 48 | // if provider data is somehow empty, it might not came from a provider. 49 | if (empty($provider)) 50 | { 51 | return \Response::error('404'); 52 | } 53 | 54 | try 55 | { 56 | $strategy = Strategy::make($provider); 57 | return Strategy::login_or_register($strategy); 58 | } 59 | catch (Strategy\Exception $e) 60 | { 61 | return $this->action_error($provider, $e->getMessage()); 62 | } 63 | } 64 | 65 | /** 66 | * Display error from failed request 67 | * 68 | * @access protected 69 | * @param string $provider 70 | * @param string $e 71 | * @return Response 72 | */ 73 | protected function action_error($provider = null, $e = '') {} 74 | } -------------------------------------------------------------------------------- /libraries/oauth/provider/dropbox.php: -------------------------------------------------------------------------------- 1 | . 8 | * 9 | * [!!] This class does not implement the Dropbox API. It is only an 10 | * implementation of standard OAuth with Dropbox as the service provider. 11 | * 12 | * @package Kohana/OAuth 13 | * @category Provider 14 | * @author Kohana Team 15 | * @copyright (c) 2010 Kohana Team 16 | * @license http://kohanaframework.org/license 17 | * @since 3.0.7 18 | */ 19 | 20 | use OneAuth\OAuth\Provider as OAuth_Provider, 21 | OneAuth\OAuth\Consumer, 22 | OneAuth\OAuth\Request, 23 | OneAuth\OAuth\Token; 24 | 25 | class Dropbox extends OAuth_Provider 26 | { 27 | public $name = 'dropbox'; 28 | 29 | public function url_request_token() 30 | { 31 | return 'https://api.dropbox.com/1/oauth/request_token'; 32 | } 33 | 34 | public function url_authorize() 35 | { 36 | return 'http://www.dropbox.com/1/oauth/authorize'; 37 | } 38 | 39 | public function url_access_token() 40 | { 41 | return 'https://api.dropbox.com/1/oauth/access_token'; 42 | } 43 | 44 | public function get_user_info(Token $token, Consumer $consumer) 45 | { 46 | // Create a new GET request with the required parameters 47 | $request = Request::make('resource', 'GET', 'https://api.dropbox.com/1/account/info', array( 48 | 'oauth_consumer_key' => $consumer->key, 49 | 'oauth_token' => $token->access_token, 50 | )); 51 | 52 | // Sign the request using the consumer and token 53 | $request->sign($this->signature, $consumer, $token); 54 | 55 | $user = json_decode($request->execute()); 56 | 57 | // Create a response from the request 58 | return array( 59 | 'uid' => $token->uid, 60 | 'name' => $user->display_name, 61 | 'location' => $user->country, 62 | ); 63 | } 64 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OneAuth Bundle 2 | ============== 3 | 4 | OAuth, OAuth2 and OpenID Auth bundle for Laravel 5 | 6 | ## Installation 7 | 8 | ### Installation with Laravel Artisan 9 | 10 | php artisan bundle:install oneauth 11 | 12 | ### Bundle Registration 13 | 14 | 'oneauth' => array('auto' => true), 15 | 16 | ### Run the migration 17 | 18 | php artisan migrate 19 | 20 | ## OneAuth Documentation 21 | 22 | OneAuth Bundle come with an offline documentation, to view this please download and enable `bundocs` bundle, 23 | see [Bundocs Bundle](http://bundles.laravel.com/bundle/bundocs) for more detail. 24 | 25 | ## Contributors 26 | 27 | This bundle is a port from `Kohana\OAuth`, `OAuth2 Package for FuelPHP` and `NinjAuth Package for FuelPHP`. Original license is reserved to the contributors. 28 | 29 | ## License 30 | 31 | The MIT License 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining a copy 34 | of this software and associated documentation files (the "Software"), to deal 35 | in the Software without restriction, including without limitation the rights 36 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 37 | copies of the Software, and to permit persons to whom the Software is 38 | furnished to do so, subject to the following conditions: 39 | 40 | The above copyright notice and this permission notice shall be included in 41 | all copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 44 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 46 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 47 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 48 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 49 | THE SOFTWARE. 50 | -------------------------------------------------------------------------------- /libraries/oauth/signature/plaintext.php: -------------------------------------------------------------------------------- 1 | sign($request, $consumer, $token); 26 | * 27 | * [!!] This method implements [OAuth 1.0 Spec 9.4.1](http://oauth.net/core/1.0/#rfc.section.9.4.1). 28 | * 29 | * @param Request request 30 | * @param Consumer consumer 31 | * @param Token token 32 | * @return $this 33 | */ 34 | public function sign(Request $request, Consumer $consumer, Token $token = null) 35 | { 36 | // Use the signing key as the signature 37 | return $this->key($consumer, $token); 38 | } 39 | 40 | /** 41 | * Verify a plaintext signature. 42 | * 43 | * if ( ! $signature->verify($signature, $request, $consumer, $token)) 44 | * { 45 | * throw new Exception('Failed to verify signature'); 46 | * } 47 | * 48 | * [!!] This method implements [OAuth 1.0 Spec 9.4.2](http://oauth.net/core/1.0/#rfc.section.9.4.2). 49 | * 50 | * @param string signature to verify 51 | * @param Request request 52 | * @param Consumer consumer 53 | * @param Token token 54 | * @return boolean 55 | * @uses Signature_PLAINTEXT::sign 56 | */ 57 | public function verify($signature, Request $request, Consumer $consumer, Token $token = null) 58 | { 59 | return $signature === $this->key($consumer, $token); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /libraries/oauth2/provider/paypal.php: -------------------------------------------------------------------------------- 1 | $token->access_token 48 | )); 49 | 50 | $response = json_decode($request->execute()); 51 | 52 | $user = $response->identity; 53 | 54 | return array( 55 | 'uid' => $user->userId, 56 | 'nickname' => \Str::slug($user->fullName, '-'), 57 | 'name' => $user->fullName, 58 | 'first_name' => $user->firstName, 59 | 'last_name' => $user->lastName, 60 | 'email' => $user->emails[0], 61 | 'location' => isset($user->addresses) ? $user->addresses[0] : '', 62 | 'image' => null, 63 | 'description' => null, 64 | 'urls' => array( 65 | 'paypal' => null 66 | ) 67 | ); 68 | } 69 | } -------------------------------------------------------------------------------- /libraries/oauth2/provider/instagram.php: -------------------------------------------------------------------------------- 1 | user; 62 | 63 | // Create a response from the request 64 | return array( 65 | 'uid' => $user->id, 66 | 'nickname' => $user->username, 67 | 'name' => $user->full_name, 68 | 'image' => $user->profile_picture, 69 | 'urls' => array( 70 | 'website' => $user->website, 71 | ), 72 | ); 73 | } 74 | } -------------------------------------------------------------------------------- /libraries/oauth/provider/tumblr.php: -------------------------------------------------------------------------------- 1 | . 8 | * 9 | * [!!] This class does not implement the Tumblr API. It is only an 10 | * implementation of standard OAuth with Tumblr as the service provider. 11 | * 12 | * @package OAuth 13 | * @category Provider 14 | * @author Fuel Development Team 15 | */ 16 | 17 | use OneAuth\OAuth\Provider as OAuth_Provider, 18 | OneAuth\OAuth\Consumer, 19 | OneAuth\OAuth\Request, 20 | OneAuth\OAuth\Token; 21 | 22 | class Tumblr extends OAuth_Provider 23 | { 24 | public $name = 'tumblr'; 25 | 26 | public function url_request_token() 27 | { 28 | return 'http://www.tumblr.com/oauth/request_token'; 29 | } 30 | 31 | public function url_authorize() 32 | { 33 | return 'http://www.tumblr.com/oauth/authorize'; 34 | } 35 | 36 | public function url_access_token() 37 | { 38 | return 'http://www.tumblr.com/oauth/access_token'; 39 | } 40 | 41 | public function get_user_info(Token $token, Consumer $consumer) 42 | { 43 | // Create a new GET request with the required parameters 44 | $request = Request::make('resource', 'GET', 'http://api.tumblr.com/v2/user/info', array( 45 | 'oauth_consumer_key' => $consumer->key, 46 | 'oauth_token' => $token->access_token, 47 | )); 48 | 49 | // Sign the request using the consumer and token 50 | $request->sign($this->signature, $consumer, $token); 51 | 52 | $response = json_decode($request->execute()); 53 | 54 | $status = current($response); 55 | $response = next($response); 56 | $user = $response->user; 57 | 58 | // Create a response from the request 59 | return array( 60 | 'uid' => $user->name, // Tumblr doesn't provide a unique key other than name 61 | 'name' => $user->name, 62 | 'likes' => $user->likes, 63 | 'following' => $user->following, 64 | 'default_post_format' => $user->default_post_format, 65 | ); 66 | } 67 | } -------------------------------------------------------------------------------- /libraries/oauth2/core.php: -------------------------------------------------------------------------------- 1 | TRUE, 17 | * CURLOPT_POSTFIELDS => http_build_query($array), 18 | * )); 19 | * 20 | * @param string remote URL 21 | * @param array curl options 22 | * @return string 23 | * @throws Exception 24 | */ 25 | public static function remote($url, array $options = NULL) 26 | { 27 | // The transfer must always be returned 28 | $options[CURLOPT_RETURNTRANSFER] = TRUE; 29 | 30 | // Open a new remote connection 31 | $remote = curl_init($url); 32 | 33 | // Set connection options 34 | if ( ! curl_setopt_array($remote, $options)) 35 | { 36 | throw new Exception('Failed to set CURL options, check CURL documentation: http://php.net/curl_setopt_array'); 37 | } 38 | 39 | // Get the response 40 | $response = curl_exec($remote); 41 | 42 | if (curl_errno($remote) == 60) 43 | { 44 | curl_setopt($remote, CURLOPT_CAINFO, Bundle::path('oneauth').'vendor'.DS.'ca_chain_bundle.crt'); 45 | $response = curl_exec($remote); 46 | } 47 | 48 | // Get the response information 49 | $code = curl_getinfo($remote, CURLINFO_HTTP_CODE); 50 | 51 | if ($code AND ($code < 200 OR $code > 299)) 52 | { 53 | $error = $response; 54 | } 55 | elseif ($response === FALSE) 56 | { 57 | $error = curl_error($remote); 58 | } 59 | 60 | // Close the connection 61 | curl_close($remote); 62 | 63 | if (isset($error)) 64 | { 65 | throw new Exception(array( 66 | 'error' => $error, 67 | 'code' => $code, 68 | 'message' => sprintf('Error fetching remote %s [ status %s ] %s', $url, $code, $error), 69 | )); 70 | } 71 | 72 | return $response; 73 | } 74 | } -------------------------------------------------------------------------------- /libraries/oauth/provider/flickr.php: -------------------------------------------------------------------------------- 1 | . 8 | * 9 | * [!!] This class does not implement the Flickr API. It is only an 10 | * implementation of standard OAuth with Flickr as the service provider. 11 | * 12 | * @package Kohana/OAuth 13 | * @category Provider 14 | * @author Kohana Team 15 | * @copyright (c) 2010 Kohana Team 16 | * @license http://kohanaframework.org/license 17 | * @since 3.0.7 18 | */ 19 | 20 | use OneAuth\OAuth\Provider as OAuth_Provider, 21 | OneAuth\OAuth\Consumer, 22 | OneAuth\OAuth\Request, 23 | OneAuth\OAuth\Token; 24 | 25 | class Flickr extends OAuth_Provider 26 | { 27 | public $name = 'flickr'; 28 | 29 | public function url_request_token() 30 | { 31 | return 'http://www.flickr.com/services/oauth/request_token'; 32 | } 33 | 34 | public function url_authorize() 35 | { 36 | return 'http://www.flickr.com/services/oauth/authorize'; 37 | } 38 | 39 | public function url_access_token() 40 | { 41 | return 'http://www.flickr.com/services/oauth/access_token'; 42 | } 43 | 44 | public function get_user_info(Token $token, Consumer $consumer) 45 | { 46 | // Create a new GET request with the required parameters 47 | $request = Request::make('resource', 'GET', 'http://api.flickr.com/services/rest', array( 48 | 'oauth_consumer_key' => $consumer->key, 49 | 'oauth_token' => $token->access_token, 50 | 'nojsoncallback' => 1, 51 | 'format' => 'json', 52 | 'method' => 'flickr.test.login', 53 | )); 54 | 55 | // Sign the request using the consumer and token 56 | $request->sign($this->signature, $consumer, $token); 57 | 58 | $response = json_decode($request->execute(), true); 59 | 60 | // Create a response from the request 61 | return array( 62 | 'uid' => array_get($response, 'user.id'), 63 | 'name' => array_get($response, 'user.username._content'), 64 | 'nickname' => array_get($response, 'user.username._content'), 65 | ); 66 | } 67 | } -------------------------------------------------------------------------------- /libraries/oauth/signature.php: -------------------------------------------------------------------------------- 1 | name; 47 | * 48 | * @param string variable name 49 | * @return mixed 50 | */ 51 | public function __get($key) 52 | { 53 | return $this->$key; 54 | } 55 | 56 | /** 57 | * Get a signing key from a consumer and token. 58 | * 59 | * $key = $signature->key($consumer, $token); 60 | * 61 | * [!!] This method implements the signing key of [OAuth 1.0 Spec 9](http://oauth.net/core/1.0/#rfc.section.9). 62 | * 63 | * @param Consumer consumer 64 | * @param Token token 65 | * @return string 66 | * @uses OAuth::urlencode 67 | */ 68 | public function key(Consumer $consumer, Token $token = NULL) 69 | { 70 | $key = Core::urlencode($consumer->secret).'&'; 71 | 72 | if ($token) $key .= Core::urlencode($token->secret); 73 | 74 | return $key; 75 | } 76 | 77 | abstract public function sign(Request $request, Consumer $consumer, Token $token = NULL); 78 | 79 | abstract public function verify($signature, Request $request, Consumer $consumer, Token $token = NULL); 80 | } -------------------------------------------------------------------------------- /libraries/oauth/provider/vimeo.php: -------------------------------------------------------------------------------- 1 | . 8 | * 9 | * [!!] This class does not implement the Vimeo API. It is only an 10 | * implementation of standard OAuth with Vimeo as the service provider. 11 | * 12 | * @package OAuth 13 | * @author Fuel Development Team 14 | */ 15 | 16 | use OneAuth\OAuth\Provider as OAuth_Provider, 17 | OneAuth\OAuth\Consumer, 18 | OneAuth\OAuth\Request, 19 | OneAuth\OAuth\Token; 20 | 21 | class Vimeo extends OAuth_Provider 22 | { 23 | public $name = 'vimeo'; 24 | 25 | public function url_request_token() 26 | { 27 | return 'http://vimeo.com/oauth/request_token'; 28 | } 29 | 30 | public function url_authorize() 31 | { 32 | return 'http://vimeo.com/oauth/authorize'; 33 | } 34 | 35 | public function url_access_token() 36 | { 37 | return 'http://vimeo.com/oauth/access_token'; 38 | } 39 | 40 | public function get_user_info(Token $token, Consumer $consumer) 41 | { 42 | // Create a new GET request with the required parameters 43 | $request = Request::make('resource', 'GET', 'http://vimeo.com/api/rest/v2/', array( 44 | 'method' => 'vimeo.people.getInfo', 45 | 'oauth_consumer_key' => $consumer->key, 46 | 'oauth_token' => $token->access_token, 47 | 'format' => 'json', 48 | )); 49 | 50 | // Sign the request using the consumer and token 51 | $request->sign($this->signature, $consumer, $token); 52 | 53 | $response = json_decode($request->execute()); 54 | $user = $response->person; 55 | 56 | $profile_image = end($user->portraits->portrait); 57 | $url = current($user->url); 58 | 59 | // Create a response from the request 60 | return array( 61 | 'uid' => $user->id, 62 | 'nickname' => $user->username, 63 | 'name' => $user->display_name ?: $user->username, 64 | 'location' => $user->location, 65 | 'image' => $profile_image->_content, 66 | 'description' => $user->bio, 67 | 'urls' => array( 68 | 'website' => $url, 69 | 'vimeo' => $user->profileurl, 70 | ), 71 | ); 72 | } 73 | } -------------------------------------------------------------------------------- /libraries/oauth/signature/hmac/sha1.php: -------------------------------------------------------------------------------- 1 | sign($request, $consumer, $token); 27 | * 28 | * [!!] This method implements [OAuth 1.0 Spec 9.2.1](http://oauth.net/core/1.0/#rfc.section.9.2.1). 29 | * 30 | * @param Request request 31 | * @param Consumer consumer 32 | * @param Token token 33 | * @return string 34 | * @uses Signature::key 35 | * @uses Request::base_string 36 | */ 37 | public function sign(Request $request, Consumer $consumer, Token $token = null) 38 | { 39 | // Get the signing key 40 | $key = $this->key($consumer, $token); 41 | 42 | // Get the base string for the signature 43 | $base_string = $request->base_string(); 44 | 45 | // Sign the base string using the key 46 | return base64_encode(hash_hmac('sha1', $base_string, $key, true)); 47 | } 48 | 49 | /** 50 | * Verify a HMAC-SHA1 signature. 51 | * 52 | * if ( ! $signature->verify($signature, $request, $consumer, $token)) 53 | * { 54 | * throw new Exception('Failed to verify signature'); 55 | * } 56 | * 57 | * [!!] This method implements [OAuth 1.0 Spec 9.2.2](http://oauth.net/core/1.0/#rfc.section.9.2.2). 58 | * 59 | * @param string signature to verify 60 | * @param Request request 61 | * @param Consumer consumer 62 | * @param Token token 63 | * @return boolean 64 | * @uses Signature_HMAC_SHA1::sign 65 | */ 66 | public function verify($signature, Request $request, Consumer $consumer, Token $token = null) 67 | { 68 | return $signature === $this->sign($request, $consumer, $token); 69 | } 70 | } -------------------------------------------------------------------------------- /libraries/oauth2/token/access.php: -------------------------------------------------------------------------------- 1 | 'Required option not passed: access_token'.PHP_EOL.print_r($options, true))); 57 | } 58 | 59 | $this->access_token = $options['access_token']; 60 | 61 | // Some providers (not many) give the uid here, so lets take it 62 | isset($options['uid']) and $this->uid = $options['uid']; 63 | 64 | // Some providers (not many) give the user here, so lets take it 65 | isset($options['user']) and $this->user = $options['user']; 66 | 67 | // We need to know when the token expires, add num. seconds to current time 68 | isset($options['expires_in']) and $this->expires = time() + ((int) $options['expires_in']); 69 | 70 | // Facebook is just being a spec ignoring jerk 71 | isset($options['expires']) and $this->expires = time() + ((int) $options['expires']); 72 | 73 | // Grab a refresh token so we can update access tokens when they expires 74 | isset($options['refresh_token']) and $this->refresh_token = $options['refresh_token']; 75 | } 76 | 77 | /** 78 | * Returns the token key. 79 | * 80 | * @return string 81 | */ 82 | public function __toString() 83 | { 84 | return (string) $this->access_token; 85 | } 86 | } -------------------------------------------------------------------------------- /libraries/oauth/provider/twitter.php: -------------------------------------------------------------------------------- 1 | . 8 | * 9 | * [!!] This class does not implement the Twitter API. It is only an 10 | * implementation of standard OAuth with Twitter as the service provider. 11 | * 12 | * @package Kohana/OAuth 13 | * @category Provider 14 | * @author Kohana Team 15 | * @copyright (c) 2010 Kohana Team 16 | * @license http://kohanaframework.org/license 17 | * @since 3.0.7 18 | */ 19 | 20 | use OneAuth\OAuth\Provider as OAuth_Provider, 21 | OneAuth\OAuth\Consumer, 22 | OneAuth\OAuth\Request, 23 | OneAuth\OAuth\Token; 24 | 25 | class Twitter extends OAuth_Provider 26 | { 27 | public $name = 'twitter'; 28 | 29 | public $uid_key = 'user_id'; 30 | 31 | public function url_request_token() 32 | { 33 | return 'https://api.twitter.com/oauth/request_token'; 34 | } 35 | 36 | public function url_authorize() 37 | { 38 | return 'https://api.twitter.com/oauth/authenticate'; 39 | } 40 | 41 | public function url_access_token() 42 | { 43 | return 'https://api.twitter.com/oauth/access_token'; 44 | } 45 | 46 | public function get_user_info(Token $token, Consumer $consumer) 47 | { 48 | // Create a new GET request with the required parameters 49 | $request = Request::make('resource', 'GET', 'http://api.twitter.com/1/users/lookup.json', array( 50 | 'oauth_consumer_key' => $consumer->key, 51 | 'oauth_token' => $token->access_token, 52 | 'user_id' => $token->uid, 53 | )); 54 | 55 | // Sign the request using the consumer and token 56 | $request->sign($this->signature, $consumer, $token); 57 | 58 | $user = current(json_decode($request->execute())); 59 | 60 | // Create a response from the request 61 | return array( 62 | 'uid' => $token->uid, 63 | 'nickname' => $user->screen_name, 64 | 'name' => $user->name ?: $user->screen_name, 65 | 'location' => $user->location, 66 | 'image' => $user->profile_image_url, 67 | 'description' => $user->description, 68 | 'urls' => array( 69 | 'website' => $user->url, 70 | 'twitter' => 'http://twitter.com/'.$user->screen_name, 71 | ), 72 | ); 73 | } 74 | } -------------------------------------------------------------------------------- /libraries/oauth/consumer.php: -------------------------------------------------------------------------------- 1 | key = $options['key']; 62 | 63 | $this->secret = $options['secret']; 64 | 65 | if (isset($options['callback'])) 66 | { 67 | $this->callback = $options['callback']; 68 | } 69 | 70 | if (isset($options['scope'])) 71 | { 72 | $this->scope = $options['scope']; 73 | } 74 | } 75 | 76 | /** 77 | * Return the value of any protected class variable. 78 | * 79 | * // Get the consumer key 80 | * $key = $consumer->key; 81 | * 82 | * @param string variable name 83 | * @return mixed 84 | */ 85 | public function __get($key) 86 | { 87 | return $this->$key; 88 | } 89 | 90 | /** 91 | * Change the consumer callback. 92 | * 93 | * @param string new consumer callback 94 | * @return $this 95 | */ 96 | public function callback($callback) 97 | { 98 | $this->callback = $callback; 99 | 100 | return $this; 101 | } 102 | } -------------------------------------------------------------------------------- /start.php: -------------------------------------------------------------------------------- 1 | Bundle::path('oneauth').'libraries'.DS.'auth', 12 | 'OneAuth\\OAuth' => Bundle::path('oneauth').'libraries'.DS.'oauth', 13 | 'OneAuth\\OAuth2' => Bundle::path('oneauth').'libraries'.DS.'oauth2', 14 | )); 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | OneAuth Events Listener 19 | |-------------------------------------------------------------------------- 20 | | 21 | | Lets listen to when OneAuth logged a user using any of the supported 22 | | providers. 23 | | 24 | | OneAuth also listen to when user actually logged in to Laravel 25 | */ 26 | Event::listen('oneauth.logged', function ($client, $user_data) 27 | { 28 | // if user already logged in, don't do anything 29 | if (IoC::resolve('oneauth.driver: auth.check')) return ; 30 | 31 | // OneAuth should login the user if user exist and is not logged in 32 | if (is_numeric($client->user_id) and $client->user_id > 0) 33 | { 34 | IoC::resolve('oneauth.driver: auth.login', array($client->user_id)); 35 | } 36 | }); 37 | 38 | Event::listen('oneauth.sync', function ($user_id) 39 | { 40 | return OneAuth\Auth\Core::sync($user_id); 41 | }); 42 | 43 | /* 44 | |-------------------------------------------------------------------------- 45 | | OneAuth IoC 46 | |-------------------------------------------------------------------------- 47 | | 48 | | Register Auth adapter as IoC, allow it to be replaced by any Authentication 49 | | bundle that doesn't use Laravel\Auth\Drivers 50 | */ 51 | if ( ! IoC::registered('oneauth.driver: auth.check')) 52 | { 53 | // Check whether current user is logged-in to the system or a guest 54 | IoC::register('oneauth.driver: auth.check', function () 55 | { 56 | return Auth::check(); 57 | }); 58 | } 59 | 60 | if ( ! IoC::registered('oneauth.driver: auth.user')) 61 | { 62 | // Get logged in user, if the user doesn't logged in yet, return null 63 | IoC::register('oneauth.driver: auth.user', function () 64 | { 65 | return Auth::user(); 66 | }); 67 | } 68 | 69 | if ( ! IoC::registered('oneauth.driver: auth.login')) 70 | { 71 | // Login the user by users.id 72 | IoC::register('oneauth.driver: auth.login', function ($user_id) 73 | { 74 | return Auth::login($user_id); 75 | }); 76 | } -------------------------------------------------------------------------------- /libraries/auth/strategy/oauth.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | use OneAuth\Auth\Strategy as Auth_Strategy, 11 | OneAuth\OAuth\Consumer, 12 | OneAuth\OAuth\Provider; 13 | 14 | class Oauth extends Auth_Strategy 15 | { 16 | public $name = 'oauth'; 17 | public $provider; 18 | 19 | public function authenticate() 20 | { 21 | // Create an consumer from the config 22 | $consumer = Consumer::make($this->config); 23 | 24 | // Load the provider 25 | $provider = Provider::make($this->provider); 26 | 27 | // Create the URL to return the user to 28 | $callback = array_get($this->config, 'callback') ?: \URL::to(\Config::get('oneauth::urls.callback', 'connect/callback')); 29 | $callback = rtrim($callback, '/').'/'.$this->provider; 30 | 31 | // Add the callback URL to the consumer 32 | $consumer->callback($callback); 33 | 34 | // Get a request token for the consumer 35 | $token = $provider->request_token($consumer); 36 | 37 | // Store the token 38 | \Cookie::put('oauth_token', base64_encode(serialize($token))); 39 | 40 | // Redirect to the twitter login page 41 | return \Redirect::to($provider->authorize_url($token, array( 42 | 'oauth_callback' => $callback, 43 | ))); 44 | } 45 | 46 | public function callback() 47 | { 48 | // Create an consumer from the config 49 | $this->consumer = Consumer::make($this->config); 50 | 51 | // Load the provider 52 | $this->provider = Provider::make($this->provider); 53 | 54 | if ($token = \Cookie::get('oauth_token')) 55 | { 56 | // Get the token from storage 57 | $this->token = unserialize(base64_decode($token)); 58 | } 59 | 60 | if ( ! property_exists($this, 'token')) 61 | { 62 | throw new Exception('Invalid token'); 63 | } 64 | 65 | if ($this->token and $this->token->access_token !== \Input::get('oauth_token')) 66 | { 67 | // Delete the token, it is not valid 68 | \Cookie::forget('oauth_token'); 69 | 70 | // Send the user back to the beginning 71 | throw new Exception('invalid token after coming back to site'); 72 | } 73 | 74 | // Get the verifier 75 | $verifier = \Input::get('oauth_verifier'); 76 | 77 | // Store the verifier in the token 78 | $this->token->verifier($verifier); 79 | 80 | // Exchange the request token for an access token 81 | return $this->provider->access_token($this->token, $this->consumer); 82 | } 83 | } -------------------------------------------------------------------------------- /libraries/oauth2/provider/windowlive.php: -------------------------------------------------------------------------------- 1 | $token->access_token, 66 | )); 67 | 68 | // perform network request 69 | $user = json_decode($request->execute()); 70 | 71 | // create a response from the request and return it 72 | return array( 73 | 'uid' => $user->id, 74 | 'name' => $user->name, 75 | 'emial' => isset($user->emails->preferred) ? $user->emails->preferred : null, 76 | 'nickname' => \Str::slug($user->name, '-'), 77 | 'locale' => $user->locale, 78 | 'urls' => array( 79 | 'windowslive' => $user->link 80 | ), 81 | ); 82 | } 83 | } -------------------------------------------------------------------------------- /libraries/oauth/token.php: -------------------------------------------------------------------------------- 1 | access_token = $options['access_token']; 81 | 82 | $this->secret = $options['secret']; 83 | 84 | // If we have a uid lets use it 85 | array_get($options, 'uid') and $this->uid = $options['uid']; 86 | } 87 | 88 | /** 89 | * Return the value of any protected class variable. 90 | * 91 | * // Get the token secret 92 | * $secret = $token->secret; 93 | * 94 | * @param string variable name 95 | * @return mixed 96 | */ 97 | public function __get($key) 98 | { 99 | return $this->$key; 100 | } 101 | 102 | /** 103 | * Return a boolean if the property is set 104 | * 105 | * // Get the token secret 106 | * if ($token->secret) exit('YAY SECRET'); 107 | * 108 | * @param string variable name 109 | * @return bool 110 | */ 111 | public function __isset($key) 112 | { 113 | return isset($this->$key); 114 | } 115 | 116 | /** 117 | * Returns the token key. 118 | * 119 | * @return string 120 | */ 121 | public function __toString() 122 | { 123 | return (string) $this->access_token; 124 | } 125 | } -------------------------------------------------------------------------------- /libraries/oauth/provider/linkedin.php: -------------------------------------------------------------------------------- 1 | . 8 | * 9 | * [!!] This class does not implement the LinkedIn API. It is only an 10 | * implementation of standard OAuth with LinkedIn as the service provider. 11 | * 12 | * @package Kohana/OAuth 13 | * @category Provider 14 | * @author Kohana Team 15 | * @copyright (c) 2010 Kohana Team 16 | * @license http://kohanaframework.org/license 17 | * @since 3.0.7 18 | */ 19 | 20 | use OneAuth\OAuth\Provider as OAuth_Provider, 21 | OneAuth\OAuth\Consumer, 22 | OneAuth\OAuth\Request, 23 | OneAuth\OAuth\Token; 24 | 25 | class Linkedin extends OAuth_Provider 26 | { 27 | public $name = 'linkedin'; 28 | 29 | public function url_request_token() 30 | { 31 | return 'https://api.linkedin.com/uas/oauth/requestToken'; 32 | } 33 | 34 | public function url_authorize() 35 | { 36 | return 'https://api.linkedin.com/uas/oauth/authorize'; 37 | } 38 | 39 | public function url_access_token() 40 | { 41 | return 'https://api.linkedin.com/uas/oauth/accessToken'; 42 | } 43 | 44 | public function get_user_info(Token $token, Consumer $consumer) 45 | { 46 | // Create a new GET request with the required parameters 47 | $url = 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,member-url-resources,picture-url,location,public-profile-url)?format=json'; 48 | $request = Request::make('resource', 'GET', $url, array( 49 | 'oauth_consumer_key' => $consumer->key, 50 | 'oauth_token' => $token->access_token, 51 | )); 52 | 53 | // Sign the request using the consumer and token 54 | $request->sign($this->signature, $consumer, $token); 55 | 56 | $user = json_decode($request->execute(), true); 57 | 58 | // Split the profile url to get the user's nickname 59 | if (isset($user['publicProfileUrl'])) { 60 | $linked_url = $user['publicProfileUrl']; 61 | $nickname = end(explode('/', $user['publicProfileUrl'])); 62 | } else { 63 | $linked_url = $nickname = false; 64 | } 65 | 66 | // Create a response from the request 67 | return array( 68 | 'uid' => $user['id'], 69 | 'name' => $user['firstName'].' '.$user['lastName'], 70 | 'image' => $user['pictureUrl'], 71 | 'nickname' => $nickname, 72 | 'description' => $user['headline'], 73 | 'location' => array_get($user, 'location.name'), 74 | 'urls' => array( 75 | 'linkedin' => $linked_url, 76 | ), 77 | ); 78 | } 79 | 80 | protected function parse($string) 81 | { 82 | $data = is_string($string) ? simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA) : $string; 83 | $arr = array(); 84 | 85 | // Convert all objects SimpleXMLElement to array recursively 86 | foreach ((array)$data as $key => $val) 87 | { 88 | $arr[$key] = (is_array($val) or is_object($val)) ? $this->_from_xml($val) : $val; 89 | } 90 | 91 | return $arr; 92 | } 93 | } -------------------------------------------------------------------------------- /libraries/auth/core.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | use \Config, \Event, \Exception, \IoC, \Redirect, \Session; 10 | 11 | class Core 12 | { 13 | /** 14 | * Redirect user based on type 15 | * 16 | * @static 17 | * @access public 18 | * @param string $type 19 | * @return void 20 | * @throws AuthException 21 | */ 22 | public static function redirect($type) 23 | { 24 | if (is_null($path = Config::get("oneauth::urls.{$type}"))) 25 | { 26 | throw new Exception(__METHOD__.": Unable to redirect using {$type} type."); 27 | } 28 | 29 | return Redirect::to($path); 30 | } 31 | 32 | /** 33 | * Login ar register new oneauth_clients 34 | * 35 | * @static 36 | * @access public 37 | * @param array $user_data 38 | * @return Redirect 39 | */ 40 | public static function login($user_data) 41 | { 42 | $client = Client::where('provider', '=', $user_data['provider']) 43 | ->where('uid', '=', $user_data['info']['uid']) 44 | ->first(); 45 | 46 | if (is_null($client)) 47 | { 48 | $client = new Client(array( 49 | 'uid' => $user_data['info']['uid'], 50 | 'provider' => $user_data['provider'], 51 | )); 52 | } 53 | 54 | // Link to user using Auth. 55 | if ( ! is_null($user = IoC::resolve('oneauth.driver: auth.user'))) 56 | { 57 | $client->user_id = $user->id; 58 | } 59 | 60 | $client->access_token = $user_data['token']->access_token ?: null; 61 | $client->secret = $user_data['token']->secret ?: null; 62 | $client->refresh_token = $user_data['token']->refresh_token ?: null; 63 | 64 | $client->save(); 65 | 66 | $user_data['token'] = serialize($user_data['token']); 67 | 68 | Event::fire('oneauth.logged', array($client, $user_data)); 69 | Session::put('oneauth', $user_data); 70 | 71 | return Core::redirect(IoC::resolve('oneauth.driver: auth.check') ? 'logged_in' : 'registration'); 72 | } 73 | 74 | /** 75 | * Retrieve user information and access token from Session, this is to allow developer 76 | * to reuse the access token to retrieve or send API request to server without having 77 | * to reinitiate OAuth\Token\Access class. 78 | * 79 | * @static 80 | * @access public 81 | * @return array 82 | */ 83 | public static function session() 84 | { 85 | if (($user_data = Session::get('oneauth'))) 86 | { 87 | $user_data['token'] = unserialize($user_data['token']); 88 | } 89 | return $user_data; 90 | } 91 | 92 | /** 93 | * Sync oneauth_clients with user 94 | * 95 | * @static 96 | * @access public 97 | * @param array $user_data 98 | * @return bool 99 | */ 100 | public static function sync($user_id) 101 | { 102 | if ( ! Session::has('oneauth')) return; 103 | 104 | $user_data = Session::get('oneauth'); 105 | 106 | $client = Client::where('provider', '=', $user_data['provider']) 107 | ->where('uid', '=', $user_data['info']['uid']) 108 | ->first(); 109 | 110 | if (is_null($client)) return; 111 | 112 | $client->user_id = $user_id; 113 | $client->save(); 114 | 115 | return true; 116 | } 117 | } -------------------------------------------------------------------------------- /libraries/oauth2/provider/basecamp.php: -------------------------------------------------------------------------------- 1 | $token->access_token, 43 | )); 44 | 45 | $user = json_decode($request->execute()); 46 | 47 | /** 48 | * Create a response from the request 49 | * Basecamp Authorization response has extra requirements and doesn't 50 | * give some of the meta information below. 51 | * Image is available via the me.json call. 52 | */ 53 | return array( 54 | 'uid' => $user->identity->id, 55 | 'name' => $user->identity->first_name .' '.$user->identity->last_name, 56 | 'nickname' => null, 57 | 'email' => isset($user->identity->email_address) ? $user->identity->email_address : null, 58 | 'image' => '', 59 | 'urls' => array(), 60 | ); 61 | } 62 | 63 | //Override this method for basecamp-specific items 64 | public function authorize($options = array()) 65 | { 66 | $state = md5(uniqid(rand(), TRUE)); 67 | Session::put('state', $state); 68 | 69 | $url = $this->url_authorize().'?'.http_build_query(array( 70 | 'type' => 'web_server', 71 | 'client_id' => $this->client_id, 72 | 'redirect_uri' => array_get($options, 'redirect_uri', $this->redirect_uri), 73 | 'state' => $state, 74 | 'response_type' => 'code', 75 | )); 76 | 77 | return Redirect::to($url); 78 | } 79 | 80 | //Override this method for Basecamp-specific items 81 | public function access($code, $options = array()) 82 | { 83 | $params = array( 84 | 'client_id' => $this->client_id, 85 | 'client_secret' => $this->client_secret, 86 | 'grant_type' => array_get($options, 'grant_type', 'authorization_code'), 87 | 'type' => 'web_server' 88 | ); 89 | 90 | switch ($params['grant_type']) 91 | { 92 | case 'authorization_code': 93 | $params['code'] = $code; 94 | $params['redirect_uri'] = array_get($options, 'redirect_uri', $this->redirect_uri); 95 | break; 96 | 97 | case 'refresh_token': 98 | $params['refresh_token'] = $code; 99 | break; 100 | } 101 | 102 | $response = null; 103 | $url = $this->url_access_token(); 104 | 105 | $request = Request::make('access', $this->method, $url, $params); 106 | $response = $request->execute(); 107 | 108 | if (isset($response->error)) 109 | { 110 | throw new Exception($response); 111 | } 112 | 113 | return Token::make('access', $response->params); 114 | } 115 | } -------------------------------------------------------------------------------- /orchestra.php: -------------------------------------------------------------------------------- 1 | handles('orchestra::register'), 13 | 'login' => handles('orchestra::login'), 14 | 'callback' => handles('oneauth::connect/callback'), 15 | 16 | 'registered' => handles('orchestra'), 17 | 'logged_in' => handles('orchestra'), 18 | )); 19 | 20 | Orchestra\Extension\Config::map('oneauth', array( 21 | 'basecamp_id' => 'oneauth::api.providers.basecamp.id', 22 | 'basecamp_secret' => 'oneauth::api.providers.basecamp.secret', 23 | 24 | 'dropbox_key' => 'oneauth::api.providers.dropbox.key', 25 | 'dropbox_secret' => 'oneauth::api.providers.dropbox.secret', 26 | 27 | 'facebook_id' => 'oneauth::api.providers.facebook.id', 28 | 'facebook_secret' => 'oneauth::api.providers.facebook.secret', 29 | 'facebook_scope' => 'oneauth::api.providers.facebook.scope', 30 | 31 | 'flickr_key' => 'oneauth::api.providers.flickr.key', 32 | 'flickr_secret' => 'oneauth::api.providers.flickr.secret', 33 | 34 | 'foursquare_id' => 'oneauth::api.providers.foursquare.id', 35 | 'foursquare_secret' => 'oneauth::api.providers.foursquare.secret', 36 | 37 | 'github_id' => 'oneauth::api.providers.github.id', 38 | 'github_secret' => 'oneauth::api.providers.github.secret', 39 | 40 | 'google_id' => 'oneauth::api.providers.google.id', 41 | 'google_secret' => 'oneauth::api.providers.google.secret', 42 | 43 | 'instagram_id' => 'oneauth::api.providers.instagram.id', 44 | 'instagram_secret' => 'oneauth::api.providers.instagram.secret', 45 | 46 | 'linkedin_key' => 'oneauth::api.providers.linkedin.key', 47 | 'linkedin_secret' => 'oneauth::api.providers.linkedin.secret', 48 | 49 | 'paypal_id' => 'oneauth::api.providers.paypal.id', 50 | 'paypal_secret' => 'oneauth::api.providers.paypal.secret', 51 | 52 | 'soundcloud_id' => 'oneauth::api.providers.soundcloud.id', 53 | 'soundcloud_secret' => 'oneauth::api.providers.soundcloud.secret', 54 | 55 | 'tumblr_key' => 'oneauth::api.providers.tumblr.key', 56 | 'tumblr_secret' => 'oneauth::api.providers.tumblr.secret', 57 | 58 | 'twitter_key' => 'oneauth::api.providers.twitter.key', 59 | 'twitter_secret' => 'oneauth::api.providers.twitter.secret', 60 | 61 | 'vimeo_key' => 'oneauth::api.providers.vimeo.key', 62 | 'vimeo_secret' => 'oneauth::api.providers.vimeo.secret', 63 | 64 | 'windowlive_id' => 'oneauth::api.providers.windowlive.id', 65 | 'windowlive_secret' => 'oneauth::api.providers.windowlive.secret', 66 | 67 | )); 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | Integration with Orchestra 72 | |-------------------------------------------------------------------------- 73 | | 74 | | Map controller routing for OneAuth 75 | */ 76 | 77 | Route::controller(array('oneauth::connect')); 78 | 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | Integration with Orchestra 82 | |-------------------------------------------------------------------------- 83 | | 84 | | Add on logged-in integration between OneAuth and Orchestra 85 | */ 86 | 87 | Event::listen('orchestra.logged.in', function() 88 | { 89 | $user = Auth::user(); 90 | Event::fire('oneauth.sync', array($user->id)); 91 | }); 92 | 93 | include_once Bundle::path('oneauth').'orchestra'.DS.'configure'.EXT; -------------------------------------------------------------------------------- /libraries/oauth2/provider/google.php: -------------------------------------------------------------------------------- 1 | $this->client_id, 52 | 'redirect_uri' => array_get($options, 'redirect_uri', $this->redirect_uri), 53 | 'state' => $state, 54 | 'scope' => is_array($this->scope) ? implode($this->scope_seperator, $this->scope) : $this->scope, 55 | 'response_type' => 'code', 56 | 'access_type' => 'offline', 57 | 'approval_prompt' => 'force', 58 | ); 59 | 60 | $url = $this->url_authorize().'?'.http_build_query($params); 61 | 62 | return \Redirect::to($url); 63 | } 64 | 65 | public function __construct(array $options = array()) 66 | { 67 | // Now make sure we have the default scope to get user data 68 | $options['scope'] = array_merge( 69 | 70 | // We need this default feed to get the authenticated users basic information 71 | array('https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email'), 72 | 73 | // And take either a string and array it, or empty array to merge into 74 | (array) array_get($options, 'scope', array()) 75 | ); 76 | 77 | parent::__construct($options); 78 | } 79 | 80 | /* 81 | * Get access to the API 82 | * 83 | * @param string The access code 84 | * @return object Success or failure along with the response details 85 | */ 86 | public function access($code, $options = array()) 87 | { 88 | if ($code === null) 89 | { 90 | throw new Exception(array('message' => 'Expected Authorization Code from '.ucfirst($this->name).' is missing')); 91 | } 92 | 93 | return parent::access($code, $options); 94 | } 95 | 96 | public function get_user_info(Token_Access $token) 97 | { 98 | $request = Request::make('resource', 'GET', 'https://www.googleapis.com/oauth2/v1/userinfo', array( 99 | 'access_token' => $token->access_token, 100 | )); 101 | 102 | $user = json_decode($request->execute(), true); 103 | 104 | return array( 105 | 'uid' => $user['email'], 106 | 'nickname' => \Str::slug($user['name'], '-'), 107 | 'name' => $user['name'] . ' ' . $user['family_name'], 108 | 'email' => $user['email'], 109 | 'location' => null, 110 | 'image' => $user['picture'], 111 | 'description' => null, 112 | 'urls' => array( 113 | 'googleplus' => $user['link'], 114 | ), 115 | ); 116 | } 117 | } -------------------------------------------------------------------------------- /libraries/auth/strategy.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | use \Config; 10 | 11 | abstract class Strategy 12 | { 13 | public $provider = null; 14 | public $config = array(); 15 | 16 | /** 17 | * Strategy name 18 | * 19 | * @access public 20 | * @var string 21 | */ 22 | public $name = null; 23 | 24 | /** 25 | * List of available provider 26 | * 27 | * @static 28 | * @access protected 29 | * @var array 30 | */ 31 | protected static $providers = array( 32 | 'basecamp' => 'OAuth2', 33 | 'dropbox' => 'OAuth', 34 | 'facebook' => 'OAuth2', 35 | 'flickr' => 'OAuth', 36 | 'foursquare' => 'OAuth2', 37 | 'github' => 'OAuth2', 38 | 'google' => 'OAuth2', 39 | 'instagram' => 'OAuth2', 40 | 'linkedin' => 'OAuth', 41 | //'openid' => 'OpenId', 42 | 'paypal' => 'OAuth2', 43 | 'soundcloud' => 'OAuth2', 44 | 'tumblr' => 'OAuth', 45 | 'twitter' => 'OAuth', 46 | 'vimeo' => 'OAuth', 47 | 'windowlive' => 'OAuth2', 48 | ); 49 | 50 | /** 51 | * Generic construct method 52 | * 53 | * @access public 54 | * @return void 55 | */ 56 | public function __construct($provider) 57 | { 58 | $this->provider = $provider; 59 | 60 | $this->config = Config::get("oneauth::api.providers.{$provider}", null); 61 | 62 | if (is_null($this->config)) 63 | { 64 | throw new Strategy\Exception(sprintf('Provider "%s" has no config.', $provider)); 65 | } 66 | } 67 | 68 | /** 69 | * Forge a new strategy 70 | * 71 | * @static 72 | * @access public 73 | * @return Auth_Strategy 74 | * @throws Strategy\Exception 75 | */ 76 | public static function make($provider = null) 77 | { 78 | $strategy = Config::get("oneauth::providers.{$provider}.strategy") ?: array_get(static::$providers, $provider); 79 | 80 | if (is_null($strategy)) 81 | { 82 | throw new Strategy\Exception(sprintf('Provider "%s" has no strategy.', $provider)); 83 | } 84 | 85 | switch ($strategy) 86 | { 87 | case 'OAuth' : 88 | return new Strategy\Oauth($provider); 89 | break; 90 | case 'OAuth2' : 91 | return new Strategy\Oauth2($provider); 92 | break; 93 | } 94 | } 95 | 96 | /** 97 | * Determine whether authenticated user should be continue to login or register new user 98 | * 99 | * @static 100 | * @access public 101 | * @param object $strategy 102 | * @return void 103 | * @throws Strategy\Exception 104 | */ 105 | public static function login_or_register($strategy) 106 | { 107 | $token = $strategy->callback(); 108 | $user_info = static::get_user_info($strategy, $token); 109 | 110 | $user_data = array( 111 | 'token' => $token, 112 | 'info' => $user_info, 113 | 'provider' => $strategy->provider->name, 114 | ); 115 | 116 | return Core::login($user_data); 117 | } 118 | 119 | /** 120 | * Get user information from provider 121 | * 122 | * @static 123 | * @access protected 124 | * @param object $strategy 125 | * @param object $response 126 | * @return array 127 | * @throws Strategy\Exception 128 | */ 129 | protected static function get_user_info($strategy, $token) 130 | { 131 | switch ($strategy->name) 132 | { 133 | case 'oauth': 134 | return $strategy->provider->get_user_info($token, $strategy->consumer); 135 | break; 136 | 137 | case 'oauth2': 138 | return $strategy->provider->get_user_info($token); 139 | break; 140 | 141 | case 'openid': 142 | return $strategy->get_user_info($token); 143 | break; 144 | 145 | default: 146 | throw new Strategy\Exception("Unsupported Strategy: {$strategy->name}"); 147 | } 148 | } 149 | 150 | abstract public function authenticate(); 151 | } -------------------------------------------------------------------------------- /orchestra/configure.php: -------------------------------------------------------------------------------- 1 | extend(function ($form) 6 | { 7 | $form->fieldset('Basecamp OAuth2', function ($fieldset) 8 | { 9 | $fieldset->control('input:text', 'Basecamp ID', 'basecamp_id'); 10 | $fieldset->control('input:text', 'Basecamp Secret', 'basecamp_secret'); 11 | }); 12 | 13 | $form->fieldset('Dropbox OAuth', function ($fieldset) 14 | { 15 | $fieldset->control('input:text', 'Dropbox Key', 'dropbox_key'); 16 | $fieldset->control('input:text', 'Dropbox Secret', 'dropbox_secret'); 17 | }); 18 | 19 | $form->fieldset('Facebook OAuth2', function ($fieldset) 20 | { 21 | $fieldset->control('input:text', 'Facebook ID', 'facebook_id'); 22 | $fieldset->control('input:text', 'Facebook Secret', 'facebook_secret'); 23 | $fieldset->control('input:text', 'facebook_scope', function ($control) 24 | { 25 | $control->label = 'Facebook Scope'; 26 | $control->value = function ($row) 27 | { 28 | $value = ! empty($row->facebook_scope) ? $row->facebook_scope : Config::get('oneauth::api.providers.facebook.scope'); 29 | 30 | return $value; 31 | }; 32 | }); 33 | }); 34 | 35 | $form->fieldset('Flickr OAuth', function ($fieldset) 36 | { 37 | $fieldset->control('input:text', 'Flickr Key', 'flickr_key'); 38 | $fieldset->control('input:text', 'Flickr Secret', 'flickr_secret'); 39 | }); 40 | 41 | $form->fieldset('FourSquare OAuth2', function ($fieldset) 42 | { 43 | $fieldset->control('input:text', 'FourSquare ID', 'foursquare_id'); 44 | $fieldset->control('input:text', 'FourSquare Secret', 'foursquare_secret'); 45 | }); 46 | 47 | $form->fieldset('Github OAuth2', function ($fieldset) 48 | { 49 | $fieldset->control('input:text', 'Github ID', 'github_id'); 50 | $fieldset->control('input:text', 'Github Secret', 'github_secret'); 51 | }); 52 | 53 | $form->fieldset('Google OAuth2', function ($fieldset) 54 | { 55 | $fieldset->control('input:text', 'Google ID', 'google_id'); 56 | $fieldset->control('input:text', 'Google Secret', 'google_secret'); 57 | }); 58 | 59 | $form->fieldset('Instagram OAuth2', function ($fieldset) 60 | { 61 | $fieldset->control('input:text', 'Instagram ID', 'instagram_id'); 62 | $fieldset->control('input:text', 'Instagram Secret', 'instagram_secret'); 63 | }); 64 | 65 | $form->fieldset('LinkedIn OAuth', function ($fieldset) 66 | { 67 | $fieldset->control('input:text', 'LinkedIn Key', 'linkedin_key'); 68 | $fieldset->control('input:text', 'LinkedIn Secret', 'linkedin_secret'); 69 | }); 70 | 71 | $form->fieldset('Paypal OAuth2', function ($fieldset) 72 | { 73 | $fieldset->control('input:text', 'Paypal ID', 'paypal_id'); 74 | $fieldset->control('input:text', 'Paypal Secret', 'paypal_secret'); 75 | }); 76 | 77 | $form->fieldset('Soundcloud OAuth2', function ($fieldset) 78 | { 79 | $fieldset->control('input:text', 'Soundcloud ID', 'soundcloud_id'); 80 | $fieldset->control('input:text', 'Soundcloud Secret', 'soundcloud_secret'); 81 | }); 82 | 83 | $form->fieldset('Tumblr OAuth', function ($fieldset) 84 | { 85 | $fieldset->control('input:text', 'Tumblr Key', 'tumblr_key'); 86 | $fieldset->control('input:text', 'Tumblr Secret', 'tumblr_secret'); 87 | }); 88 | 89 | $form->fieldset('Twitter OAuth', function ($fieldset) 90 | { 91 | $fieldset->control('input:text', 'Twitter Key', 'twitter_key'); 92 | $fieldset->control('input:text', 'Twitter Secret', 'twitter_secret'); 93 | }); 94 | 95 | $form->fieldset('Vimeo OAuth', function ($fieldset) 96 | { 97 | $fieldset->control('input:text', 'Vimeo Key', 'vimeo_key'); 98 | $fieldset->control('input:text', 'Vimeo Secret', 'vimeo_secret'); 99 | }); 100 | 101 | $form->fieldset('WindowLive OAuth2', function ($fieldset) 102 | { 103 | $fieldset->control('input:text', 'WindowLive ID', 'windowlive_id'); 104 | $fieldset->control('input:text', 'WindowLive Secret', 'windowlive_secret'); 105 | }); 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /libraries/oauth2/provider.php: -------------------------------------------------------------------------------- 1 | client_id = array_get($options, 'id')) 104 | { 105 | throw new Exception(array('message' => 'Required option not provided: id')); 106 | } 107 | 108 | $this->callback = array_get($options, 'callback'); 109 | $this->client_secret = array_get($options, 'secret'); 110 | $this->scope = array_get($options, 'scope', $this->scope); 111 | 112 | $this->redirect_uri = URL::current(); 113 | } 114 | 115 | /** 116 | * Return the value of any protected class variable. 117 | * 118 | * // Get the provider signature 119 | * $signature = $provider->signature; 120 | * 121 | * @param string variable name 122 | * @return mixed 123 | */ 124 | public function __get($key) 125 | { 126 | return $this->$key; 127 | } 128 | 129 | /** 130 | * Returns the authorization URL for the provider. 131 | * 132 | * $url = $provider->url_authorize(); 133 | * 134 | * @return string 135 | */ 136 | abstract public function url_authorize(); 137 | 138 | /** 139 | * Returns the access token endpoint for the provider. 140 | * 141 | * $url = $provider->url_access_token(); 142 | * 143 | * @return string 144 | */ 145 | abstract public function url_access_token(); 146 | 147 | /* 148 | * Get an authorization code from Facebook. Redirects to Facebook, which this redirects back to the app using the redirect address you've set. 149 | */ 150 | public function authorize($options = array()) 151 | { 152 | $state = md5(uniqid(rand(), TRUE)); 153 | Session::put('state', $state); 154 | 155 | $url = $this->url_authorize().'?'.http_build_query(array( 156 | 'client_id' => $this->client_id, 157 | 'redirect_uri' => array_get($options, 'redirect_uri', $this->redirect_uri), 158 | 'state' => $state, 159 | 'scope' => is_array($this->scope) ? implode($this->scope_seperator, $this->scope) : $this->scope, 160 | 'response_type' => 'code', 161 | )); 162 | 163 | return Redirect::to($url); 164 | } 165 | 166 | /* 167 | * Get access to the API 168 | * 169 | * @param string The access code 170 | * @return object Success or failure along with the response details 171 | */ 172 | public function access($code, $options = array()) 173 | { 174 | $params = array( 175 | 'client_id' => $this->client_id, 176 | 'client_secret' => $this->client_secret, 177 | 'grant_type' => array_get($options, 'grant_type', 'authorization_code'), 178 | ); 179 | 180 | switch ($params['grant_type']) 181 | { 182 | case 'authorization_code': 183 | $params['code'] = $code; 184 | $params['redirect_uri'] = array_get($options, 'redirect_uri', $this->redirect_uri); 185 | break; 186 | 187 | case 'refresh_token': 188 | $params['refresh_token'] = $code; 189 | break; 190 | } 191 | 192 | $response = null; 193 | $url = $this->url_access_token(); 194 | 195 | $request = Request::make('access', $this->method, $url, $params); 196 | $response = $request->execute(); 197 | 198 | if (isset($response->error)) 199 | { 200 | throw new Exception($response); 201 | } 202 | 203 | return Token::make('access', $response->params); 204 | } 205 | } -------------------------------------------------------------------------------- /libraries/oauth2/request.php: -------------------------------------------------------------------------------- 1 | method = strtoupper($method); 71 | 72 | // Separate the URL and query string, which will be used as additional 73 | // default parameters 74 | list ($url, $default) = Core::parse_url($url); 75 | 76 | // Set the request URL 77 | $this->url = $url; 78 | 79 | // Set the default parameters 80 | if ($default) $this->params($default); 81 | 82 | // Set the request parameters 83 | if ($params) $this->params($params); 84 | } 85 | 86 | /** 87 | * Return the value of any protected class variable. 88 | * 89 | * // Get the request parameters 90 | * $params = $request->params; 91 | * 92 | * // Get the request URL 93 | * $url = $request->url; 94 | * 95 | * @param string variable name 96 | * @return mixed 97 | */ 98 | public function __get($key) 99 | { 100 | return $this->$key; 101 | } 102 | 103 | /** 104 | * Parameter getter and setter. Setting the value to `null` will remove it. 105 | * 106 | * @param string parameter name 107 | * @param mixed parameter value 108 | * @param boolean allow duplicates? 109 | * @return mixed when getting 110 | * @return $this when setting 111 | * @uses array_get 112 | */ 113 | public function param($name, $value = null, $duplicate = false) 114 | { 115 | if ($value === null) 116 | { 117 | // Get the parameter 118 | return array_get($this->params, $name); 119 | } 120 | 121 | if (isset($this->params[$name]) AND $duplicate) 122 | { 123 | if ( ! is_array($this->params[$name])) 124 | { 125 | // Convert the parameter into an array 126 | $this->params[$name] = array($this->params[$name]); 127 | } 128 | 129 | // Add the duplicate value 130 | $this->params[$name][] = $value; 131 | } 132 | else 133 | { 134 | // Set the parameter value 135 | $this->params[$name] = $value; 136 | } 137 | 138 | return $this; 139 | } 140 | 141 | /** 142 | * Set multiple parameters. 143 | * 144 | * $request->params($params); 145 | * 146 | * @param array parameters 147 | * @param boolean allow duplicates? 148 | * @return $this 149 | * @uses Request::param 150 | */ 151 | public function params(array $params, $duplicate = false) 152 | { 153 | foreach ($params as $name => $value) 154 | { 155 | $this->param($name, $value, $duplicate); 156 | } 157 | 158 | return $this; 159 | } 160 | 161 | /** 162 | * Convert the request parameters into a query string, suitable for GET and 163 | * POST requests. 164 | * 165 | * $query = $request->as_query(); 166 | * 167 | * @param boolean return a normalized string? 168 | * @return string 169 | */ 170 | public function as_query($as_string = true) 171 | { 172 | $params = $this->params; 173 | 174 | return $as_string ? Core::normalize_params($params) : $params; 175 | } 176 | 177 | /** 178 | * Return the entire request URL with the parameters as a GET string. 179 | * 180 | * $url = $request->as_url(); 181 | * 182 | * @return string 183 | * @uses Request::as_query 184 | */ 185 | public function as_url() 186 | { 187 | return $this->url.'?'.$this->as_query(true); 188 | } 189 | 190 | /** 191 | * Execute the request and return a response. 192 | * 193 | * @param array additional cURL options 194 | * @return string request response body 195 | * @uses array_get 196 | * @uses Core::remote 197 | */ 198 | public function execute(array $options = null) 199 | { 200 | // Get the URL of the request 201 | $url = $this->url; 202 | 203 | if ( ! isset($options[CURLOPT_CONNECTTIMEOUT])) 204 | { 205 | // Use the request default timeout 206 | $options[CURLOPT_CONNECTTIMEOUT] = $this->timeout; 207 | } 208 | 209 | if (\Request::env() === 'local') 210 | { 211 | $options[CURLOPT_SSL_VERIFYPEER] = false; 212 | } 213 | 214 | if (substr($this->method, 0, 4) === 'POST') 215 | { 216 | // Send the request as a POST 217 | $options[CURLOPT_POST] = true; 218 | $as_string = false; 219 | 220 | if ($this->method === 'POST_QUERY') 221 | { 222 | $as_string = true; 223 | } 224 | 225 | if ($post = $this->as_query($as_string)) 226 | { 227 | // Attach the post fields to the request 228 | $options[CURLOPT_POSTFIELDS] = $post; 229 | } 230 | } 231 | elseif (($query = $this->as_query())) 232 | { 233 | // Append the parameters to the query string 234 | $url = "{$url}?{$query}"; 235 | } 236 | 237 | $response = Core::remote($url, $options); 238 | 239 | // check if it's a json string 240 | if ($this->name === 'access' and strpos(trim($response), '{') === 0) $response = http_build_query(json_decode($response, true)); 241 | 242 | return $response; 243 | } 244 | } -------------------------------------------------------------------------------- /vendor/ca_chain_bundle.crt: -------------------------------------------------------------------------------- 1 | Verisign Class 3 Public Primary Certification Authority - G2 2 | ============================================================ 3 | -----BEGIN CERTIFICATE----- 4 | MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT 5 | MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy 6 | eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln 7 | biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz 8 | dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT 9 | MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy 10 | eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln 11 | biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz 12 | dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO 13 | FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 14 | lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB 15 | MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT 16 | 1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD 17 | Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 18 | -----END CERTIFICATE----- 19 | 20 | Thawte Premium Server CA 21 | ======================== 22 | -----BEGIN CERTIFICATE----- 23 | MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT 24 | DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs 25 | dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE 26 | AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl 27 | ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT 28 | AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU 29 | VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 30 | aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ 31 | cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 32 | aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh 33 | Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ 34 | qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm 35 | SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf 36 | 8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t 37 | UCemDaYj+bvLpgcUQg== 38 | -----END CERTIFICATE----- 39 | 40 | Equifax Secure Global eBusiness CA 41 | ================================== 42 | -----BEGIN CERTIFICATE----- 43 | MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT 44 | RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp 45 | bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx 46 | HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds 47 | b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV 48 | PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN 49 | qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn 50 | hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j 51 | BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs 52 | MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN 53 | I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY 54 | NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV 55 | -----END CERTIFICATE----- 56 | 57 | Equifax Secure eBusiness CA 1 58 | ============================= 59 | -----BEGIN CERTIFICATE----- 60 | MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT 61 | RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB 62 | LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE 63 | ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz 64 | IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ 65 | 1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a 66 | IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk 67 | MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW 68 | Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF 69 | AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 70 | lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ 71 | KpYrtWKmpj29f5JZzVoqgrI3eQ== 72 | -----END CERTIFICATE----- 73 | 74 | Equifax Secure eBusiness CA 2 75 | ============================= 76 | -----BEGIN CERTIFICATE----- 77 | MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE 78 | ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y 79 | MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT 80 | DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB 81 | nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn 82 | 2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 83 | BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG 84 | A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx 85 | JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG 86 | A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e 87 | uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB 88 | Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 89 | jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia 90 | 78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm 91 | V+GRMOrN 92 | -----END CERTIFICATE----- 93 | 94 | Equifax Secure CA 95 | ================= 96 | -----BEGIN CERTIFICATE----- 97 | MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE 98 | ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 99 | MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT 100 | B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB 101 | nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR 102 | fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW 103 | 8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG 104 | A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE 105 | CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG 106 | A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS 107 | spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB 108 | Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 109 | zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB 110 | BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 111 | 70+sB3c4 112 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /libraries/oauth/provider.php: -------------------------------------------------------------------------------- 1 | signature = $options['signature']; 95 | } 96 | 97 | if ( ! is_object($this->signature)) 98 | { 99 | // Convert the signature name into an object 100 | $this->signature = Signature::make($this->signature); 101 | } 102 | } 103 | 104 | /** 105 | * Return the value of any protected class variable. 106 | * 107 | * // Get the provider signature 108 | * $signature = $provider->signature; 109 | * 110 | * @param string variable name 111 | * @return mixed 112 | */ 113 | public function __get($key) 114 | { 115 | return $this->$key; 116 | } 117 | 118 | /** 119 | * Returns the request token URL for the provider. 120 | * 121 | * $url = $provider->url_request_token(); 122 | * 123 | * @return string 124 | */ 125 | abstract public function url_request_token(); 126 | 127 | /** 128 | * Returns the authorization URL for the provider. 129 | * 130 | * $url = $provider->url_authorize(); 131 | * 132 | * @return string 133 | */ 134 | abstract public function url_authorize(); 135 | 136 | /** 137 | * Returns the access token endpoint for the provider. 138 | * 139 | * $url = $provider->url_access_token(); 140 | * 141 | * @return string 142 | */ 143 | abstract public function url_access_token(); 144 | 145 | /** 146 | * Returns basic information about the user. 147 | * 148 | * $url = $provider->get_user_info(); 149 | * 150 | * @return string 151 | */ 152 | abstract public function get_user_info(Token $token, Consumer $consumer); 153 | 154 | /** 155 | * Ask for a request token from the OAuth provider. 156 | * 157 | * $token = $provider->request_token($consumer); 158 | * 159 | * @param Consumer consumer 160 | * @param array additional request parameters 161 | * @return Token_Request 162 | * @uses Request_Token 163 | */ 164 | public function request_token(Consumer $consumer, array $params = null) 165 | { 166 | // Create a new GET request for a request token with the required parameters 167 | $request = Request::make('token', 'GET', $this->url_request_token(), array( 168 | 'oauth_consumer_key' => $consumer->key, 169 | 'oauth_callback' => $consumer->callback, 170 | 'scope' => is_array($consumer->scope) ? implode($this->scope_seperator, $consumer->scope) : $consumer->scope, 171 | )); 172 | 173 | if ($params) 174 | { 175 | // Load user parameters 176 | $request->params($params); 177 | } 178 | 179 | // Sign the request using only the consumer, no token is available yet 180 | $request->sign($this->signature, $consumer); 181 | 182 | // Create a response from the request 183 | $response = $request->execute(); 184 | 185 | // Store this token somewhere useful 186 | return Token::make('request', array( 187 | 'access_token' => $response->param('oauth_token'), 188 | 'secret' => $response->param('oauth_token_secret'), 189 | )); 190 | } 191 | 192 | /** 193 | * Get the authorization URL for the request token. 194 | * 195 | * Response::redirect($provider->authorize_url($token)); 196 | * 197 | * @param Token_Request token 198 | * @param array additional request parameters 199 | * @return string 200 | */ 201 | public function authorize_url(Token\Request $token, array $params = null) 202 | { 203 | // Create a new GET request for a request token with the required parameters 204 | $request = Request::make('authorize', 'GET', $this->url_authorize(), array( 205 | 'oauth_token' => $token->access_token, 206 | )); 207 | 208 | if ($params) 209 | { 210 | // Load user parameters 211 | $request->params($params); 212 | } 213 | 214 | return $request->as_url(); 215 | } 216 | 217 | /** 218 | * Exchange the request token for an access token. 219 | * 220 | * $token = $provider->access_token($consumer, $token); 221 | * 222 | * @param Consumer consumer 223 | * @param Token_Request token 224 | * @param array additional request parameters 225 | * @return Token_Access 226 | */ 227 | public function access_token(Token\Request $token, Consumer $consumer, array $params = null) 228 | { 229 | // Create a new GET request for a request token with the required parameters 230 | $request = Request::make('access', 'GET', $this->url_access_token(), array( 231 | 'oauth_consumer_key' => $consumer->key, 232 | 'oauth_token' => $token->access_token, 233 | 'oauth_verifier' => $token->verifier, 234 | )); 235 | 236 | if ($params) 237 | { 238 | // Load user parameters 239 | $request->params($params); 240 | } 241 | 242 | // Sign the request using only the consumer, no token is available yet 243 | $request->sign($this->signature, $consumer, $token); 244 | 245 | // Create a response from the request 246 | $response = $request->execute(); 247 | 248 | // Store this token somewhere useful 249 | return Token::make('access', array( 250 | 'access_token' => $response->param('oauth_token'), 251 | 'secret' => $response->param('oauth_token_secret'), 252 | 'uid' => $response->param($this->uid_key) ?: Input::get($this->uid_key), 253 | )); 254 | } 255 | } -------------------------------------------------------------------------------- /libraries/oauth/core.php: -------------------------------------------------------------------------------- 1 | TRUE, 32 | * CURLOPT_POSTFIELDS => http_build_query($array), 33 | * )); 34 | * 35 | * @param string remote URL 36 | * @param array curl options 37 | * @return string 38 | * @throws Exception 39 | */ 40 | public static function remote($url, array $options = NULL) 41 | { 42 | // The transfer must always be returned 43 | $options[CURLOPT_RETURNTRANSFER] = TRUE; 44 | 45 | // Open a new remote connection 46 | $remote = curl_init($url); 47 | 48 | // Set connection options 49 | if ( ! curl_setopt_array($remote, $options)) 50 | { 51 | throw new Exception('Failed to set CURL options, check CURL documentation: http://php.net/curl_setopt_array'); 52 | } 53 | 54 | // Get the response 55 | $response = curl_exec($remote); 56 | 57 | if (curl_errno($remote) == 60) 58 | { 59 | curl_setopt($remote, CURLOPT_CAINFO, Bundle::path('oneauth').'vendor'.DS.'ca_chain_bundle.crt'); 60 | $response = curl_exec($remote); 61 | } 62 | 63 | // Get the response information 64 | $code = curl_getinfo($remote, CURLINFO_HTTP_CODE); 65 | 66 | if ($code AND ($code < 200 OR $code > 299)) 67 | { 68 | $error = $response; 69 | } 70 | elseif ($response === FALSE) 71 | { 72 | $error = curl_error($remote); 73 | } 74 | 75 | // Close the connection 76 | curl_close($remote); 77 | 78 | if (isset($error)) 79 | { 80 | throw new Exception(sprintf('Error fetching remote %s [ status %s ] %s', $url, $code, $error)); 81 | } 82 | 83 | return $response; 84 | } 85 | 86 | /** 87 | * RFC3986 compatible version of urlencode. Passing an array will encode 88 | * all of the values in the array. Array keys will not be encoded. 89 | * 90 | * $input = Core::urlencode($input); 91 | * 92 | * Multi-dimensional arrays are not allowed! 93 | * 94 | * [!!] This method implements [OAuth 1.0 Spec 5.1](http://oauth.net/core/1.0/#rfc.section.5.1). 95 | * 96 | * @param mixed input string or array 97 | * @return mixed 98 | */ 99 | public static function urlencode($input) 100 | { 101 | if (is_array($input)) 102 | { 103 | // Encode the values of the array 104 | return array_map(array(__NAMESPACE__.'\\Core', 'urlencode'), $input); 105 | } 106 | 107 | // Encode the input 108 | $input = rawurlencode($input); 109 | 110 | return $input; 111 | } 112 | 113 | /** 114 | * RFC3986 complaint version of urldecode. Passing an array will decode 115 | * all of the values in the array. Array keys will not be encoded. 116 | * 117 | * $input = Core::urldecode($input); 118 | * 119 | * Multi-dimensional arrays are not allowed! 120 | * 121 | * [!!] This method implements [OAuth 1.0 Spec 5.1](http://oauth.net/core/1.0/#rfc.section.5.1). 122 | * 123 | * @param mixed input string or array 124 | * @return mixed 125 | */ 126 | public static function urldecode($input) 127 | { 128 | if (is_array($input)) 129 | { 130 | // Decode the values of the array 131 | return array_map(array(__NAMESPACE__.'\\Core', 'urldecode'), $input); 132 | } 133 | 134 | // Decode the input 135 | return rawurldecode($input); 136 | } 137 | 138 | /** 139 | * Normalize all request parameters into a string. 140 | * 141 | * $query = Core::normalize_params($params); 142 | * 143 | * [!!] This method implements [OAuth 1.0 Spec 9.1.1](http://oauth.net/core/1.0/#rfc.section.9.1.1). 144 | * 145 | * @param array request parameters 146 | * @return string 147 | * @uses Core::urlencode 148 | */ 149 | public static function normalize_params(array $params = NULL) 150 | { 151 | if ( ! $params) 152 | { 153 | // Nothing to do 154 | return ''; 155 | } 156 | 157 | // Encode the parameter keys and values 158 | $keys = static::urlencode(array_keys($params)); 159 | $values = static::urlencode(array_values($params)); 160 | 161 | // Recombine the parameters 162 | $params = array_combine($keys, $values); 163 | 164 | // OAuth Spec 9.1.1 (1) 165 | // "Parameters are sorted by name, using lexicographical byte value ordering." 166 | uksort($params, 'strcmp'); 167 | 168 | // Create a new query string 169 | $query = array(); 170 | 171 | foreach ($params as $name => $value) 172 | { 173 | if (is_array($value)) 174 | { 175 | // OAuth Spec 9.1.1 (1) 176 | // "If two or more parameters share the same name, they are sorted by their value." 177 | $value = natsort($value); 178 | 179 | foreach ($value as $duplicate) 180 | { 181 | $query[] = $name.'='.$duplicate; 182 | } 183 | } 184 | else 185 | { 186 | $query[] = $name.'='.$value; 187 | } 188 | } 189 | 190 | return implode('&', $query); 191 | } 192 | 193 | /** 194 | * Parse the query string out of the URL and return it as parameters. 195 | * All GET parameters must be removed from the request URL when building 196 | * the base string and added to the request parameters. 197 | * 198 | * // parsed parameters: array('oauth_key' => 'abcdef123456789') 199 | * list($url, $params) = Core::parse_url('http://example.com/oauth/access?oauth_key=abcdef123456789'); 200 | * 201 | * [!!] This implements [OAuth Spec 9.1.1](http://oauth.net/core/1.0/#rfc.section.9.1.1). 202 | * 203 | * @param string URL to parse 204 | * @return array (clean_url, params) 205 | * @uses Core::parse_params 206 | */ 207 | public static function parse_url($url) 208 | { 209 | if ($query = parse_url($url, PHP_URL_QUERY)) 210 | { 211 | // Remove the query string from the URL 212 | list($url) = explode('?', $url, 2); 213 | 214 | // Parse the query string as request parameters 215 | $params = static::parse_params($query); 216 | } 217 | else 218 | { 219 | // No parameters are present 220 | $params = array(); 221 | } 222 | 223 | return array($url, $params); 224 | } 225 | 226 | /** 227 | * Parse the parameters in a string and return an array. Duplicates are 228 | * converted into indexed arrays. 229 | * 230 | * // Parsed: array('a' => '1', 'b' => '2', 'c' => '3') 231 | * $params = Core::parse_params('a=1,b=2,c=3'); 232 | * 233 | * // Parsed: array('a' => array('1', '2'), 'c' => '3') 234 | * $params = Core::parse_params('a=1,a=2,c=3'); 235 | * 236 | * @param string parameter string 237 | * @return array 238 | */ 239 | public static function parse_params($params) 240 | { 241 | // Split the parameters by & 242 | $params = explode('&', trim($params)); 243 | 244 | // Create an array of parsed parameters 245 | $parsed = array(); 246 | 247 | foreach ($params as $param) 248 | { 249 | // Split the parameter into name and value 250 | list($name, $value) = explode('=', $param, 2); 251 | 252 | // Decode the name and value 253 | $name = static::urldecode($name); 254 | $value = static::urldecode($value); 255 | 256 | if (isset($parsed[$name])) 257 | { 258 | if ( ! is_array($parsed[$name])) 259 | { 260 | // Convert the parameter to an array 261 | $parsed[$name] = array($parsed[$name]); 262 | } 263 | 264 | // Add a new duplicate parameter 265 | $parsed[$name][] = $value; 266 | } 267 | else 268 | { 269 | // Add a new parameter 270 | $parsed[$name] = $value; 271 | } 272 | } 273 | 274 | return $parsed; 275 | } 276 | } -------------------------------------------------------------------------------- /libraries/oauth/request.php: -------------------------------------------------------------------------------- 1 | method = strtoupper($method); 102 | 103 | // Separate the URL and query string, which will be used as additional 104 | // default parameters 105 | list ($url, $default) = Core::parse_url($url); 106 | 107 | // Set the request URL 108 | $this->url = $url; 109 | 110 | // Set the default parameters 111 | if ($default) $this->params($default); 112 | 113 | // Set the request parameters 114 | if ($params) $this->params($params); 115 | 116 | // Set the version of this request 117 | if ($this->required('oauth_version') and ! isset($this->params['oauth_version'])) 118 | { 119 | $this->params['oauth_version'] = Core::$version; 120 | } 121 | 122 | // Set the timestamp of this request 123 | if ($this->required('oauth_timestamp') and ! isset($this->params['oauth_timestamp'])) 124 | { 125 | $this->params['oauth_timestamp'] = $this->timestamp(); 126 | } 127 | 128 | // Set the unique nonce of this request 129 | if ($this->required('oauth_nonce') and ! isset($this->params['oauth_nonce'])) 130 | { 131 | $this->params['oauth_nonce'] = $this->nonce(); 132 | } 133 | } 134 | 135 | /** 136 | * Return the value of any protected class variable. 137 | * 138 | * // Get the request parameters 139 | * $params = $request->params; 140 | * 141 | * // Get the request URL 142 | * $url = $request->url; 143 | * 144 | * @param string variable name 145 | * @return mixed 146 | */ 147 | public function __get($key) 148 | { 149 | return $this->$key; 150 | } 151 | 152 | /** 153 | * Generates the UNIX timestamp for a request. 154 | * 155 | * $time = $request->timestamp(); 156 | * 157 | * [!!] This method implements [OAuth 1.0 Spec 8](http://oauth.net/core/1.0/#rfc.section.8). 158 | * 159 | * @return integer 160 | */ 161 | public function timestamp() 162 | { 163 | return time(); 164 | } 165 | 166 | /** 167 | * Generates the nonce for a request. 168 | * 169 | * $nonce = $request->nonce(); 170 | * 171 | * [!!] This method implements [OAuth 1.0 Spec 8](http://oauth.net/core/1.0/#rfc.section.8). 172 | * 173 | * @return string 174 | * @uses Str::random 175 | */ 176 | public function nonce() 177 | { 178 | return Str::random(40, 'alnum'); 179 | } 180 | 181 | /** 182 | * Get the base signature string for a request. 183 | * 184 | * $base = $request->base_string(); 185 | * 186 | * [!!] This method implements [OAuth 1.0 Spec A5.1](http://oauth.net/core/1.0/#rfc.section.A.5.1). 187 | * 188 | * @param Request request to sign 189 | * @return string 190 | * @uses Core::urlencode 191 | * @uses Core::normalize_params 192 | */ 193 | public function base_string() 194 | { 195 | $url = $this->url; 196 | 197 | // Get the request parameters 198 | $params = array_diff_key($this->params, $this->upload); 199 | 200 | // "oauth_signature" is never included in the base string! 201 | unset($params['oauth_signature']); 202 | 203 | // method & url & sorted-parameters 204 | return implode('&', array( 205 | $this->method, 206 | Core::urlencode($url), 207 | Core::urlencode(Core::normalize_params($params)), 208 | )); 209 | } 210 | 211 | /** 212 | * Parameter getter and setter. Setting the value to `null` will remove it. 213 | * 214 | * // Set the "oauth_consumer_key" to a new value 215 | * $request->param('oauth_consumer_key', $key); 216 | * 217 | * // Get the "oauth_consumer_key" value 218 | * $key = $request->param('oauth_consumer_key'); 219 | * 220 | * @param string parameter name 221 | * @param mixed parameter value 222 | * @param boolean allow duplicates? 223 | * @return mixed when getting 224 | * @return $this when setting 225 | * @uses array_get 226 | */ 227 | public function param($name, $value = null, $duplicate = false) 228 | { 229 | if ($value === null) 230 | { 231 | // Get the parameter 232 | return array_get($this->params, $name); 233 | } 234 | 235 | if (isset($this->params[$name]) AND $duplicate) 236 | { 237 | if ( ! is_array($this->params[$name])) 238 | { 239 | // Convert the parameter into an array 240 | $this->params[$name] = array($this->params[$name]); 241 | } 242 | 243 | // Add the duplicate value 244 | $this->params[$name][] = $value; 245 | } 246 | else 247 | { 248 | // Set the parameter value 249 | $this->params[$name] = $value; 250 | } 251 | 252 | return $this; 253 | } 254 | 255 | /** 256 | * Set multiple parameters. 257 | * 258 | * $request->params($params); 259 | * 260 | * @param array parameters 261 | * @param boolean allow duplicates? 262 | * @return $this 263 | * @uses Request::param 264 | */ 265 | public function params(array $params, $duplicate = false) 266 | { 267 | foreach ($params as $name => $value) 268 | { 269 | $this->param($name, $value, $duplicate); 270 | } 271 | 272 | return $this; 273 | } 274 | 275 | /** 276 | * Upload getter and setter. Setting the value to `null` will remove it. 277 | * 278 | * // Set the "image" file path for uploading 279 | * $request->upload('image', $file_path); 280 | * 281 | * // Get the "image" file path 282 | * $key = $request->param('oauth_consumer_key'); 283 | * 284 | * @param string upload name 285 | * @param mixed upload file path 286 | * @return mixed when getting 287 | * @return $this when setting 288 | * @uses Request::param 289 | */ 290 | public function upload($name, $value = null) 291 | { 292 | if ($value !== null) 293 | { 294 | // This is an upload parameter 295 | $this->upload[$name] = true; 296 | 297 | // Get the mime type of the image 298 | $mime = File::mime($value); 299 | 300 | // Format the image path for CURL 301 | $value = "@{$value};type={$mime}"; 302 | } 303 | 304 | return $this->param($name, $value, false); 305 | } 306 | 307 | /** 308 | * Get and set required parameters. 309 | * 310 | * $request->required($field, $value); 311 | * 312 | * @param string parameter name 313 | * @param boolean field value 314 | * @return boolean when getting 315 | * @return $this when setting 316 | */ 317 | public function required($param, $value = null) 318 | { 319 | // Get the current status 320 | if ($value === null) return ! empty($this->required[$param]); 321 | 322 | // Change the requirement value 323 | $this->required[$param] = (boolean) $value; 324 | 325 | return $this; 326 | } 327 | 328 | /** 329 | * Convert the request parameters into an `Authorization` header. 330 | * 331 | * $header = $request->as_header(); 332 | * 333 | * [!!] This method implements [OAuth 1.0 Spec 5.4.1](http://oauth.net/core/1.0/#rfc.section.5.4.1). 334 | * 335 | * @return string 336 | */ 337 | public function as_header() 338 | { 339 | $header = array(); 340 | 341 | foreach ($this->params as $name => $value) 342 | { 343 | if (strpos($name, 'oauth_') === 0) 344 | { 345 | // OAuth Spec 5.4.1 346 | // "Parameter names and values are encoded per Parameter Encoding [RFC 3986]." 347 | $header[] = Core::urlencode($name).'="'.Core::urlencode($value).'"'; 348 | } 349 | } 350 | 351 | return 'OAuth '.implode(', ', $header); 352 | } 353 | 354 | /** 355 | * Convert the request parameters into a query string, suitable for GET and 356 | * POST requests. 357 | * 358 | * $query = $request->as_query(); 359 | * 360 | * [!!] This method implements [OAuth 1.0 Spec 5.2 (2,3)](http://oauth.net/core/1.0/#rfc.section.5.2). 361 | * 362 | * @param boolean include oauth parameters? 363 | * @param boolean return a normalized string? 364 | * @return string 365 | */ 366 | public function as_query($include_oauth = null, $as_string = true) 367 | { 368 | if ($include_oauth === null) 369 | { 370 | // If we are sending a header, OAuth parameters should not be 371 | // included in the query string. 372 | $include_oauth = ! $this->send_header; 373 | } 374 | 375 | if ($include_oauth) 376 | { 377 | $params = $this->params; 378 | } 379 | else 380 | { 381 | $params = array(); 382 | foreach ($this->params as $name => $value) 383 | { 384 | if (strpos($name, 'oauth_') !== 0) 385 | { 386 | // This is not an OAuth parameter 387 | $params[$name] = $value; 388 | } 389 | } 390 | } 391 | 392 | return $as_string ? Core::normalize_params($params) : $params; 393 | } 394 | 395 | /** 396 | * Return the entire request URL with the parameters as a GET string. 397 | * 398 | * $url = $request->as_url(); 399 | * 400 | * @return string 401 | * @uses Request::as_query 402 | */ 403 | public function as_url() 404 | { 405 | return $this->url.'?'.$this->as_query(true); 406 | } 407 | 408 | /** 409 | * Sign the request, setting the `oauth_signature_method` and `oauth_signature`. 410 | * 411 | * @param Signature signature 412 | * @param Consumer consumer 413 | * @param Token token 414 | * @return $this 415 | * @uses Signature::sign 416 | */ 417 | public function sign(Signature $signature, Consumer $consumer, Token $token = null) 418 | { 419 | // Create a new signature class from the method 420 | $this->param('oauth_signature_method', $signature->name); 421 | 422 | // Sign the request using the consumer and token 423 | $this->param('oauth_signature', $signature->sign($this, $consumer, $token)); 424 | 425 | return $this; 426 | } 427 | 428 | /** 429 | * Checks that all required request parameters have been set. Throws an 430 | * exception if any parameters are missing. 431 | * 432 | * try 433 | * { 434 | * $request->check(); 435 | * } 436 | * catch (Exception $e) 437 | * { 438 | * // Request has missing parameters 439 | * } 440 | * 441 | * @return true 442 | * @throws Exception 443 | */ 444 | public function check() 445 | { 446 | foreach ($this->required as $param => $required) 447 | { 448 | if ($required AND ! isset($this->params[$param])) 449 | { 450 | throw new Exception(sprintf('Request to %s requires missing parameter "%s"', $this->url, $param)); 451 | } 452 | } 453 | 454 | return true; 455 | } 456 | 457 | /** 458 | * Execute the request and return a response. 459 | * 460 | * @param array additional cURL options 461 | * @return string request response body 462 | * @uses array_get 463 | * @uses Core::remote 464 | */ 465 | public function execute(array $options = null) 466 | { 467 | // Check that all required fields are set 468 | $this->check(); 469 | 470 | // Get the URL of the request 471 | $url = $this->url; 472 | 473 | if ( ! isset($options[CURLOPT_CONNECTTIMEOUT])) 474 | { 475 | // Use the request default timeout 476 | $options[CURLOPT_CONNECTTIMEOUT] = $this->timeout; 477 | } 478 | 479 | if (\Request::env() === 'local') 480 | { 481 | $options[CURLOPT_SSL_VERIFYPEER] = false; 482 | } 483 | 484 | if ($this->send_header) 485 | { 486 | // Get the the current headers 487 | $headers = array_get($options, CURLOPT_HTTPHEADER, array()); 488 | 489 | // Add the Authorization header 490 | $headers[] = 'Authorization: '.$this->as_header(); 491 | 492 | // Store the new headers 493 | $options[CURLOPT_HTTPHEADER] = $headers; 494 | } 495 | 496 | if ($this->method === 'POST') 497 | { 498 | // Send the request as a POST 499 | $options[CURLOPT_POST] = true; 500 | 501 | if ($post = $this->as_query(null, empty($this->upload))) 502 | { 503 | // Attach the post fields to the request 504 | $options[CURLOPT_POSTFIELDS] = $post; 505 | } 506 | } 507 | elseif (($query = $this->as_query())) 508 | { 509 | // Append the parameters to the query string 510 | $url = "{$url}?{$query}"; 511 | } 512 | 513 | return Core::remote($url, $options); 514 | } 515 | } --------------------------------------------------------------------------------