Skip to content

Commit

Permalink
Added support for refresh tokens.
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Sturgeon committed Nov 21, 2011
1 parent 51c1c00 commit 0d87fc0
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 58 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,31 @@ NinjAuth comes from the company behind the project: [HappyNinjas](http://happyni

## Usage Example

### Controller

http://example.com/auth/session/facebook

```php
class Controller_Auth extends \NinjAuth\Controller {}
```
```

### Configuration

'somewhere' => array(
'id' => '9cd980e0d883ERG42974b6cd78175135',
'secret' => '19d874DW43534SDFfce025d9bba4423452',
// Specify a specific callback
'callback' => 'http://example.com/foo/bar',
),

'google' => array(
'key' => 'yourkey',
'secret' => 'yoursecret',
// Provide a string or array for the API scope
'scope' => array('https://www.google.com/analytics/feeds', 'https://www.google.com/m8/feeds'),
// Google supports OAuth and OAuth2. Pick a specific
'strategy' => 'OAuth',
),
1 change: 0 additions & 1 deletion bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*
* @package Fuel
* @version 1.0
* @OAuthor Fuel Development Team
* @license MIT License
* @copyright 2010 - 2011 Fuel Development Team
* @link http://fuelphp.com
Expand Down
4 changes: 2 additions & 2 deletions classes/controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ public function before()

public function action_session($provider)
{
Strategy::factory($provider)->authenticate();
Strategy::forge($provider)->authenticate();
}

public function action_callback($provider)
{
$strategy = Strategy::factory($provider);
$strategy = Strategy::forge($provider);

Strategy::login_or_register($strategy);
}
Expand Down
14 changes: 13 additions & 1 deletion classes/model/authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

class Model_Authentication extends \Orm\Model {

protected static $_properties = array('id', 'user_id', 'provider', 'uid', 'token', 'secret', 'created_at', 'updated_at');
public static $_properties = array(
'id', 'provider', 'uid', 'access_token', 'secret', 'expires', 'refresh_token', 'user_id', 'created_at', 'updated_at'
);

protected static $_observers = array(
'Orm\Observer_CreatedAt' => array(
'events' => array('before_insert'),
'mysql_timestamp' => false,
),
'Orm\Observer_UpdatedAt' => array(
'events' => array('before_save'),
'mysql_timestamp' => false,
),
);
}
44 changes: 28 additions & 16 deletions classes/strategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

abstract class Strategy {

/**
* @var string Strategy name
*/
public $name;

protected static $providers = array(
Expand All @@ -15,7 +18,7 @@ abstract class Strategy {
'github' => 'OAuth2',
'linkedin' => 'OAuth',
'unmagnify' => 'OAuth2',
'youtube' => 'OAuth',
'youtube' => 'OAuth2',
'openid' => 'OpenId',
);

Expand All @@ -32,7 +35,7 @@ public function __construct($provider)
}
}

public static function factory($provider)
public static function forge($provider)
{
// If a strategy has been specified use it, otherwise look it up
$strategy = \Config::get("ninjauth.providers.{$provider}.strategy") ?: \Arr::get(static::$providers, $provider);
Expand All @@ -43,16 +46,17 @@ public static function factory($provider)
}

$class = "NinjAuth\\Strategy_{$strategy}";

return new $class($provider);
}

public static function login_or_register($strategy)
{
$response = $strategy->callback();
$token = $strategy->callback();

if (\Auth::check())
{
$user_id = end(\Auth::instance()->get_user_id());
list($driver, $user_id) = \Auth::instance()->get_user_id();

$num_linked = Model_Authentication::count_by_user_id($user_id);

Expand All @@ -62,26 +66,34 @@ public static function login_or_register($strategy)
switch ($strategy->name)
{
case 'oauth':
$user_hash = $strategy->provider->get_user_info($strategy->consumer, $response);
$user_hash = $strategy->provider->get_user_info($strategy->consumer, $token);
break;

case 'oauth2':
$user_hash = $strategy->provider->get_user_info($response->token);
$user_hash = $strategy->provider->get_user_info($token);
break;

case 'openid':
$user_hash = $strategy->get_user_info($response);
$user_hash = $strategy->get_user_info($token);
break;
}

// If there is no uid we can't remember who this is
if ( ! isset($user_hash['uid']))
{
throw new Exception('No uid in response.');
}

// Attach this account to the logged in user
Model_Authentication::forge(array(
'user_id' => $user_id,
'provider' => $user_hash['credentials']['provider'],
'uid' => $user_hash['credentials']['uid'],
'token' => $user_hash['credentials']['token'],
'secret' => $user_hash['credentials']['secret'],
'created_at' => time(),
'user_id' => $user_id,
'provider' => $provider->name,
'uid' => $user_hash['uid'],
'access_token' => isset($token->access_token) ? $token->access_token : null,
'secret' => isset($token->secret) ? $token->secret : null,
'expires' => isset($token->expires) ? $token->expires : null,
'refresh_token' => isset($token->refresh_token) ? $token->refresh_token : null,
'created_at' => time(),
))->save();

// Attachment went ok so we'll redirect
Expand All @@ -96,7 +108,7 @@ public static function login_or_register($strategy)
}

// The user exists, so send him on his merry way as a user
else if ($authentication = Model_Authentication::find_by_token_and_secret($response->token, $response->secret))
else if ($authentication = Model_Authentication::find_by_uid($response->uid))
{
// Force a login with this username
if (\Auth::instance()->force_login($authentication->user_id))
Expand All @@ -116,15 +128,15 @@ public static function login_or_register($strategy)
break;

case 'oauth2':
$user_hash = $strategy->provider->get_user_info($response->token);
$user_hash = $strategy->provider->get_user_info($response);
break;

case 'openid':
$user_hash = $strategy->get_user_info($response);
break;

default:
exit('Ummm....');
throw new Exception("Unsupported Strategy: {$strategy->name}");
}

\Session::set('ninjauth', $user_hash);
Expand Down
10 changes: 5 additions & 5 deletions classes/strategy/oauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ class Strategy_OAuth extends Strategy {
public function authenticate()
{
// Create an consumer from the config
$consumer = \OAuth\Consumer::factory($this->config);
$consumer = \OAuth\Consumer::forge($this->config);

// Load the provider
$provider = \OAuth\Provider::factory($this->provider);
$provider = \OAuth\Provider::forge($this->provider);

// Create the URL to return the user to
$callback = \Uri::create(\Config::get('ninjauth.urls.callback', \Request::active()->route->segments[0].'/callback').'/'.$this->provider);
$callback = \Arr::get($this->config, 'callback') ?: \Uri::create(\Config::get('ninjauth.urls.callback', \Request::active()->route->segments[0].'/callback/'.$this->provider));

// Add the callback URL to the consumer
$consumer->callback($callback);
Expand All @@ -36,10 +36,10 @@ public function authenticate()
public function callback()
{
// Create an consumer from the config
$this->consumer = \OAuth\Consumer::factory($this->config);
$this->consumer = \OAuth\Consumer::forge($this->config);

// Load the provider
$this->provider = \OAuth\Provider::factory($this->provider);
$this->provider = \OAuth\Provider::forge($this->provider);

if ($token = \Cookie::get('oauth_token'))
{
Expand Down
19 changes: 3 additions & 16 deletions classes/strategy/oauth2.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Strategy_OAuth2 extends Strategy {
public function authenticate()
{
// Load the provider
$provider = \OAuth2\Provider::factory($this->provider, $this->config);
$provider = \OAuth2\Provider::forge($this->provider, $this->config);

// Grab a callback from the config
if ($provider->callback === null)
Expand All @@ -25,22 +25,9 @@ public function authenticate()
public function callback()
{
// Load the provider
$this->provider = \OAuth2\Provider::factory($this->provider, $this->config);
$this->provider = \OAuth2\Provider::forge($this->provider, $this->config);

try
{
$params = $this->provider->access(\Input::get('code'));

return (object) array(
'token' => $params['access_token'],
'secret' => null,
);
}

catch (Exception $e)
{
exit('That didnt work: '.$e);
}
return $this->provider->access(\Input::get('code'));
}

}
25 changes: 9 additions & 16 deletions classes/strategy/openid.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function __construct($provider)
public function authenticate()
{
$identity = \Input::post(\Config::get('ninjauth.providers.openid.identifier_form_name'));
if(empty($identity))
if (empty($identity))
{
throw new Exception('No identity provided');
}
Expand Down Expand Up @@ -61,7 +61,7 @@ public function authenticate()
*/
public function callback()
{
if($this->openid->mode == 'cancel')
if ($this->openid->mode == 'cancel')
{
throw new CancelException('User canceled the process');
}
Expand All @@ -71,8 +71,7 @@ public function callback()
}

return (object) array(
'token' => $this->openid->identity,
'secret' => '', // otherwise the database complains about a null value
'access_token' => $this->openid->identity,
);
}

Expand All @@ -94,14 +93,14 @@ public function callback()
private function get_data($map, $data)
{
$r = '';
if(is_array($map))
if (is_array($map))
{
foreach($map as $m)
foreach ($map as $m)
{
$r .= $this->get_data($m, $data);
}
}
else if(array_key_exists($map, $data))
else if (array_key_exists($map, $data))
{
$r = $data[$map];
}
Expand All @@ -114,17 +113,11 @@ private function get_data($map, $data)
*/
public function get_user_info($response)
{
$ret = array(
'credentials' => array(
'uid' => $this->openid->identity,
'provider' => $this->name,
'token' => $response->token,
'secret' => $response->secret,
),
);
$ret['uid'] = $this->openid->identity;

$data = $this->openid->getAttributes();
foreach(static::$mapping as $name => $map)

foreach (static::$mapping as $name => $map)
{
$ret[$name] = $this->get_data($map, $data);
}
Expand Down
26 changes: 26 additions & 0 deletions migrations/002_add_refresh_tokens.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Fuel\Migrations;

class Add_refresh_tokens {

public function up()
{
\DBUtil::add_fields('authentications', array(
'access_token' => array('constraint' => 255, 'type' => 'varchar', 'null' => true),
'expires' => array('constraint' => 12, 'type' => 'int', 'default' => 0, 'null' => true),
'refresh_token' => array('constraint' => 255, 'type' => 'varchar', 'null' => true),
));

\DBUtil::drop_fields('authentications', array('token'));
}

public function down()
{
\DBUtil::add_fields('authentications', array(
'token' => array('constraint' => 255, 'type' => 'varchar', 'null' => true),
));

\DBUtil::drop_fields('authentications', array('access_token', 'expires', 'refresh_token'));
}
}

0 comments on commit 0d87fc0

Please sign in to comment.