Skip to content

Commit f3a333b

Browse files
author
Phil Sturgeon
committed
Upgraded from recent fuel-oauth2 improvements.
1 parent 39ee5aa commit f3a333b

7 files changed

+301
-57
lines changed

libraries/OAuth2.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
include('OAuth2_Exception.php');
4-
include('OAuth2_Client.php');
4+
include('OAuth2_Token.php');
55
include('OAuth2_Provider.php');
66

77
/**

libraries/OAuth2_Client.php

-15
This file was deleted.

libraries/OAuth2_Provider.php

+108-35
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@
1111

1212
abstract class OAuth2_Provider {
1313

14+
/**
15+
* Create a new provider.
16+
*
17+
* // Load the Twitter provider
18+
* $provider = OAuth2_Provider::forge('twitter');
19+
*
20+
* @param string provider name
21+
* @param array provider options
22+
* @return OAuth_Provider
23+
*/
24+
public static function factory($name, array $options = null)
25+
{
26+
$class = 'OAuth2_Provider_'.ucfirst($name);
27+
return new $class($options);
28+
}
29+
1430
/**
1531
* @var string provider name
1632
*/
@@ -21,11 +37,26 @@ abstract class OAuth2_Provider {
2137
*/
2238
public $uid_key = 'uid';
2339

40+
/**
41+
* @var string scope separator, most use "," but some like Google are spaces
42+
*/
43+
public $scope_seperator = ',';
44+
45+
/**
46+
* @var string additional request parameters to be used for remote requests
47+
*/
48+
public $callback = null;
49+
2450
/**
2551
* @var array additional request parameters to be used for remote requests
2652
*/
2753
protected $params = array();
2854

55+
/**
56+
* @var string the method to use when requesting tokens
57+
*/
58+
protected $method = 'GET';
59+
2960
/**
3061
* Overloads default class properties from the options.
3162
*
@@ -34,21 +65,26 @@ abstract class OAuth2_Provider {
3465
* @param array provider options
3566
* @return void
3667
*/
37-
public function __construct(array $options = NULL)
68+
public function __construct(array $options = array())
3869
{
3970
if ( ! $this->name)
4071
{
4172
// Attempt to guess the name from the class name
4273
$this->name = strtolower(substr(get_class($this), strlen('OAuth2_Provider_')));
4374
}
44-
45-
foreach ($options as $key => $val)
75+
76+
if (empty($options['id']))
4677
{
47-
$this->{$key} = $val;
78+
throw new Exception('Required option not provided: id');
4879
}
80+
81+
$this->client_id = $options['id'];
4982

50-
// Set a default, which will be used if none are provided pre-request
51-
$this->redirect_uri = get_instance()->config->site_url(get_instance()->uri->uri_string());
83+
isset($options['callback']) and $this->callback = $options['callback'];
84+
isset($options['secret']) and $this->client_secret = $options['secret'];
85+
isset($options['scope']) and $this->scope = $options['scope'];
86+
87+
$this->redirect_uri = site_url(get_instance()->uri->uri_string());
5288
}
5389

5490
/**
@@ -90,17 +126,15 @@ public function authorize($options = array())
90126
{
91127
$state = md5(uniqid(rand(), TRUE));
92128
get_instance()->session->set_userdata('state', $state);
93-
94-
$params = array(
95-
'client_id' => $this->client_id,
96-
'redirect_uri' => isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri,
97-
'state' => $state,
98-
'scope' => $this->scope,
99-
'response_type' => 'code', # required for Windows Live
100-
);
101-
102-
$url = $this->url_authorize().'?'.http_build_query($params);
103-
129+
130+
$url = $this->url_authorize().'?'.http_build_query(array(
131+
'client_id' => $this->client_id,
132+
'redirect_uri' => isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri,
133+
'state' => $state,
134+
'scope' => is_array($this->scope) ? implode($this->scope_seperator, $this->scope) : $this->scope,
135+
'response_type' => 'code',
136+
));
137+
104138
redirect($url);
105139
}
106140

@@ -110,39 +144,78 @@ public function authorize($options = array())
110144
* @param string The access code
111145
* @return object Success or failure along with the response details
112146
*/
113-
public function access($code)
147+
public function access($code, $options = array())
114148
{
115149
$params = array(
116-
'client_id' => $this->client_id,
117-
'redirect_uri' => isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri,
150+
'client_id' => $this->client_id,
118151
'client_secret' => $this->client_secret,
119-
'code' => $code,
120-
'grant_type' => 'authorization_code', # required for Windows Live
152+
'grant_type' => isset($options['grant_type']) ? $options['grant_type'] : 'authorization_code',
121153
);
122-
123-
$url = $this->url_access_token().'?'.http_build_query($params);
124-
125-
$response = file_get_contents($url);
126154

127-
$params = null;
155+
switch ($params['grant_type'])
156+
{
157+
case 'authorization_code':
158+
$params['code'] = $code;
159+
$params['redirect_uri'] = isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri;
160+
break;
161+
162+
case 'refresh_token':
163+
$params['refresh_token'] = $code;
164+
break;
165+
}
166+
167+
$response = null;
168+
$url = $this->url_access_token();
128169

129-
// TODO: This could be moved to a provider method to reduce provider specific awareness
130-
switch($this->name)
170+
switch ($this->method)
131171
{
132-
case 'windowslive':
133-
$params = json_decode($response, true);
172+
case 'GET':
173+
174+
// Need to switch to Request library, but need to test it on one that works
175+
$url .= '?'.http_build_query($params);
176+
$response = file_get_contents($url);
177+
178+
parse_str($response, $return);
179+
180+
break;
181+
182+
case 'POST':
183+
184+
$postdata = http_build_query($params);
185+
$opts = array(
186+
'http' => array(
187+
'method' => 'POST',
188+
'header' => 'Content-type: application/x-www-form-urlencoded',
189+
'content' => $postdata
190+
)
191+
);
192+
$context = stream_context_create($opts);
193+
$response = file_get_contents($url, false, $context);
194+
195+
$return = get_object_vars(json_decode($response));
196+
134197
break;
135198

136199
default:
137-
parse_str($response, $params);
200+
throw new OutOfBoundsException("Method '{$this->method}' must be either GET or POST");
138201
}
139202

140-
if (isset($params['error']))
203+
if (isset($return['error']))
141204
{
142-
throw new OAuth2_Exception($params);
205+
throw new OAuth2_Exception($return);
206+
}
207+
208+
switch ($params['grant_type'])
209+
{
210+
case 'authorization_code':
211+
return OAuth2_Token::factory('access', $return);
212+
break;
213+
214+
case 'refresh_token':
215+
return OAuth2_Token::factory('refresh', $return);
216+
break;
143217
}
144218

145-
return $params;
146219
}
147220

148221
}

libraries/OAuth2_Token.php

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* OAuth2 Token
4+
*
5+
* @package OAuth2
6+
* @category Token
7+
* @author Phil Sturgeon
8+
* @copyright (c) 2011 HappyNinjas Ltd
9+
*/
10+
11+
abstract class OAuth2_Token {
12+
13+
/**
14+
* Create a new token object.
15+
*
16+
* $token = OAuth2_Token::forge($name);
17+
*
18+
* @param string token type
19+
* @param array token options
20+
* @return Token
21+
*/
22+
public static function factory($type = 'access', array $options = null)
23+
{
24+
$class = 'OAuth2_Token_'.ucfirst($type);
25+
26+
include $class.'.php';
27+
28+
return new $class($options);
29+
}
30+
31+
/**
32+
* Return the value of any protected class variable.
33+
*
34+
* // Get the token secret
35+
* $secret = $token->secret;
36+
*
37+
* @param string variable name
38+
* @return mixed
39+
*/
40+
public function __get($key)
41+
{
42+
return $this->$key;
43+
}
44+
45+
/**
46+
* Return a boolean if the property is set
47+
*
48+
* // Get the token secret
49+
* if ($token->secret) exit('YAY SECRET');
50+
*
51+
* @param string variable name
52+
* @return bool
53+
*/
54+
public function __isset($key)
55+
{
56+
return isset($this->$key);
57+
}
58+
59+
} // End Token

libraries/OAuth2_Token_Access.php

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* OAuth2 Token
4+
*
5+
* @package OAuth2
6+
* @category Token
7+
* @author Phil Sturgeon
8+
* @copyright (c) 2011 HappyNinjas Ltd
9+
*/
10+
11+
class OAuth2_Token_Access extends OAuth2_Token
12+
{
13+
/**
14+
* @var string access_token
15+
*/
16+
protected $access_token;
17+
18+
/**
19+
* @var int expires
20+
*/
21+
protected $expires;
22+
23+
/**
24+
* @var string refresh_token
25+
*/
26+
protected $refresh_token;
27+
28+
/**
29+
* @var string uid
30+
*/
31+
protected $uid;
32+
33+
/**
34+
* Sets the token, expiry, etc values.
35+
*
36+
* @param array token options
37+
* @return void
38+
*/
39+
public function __construct(array $options)
40+
{
41+
if ( ! isset($options['access_token']))
42+
{
43+
throw new Exception('Required option not passed: access_token'.PHP_EOL.print_r($options, true));
44+
}
45+
46+
// if ( ! isset($options['expires_in']) and ! isset($options['expires']))
47+
// {
48+
// throw new Exception('We do not know when this access_token will expire');
49+
// }
50+
51+
$this->access_token = $options['access_token'];
52+
53+
// Some providers (not many) give the uid here, so lets take it
54+
isset($options['uid']) and $this->uid = $options['uid'];
55+
56+
// We need to know when the token expires, add num. seconds to current time
57+
isset($options['expires_in']) and $this->expires = time() + ((int) $options['expires_in']);
58+
59+
// Facebook is just being a spec ignoring jerk
60+
isset($options['expires']) and $this->expires = time() + ((int) $options['expires']);
61+
62+
// Grab a refresh token so we can update access tokens when they expires
63+
isset($options['refresh_token']) and $this->refresh_token = $options['refresh_token'];
64+
}
65+
66+
/**
67+
* Returns the token key.
68+
*
69+
* @return string
70+
*/
71+
public function __toString()
72+
{
73+
return (string) $this->access_token;
74+
}
75+
76+
} // End OAuth2_Token_Access

0 commit comments

Comments
 (0)