Skip to content

Commit

Permalink
Bug fix and clean up
Browse files Browse the repository at this point in the history
- Added requirements, installation and contributing information to
README.md.
- Added OAuth2::sessions() to check if sessions are enabled and one is
active.
- Fixed OAuth2::iloginURL(), OAuth2::iloginButton() and
OAuth2::iloginRedirect() from generating bad links and
outputting/logging undefined variable: $redirect_uri errors.
- OAuth2::loginRedirect() now checks if headers have already been sent.
- Added OAuth2::loginRedirect(string $message), to output a string
before stopping the script.
- Added license to composer.json.
  • Loading branch information
samuelthomas2774 committed Jul 12, 2015
1 parent c7578f9 commit d31d95e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 36 deletions.
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,44 @@ An OAuth 2.0 Client library with built-in support for Facebook, Google, Microsof
- Eventbrite https://eventbrite.com
- Other, just create a new OAuth2 object and include the dialog->base_url, api->base_url and requests->{"/oauth/token"} options.

Requirements and installation
------------

This requires at least PHP/5.4.

| Version | Supported |
|---------|-----------|
| PHP/5.3 | No |
| PHP/5.4 | Not tested |
| PHP/5.5 | Yes |
| PHP/5.6 | Yes |
| PHP/7.0 | Not tested |

To install this, you can either download the .zip or .tar and extract it or use composer.

#### Download .zip / .tar

1. Download the .zip or .tar file from the [releases](/samuelthomas2774/oauth-client/releases) page.
2. Extract the files from the downloaded .zip or .tar file.
3. Upload the extracted files to your website, or move them to wherever they should be.

#### Composer

1. Add "samuelthomas2774/oauth-client": "~2.1.0" to your composer.json.
```json
{
"require": {
"samuelthomas2774/oauth-client": "~2.1.0"
}
}

```
2. Run composer. This will automatically download the latest patch version.
```
php composer.phar install

```

Default (OAuth2)
------------
1. Include src/autoload.php in all pages that need access to any provider.
Expand Down Expand Up @@ -347,3 +385,13 @@ try { echo "Your Facebook User ID (for this app) is: " . $oauth->userid(); }
catch(Exception $error) { exit("Facebook returned an error: " . print_r($error, true)); }

```

Contributing
------------

Please fork and edit this if you spot a bug or want to add a new feature, pull requests for useful features, bug fixes and additional providers will be accepted (unless they add more bugs than they fix :smile:).

If you would like a new feature but can't or don't want to add if yourself, just [contact me on my website][st/about/contact] or [create an issue with the `feature` label][issue:new:feature].

[st/about/contact]: https://samuelthomas.ml/about/contact
[issue:new:feature]: https://github.com/samuelthomas2774/oauth-client/issues/new?labels[]=feature
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"description": "An OAuth 2.0 Client library with built-in support for Facebook, Google, Microsoft, Yahoo, GitHub, LinkedIn & more.",
"keywords": [ "oauth", "client", "oauth-client", "oauth2", "oauth2-client" ],
"homepage": "https://samuelthomas2774.github.io/oauth-client/",
"license": "MIT",
"authors": [
{
"name": "Samuel Elliott",
Expand All @@ -13,4 +14,4 @@
"autoload": {
"files": [ "src/autoload.php" ]
}
}
}
2 changes: 1 addition & 1 deletion src/facebook.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function parseSignedRequest($signed_request = null) {
$data = json_decode(base64_decode(strtr($payload, "-_", "+/")), false);

// Confirm the signature.
$expected_sig = hash_hmac("sha256", $payload, $this->client()->secret, $raw = true);
$expected_sig = hash_hmac("sha256", $payload, $this->client()->secret, true);
if($sig !== $expected_sig)
throw new Exception(__METHOD__ . "(): Invalid signature. Make sure you have entered the client_secret correctly.");

Expand Down
83 changes: 49 additions & 34 deletions src/oauth.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,18 @@ public function __construct($client_id, $client_secret, $options = Array()) {
if(!is_array($options) && !is_object($options)) throw new Exception(__METHOD__ . "(): \$options must be an array or an object.");
else {
$default_options = $this->defaultoptions();
if(is_object($this->options) || is_array($this->options)) $extended_options = (array)$this->options;
if(is_object($this->options) || is_array($this->options)) $extended_options = $this->options;
else $extended_options = Array();
$user_options = (array)$options;

$this->options = $default_options;
foreach($extended_options as $key => $value) $this->options($key, $value);
foreach($options as $key => $value) $this->options($key, $value);
}

// Try to restore the access token from options or the session.
if($this->options("access_token") != null) {
if(is_string($this->options("access_token"))) {
$this->token = $this->options("access_token"); unset($this->options->access_token);
} elseif($this->session("token") != null) $this->token = $this->session("token");
} elseif(is_string($this->session("token"))) $this->token = $this->session("token");
}

// function autorun(). Completes most OAuth-related tasks itself.
Expand Down Expand Up @@ -126,17 +125,17 @@ public function api($method, $url, $params = Array(), $headers = Array(), $auth
// function getAccessTokenFromCode(). Exchanges the code for an access token.
public function getAccessTokenFromCode($redirect_url, $code = null, $state = true) {
// Check if redirect_url is a url. The redirect_url should be exactly the same as the redirect_url used in the login dialog. (So really, this should just be the same as the current url.)
if(!filter_var($redirect_url, FILTER_VALIDATE_URL)) throw new Exception(__METHOD__ . "(): \$redirect_url must be a valid url.");
if(!is_string($redirect_url) || !filter_var($redirect_url, FILTER_VALIDATE_URL)) throw new Exception(__METHOD__ . "(): \$redirect_url must be a valid url.");

// Check if code is a string or null.
if(is_string($code)) $code = trim($code);
elseif(($code == null) && isset($_GET["code"])) $code = trim($_GET["code"]);
elseif(($code === null) && isset($_GET["code"])) $code = trim($_GET["code"]);
else throw new Exception(__METHOD__ . "(): \$code must be a string.");

// Check state if required.
if($state == true) $state = isset($_GET["state"]) ? $_GET["state"] : null;
if(($this->options("session_prefix") != null) && ($state != false) && ( // Check state? Ignore if sessions are disabled (as state won't exist) or if $state is set to false.
($this->session("state") == null) || // State is not set: trigger error.
if($state === true) $state = isset($_GET["state"]) ? $_GET["state"] : null;
if($this->sessions() && ($state !== false) && ( // Check state? Ignore if sessions are disabled (as state won't exist) or if $state is set to false.
!is_string($this->session("state")) || // State is not set (or is not string): trigger error.
($this->session("state") != $state) // State does not match $state: trigger error.
)) {
// Invalid state parameter.
Expand Down Expand Up @@ -204,19 +203,19 @@ public function getAccessTokenFromRefreshToken($refresh_token) {
// function iloginURL(). Returns the URL for the login dialog.
public function iloginURL($redirect_url, $permissions = Array(), $params = Array()) {
if(is_array($params) && !isset($params["response_type"])) $params["response_type"] = "token";
return $this->loginURL($redirect_uri, $permissions, $params);
return $this->loginURL($redirect_url, $permissions, $params);
}

// function iloginButton(). Returns the URL for the login dialog.
public function iloginButton($button_text, $redirect_url, $permissions = Array(), $params = Array(), $colour = null) {
if(is_array($params) && !isset($params["response_type"])) $params["response_type"] = "token";
return $this->loginButton($button_text, $redirect_uri, $permissions, $params, $colour);
return $this->loginButton($button_text, $redirect_url, $permissions, $params, $colour);
}

// function iloginRedirect(). Redirects to the login dialog.
public function iloginRedirect($redirect_url, $permissions = Array(), $params = Array()) {
public function iloginRedirect($redirect_url, $permissions = Array(), $params = Array(), $message = "") {
if(is_array($params) && !isset($params["response_type"])) $params["response_type"] = "token";
return $this->loginRedirect($redirect_uri, $permissions, $params);
return $this->loginRedirect($redirect_url, $permissions, $params, $message);
}

// --- Resource Owner Credentials Grant --- //
Expand Down Expand Up @@ -356,23 +355,29 @@ public function loginButton($button_text, $redirect_url, $permissions = Array(),
}

// function loginRedirect(). Redirects to the login dialog.
public function loginRedirect($redirect_url, $permissions = Array(), $params = Array()) {
public function loginRedirect($redirect_url, $permissions = Array(), $params = Array(), $message) {
// Get a Login Dialog URL using the OAuth2::loginURL() function.
$url = $this->loginURL($redirect_url, $permissions, $params);

// Make sure $message is a string.
if(!is_string($message)) $message = "";

// Make sure headers have not been sent.
if(headers_sent()) throw new Exception(__METHOD__ . "(): Headers have already been sent.");

// Redirect to the Login Dialog.
header("Location: {$url}", true, 303);
exit();
exit($message);
}

// function accessToken(). Returns / sets the current access token.
public function accessToken($token = false, $session = true) {
if($token === null) {
$this->token = null;
if($session == true) $this->session("token", null);
if($session === true) $this->session("token", null);
} elseif(is_string($token)) {
$this->token = $token;
if($session == true) $this->session("token", $token);
if($session === true) $this->session("token", $token);
} else {
return $this->token;
}
Expand Down Expand Up @@ -406,7 +411,6 @@ public function options($name) {
$options = Array(&$this->options);
$ek = 0;
$nk = array_keys($name);
$lo = end($nk);
foreach($name as $i => $key) {
if(is_object($options[$ek])) {
if(!isset($options[$ek]->{$key}) && $aset) {
Expand Down Expand Up @@ -491,23 +495,37 @@ public function client() {
// -- FOR OAuth2 AND OAuthRequest USE ONLY -- //
// function triggerError(). Triggers an error. This should only be used by the OAuth2 and OAuthRequest classes.
public function triggerError($message, $error = null) {
$this->error = $error != null ? $error : $message;
if($this->options([ "errors", "throw" ]) == true) throw new Exception($message);
$this->error = $error !== null ? $error : $message;
if($this->options([ "errors", "throw" ]) === true) throw new Exception($message);
}

// function sessions(). Checks if sessions are enabled.
public function sessions() {
// Get session_prefix. If not a string or false reset to default.
if(!is_string($session_prefix = $this->options("session_prefix")) && ($session_prefix !== false))
$this->options("session_prefix", $session_prefix = $this->defaultoptions()->session_prefix);

if(session_status() !== PHP_SESSION_ACTIVE)
// Doesn't matter if sessions are disabled: one hasn't been started.
return false;
elseif($session_prefix === false)
// Sessions are diabled.
return false;
else
// Sessions are enabled and one is active.
return true;
}

// function session(). Returns / Sets session data. This should only be used by the OAuth2 and OAuthRequest classes.
// Fails silently if sessions are disabled.
public function session($name) {
$params = func_get_args();

// Get session_prefix. If not a string or false reset to default.
if(!is_string($session_prefix = $this->options("session_prefix")) && ($session_prefix != false))
$this->options("session_prefix", $session_prefix = $this->defaultoptions()->session_prefix);
// Check if sessions are enabled.
if(!$this->sessions()) return null;
$session_prefix = $this->options([ "session_prefix" ]);

if($session_prefix == false)
// Sessions are diabled.
return null;
elseif(array_key_exists(1, $params) && ($params[1] === null)) {
if(array_key_exists(1, $params) && ($params[1] === null)) {
// Delete
$_SESSION[$session_prefix . $name] = null;
unset($_SESSION[$session_prefix . $name]);
Expand All @@ -526,14 +544,11 @@ public function session($name) {
// Fails silently if sessions are disabled.
// This can now be done with OAuth2::session(), by setting $value to null.
public function sessionDelete($name) {
$session_prefix = $this->options("session_prefix");
if(!is_string($session_prefix) && ($session_prefix != false))
$this->options("session_prefix", $session_prefix = $this->defaultoptions()->session_prefix);
// Check if sessions are enabled.
if(!$this->sessions()) return null;
$session_prefix = $this->options([ "session_prefix" ]);

if($session_prefix == false)
// Sessions are diabled.
return null;
elseif(isset($_SESSION[$session_prefix . $name]))
if(isset($_SESSION[$session_prefix . $name]))
// Delete
unset($_SESSION[$session_prefix . $name]);
}
Expand Down

0 comments on commit d31d95e

Please sign in to comment.