diff --git a/README.md b/README.md index cb8be81..294ca9d 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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 diff --git a/composer.json b/composer.json index 2313377..6e46be1 100644 --- a/composer.json +++ b/composer.json @@ -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", @@ -13,4 +14,4 @@ "autoload": { "files": [ "src/autoload.php" ] } -} \ No newline at end of file +} diff --git a/src/facebook.class.php b/src/facebook.class.php index 29ee73e..21d1b99 100644 --- a/src/facebook.class.php +++ b/src/facebook.class.php @@ -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."); diff --git a/src/oauth.class.php b/src/oauth.class.php index eadd508..8aa94d8 100644 --- a/src/oauth.class.php +++ b/src/oauth.class.php @@ -50,9 +50,8 @@ 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); @@ -60,9 +59,9 @@ public function __construct($client_id, $client_secret, $options = Array()) { } // 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. @@ -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. @@ -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 --- // @@ -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; } @@ -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) { @@ -491,8 +495,25 @@ 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. @@ -500,14 +521,11 @@ public function triggerError($message, $error = null) { 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]); @@ -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]); }