New file |
0,0 → 1,412 |
<?php |
|
/** |
* This is the PHP OpenID library by JanRain, Inc. |
* |
* This module contains core utility functionality used by the |
* library. See Consumer.php and Server.php for the consumer and |
* server implementations. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: See the COPYING file included in this distribution. |
* |
* @package OpenID |
* @author JanRain, Inc. <openid@janrain.com> |
* @copyright 2005 Janrain, Inc. |
* @license http://www.gnu.org/copyleft/lesser.html LGPL |
*/ |
|
/** |
* Require the fetcher code. |
*/ |
require_once "Services/Yadis/PlainHTTPFetcher.php"; |
require_once "Services/Yadis/ParanoidHTTPFetcher.php"; |
require_once "Auth/OpenID/BigMath.php"; |
|
/** |
* Status code returned by the server when the only option is to show |
* an error page, since we do not have enough information to redirect |
* back to the consumer. The associated value is an error message that |
* should be displayed on an HTML error page. |
* |
* @see Auth_OpenID_Server |
*/ |
define('Auth_OpenID_LOCAL_ERROR', 'local_error'); |
|
/** |
* Status code returned when there is an error to return in key-value |
* form to the consumer. The caller should return a 400 Bad Request |
* response with content-type text/plain and the value as the body. |
* |
* @see Auth_OpenID_Server |
*/ |
define('Auth_OpenID_REMOTE_ERROR', 'remote_error'); |
|
/** |
* Status code returned when there is a key-value form OK response to |
* the consumer. The value associated with this code is the |
* response. The caller should return a 200 OK response with |
* content-type text/plain and the value as the body. |
* |
* @see Auth_OpenID_Server |
*/ |
define('Auth_OpenID_REMOTE_OK', 'remote_ok'); |
|
/** |
* Status code returned when there is a redirect back to the |
* consumer. The value is the URL to redirect back to. The caller |
* should return a 302 Found redirect with a Location: header |
* containing the URL. |
* |
* @see Auth_OpenID_Server |
*/ |
define('Auth_OpenID_REDIRECT', 'redirect'); |
|
/** |
* Status code returned when the caller needs to authenticate the |
* user. The associated value is a {@link Auth_OpenID_ServerRequest} |
* object that can be used to complete the authentication. If the user |
* has taken some authentication action, use the retry() method of the |
* {@link Auth_OpenID_ServerRequest} object to complete the request. |
* |
* @see Auth_OpenID_Server |
*/ |
define('Auth_OpenID_DO_AUTH', 'do_auth'); |
|
/** |
* Status code returned when there were no OpenID arguments |
* passed. This code indicates that the caller should return a 200 OK |
* response and display an HTML page that says that this is an OpenID |
* server endpoint. |
* |
* @see Auth_OpenID_Server |
*/ |
define('Auth_OpenID_DO_ABOUT', 'do_about'); |
|
/** |
* Defines for regexes and format checking. |
*/ |
define('Auth_OpenID_letters', |
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
|
define('Auth_OpenID_digits', |
"0123456789"); |
|
define('Auth_OpenID_punct', |
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"); |
|
if (Auth_OpenID_getMathLib() === null) { |
define('Auth_OpenID_NO_MATH_SUPPORT', true); |
} |
|
/** |
* The OpenID utility function class. |
* |
* @package OpenID |
* @access private |
*/ |
class Auth_OpenID { |
|
/** |
* These namespaces are automatically fixed in query arguments by |
* Auth_OpenID::fixArgs. |
*/ |
function getOpenIDNamespaces() |
{ |
return array('openid', |
'sreg'); |
} |
|
/** |
* Rename query arguments back to 'openid.' from 'openid_' |
* |
* @access private |
* @param array $args An associative array of URL query arguments |
*/ |
function fixArgs($args) |
{ |
foreach (array_keys($args) as $key) { |
$fixed = $key; |
if (preg_match('/^openid/', $key)) { |
foreach (Auth_OpenID::getOpenIDNamespaces() as $ns) { |
if (preg_match('/'.$ns.'_/', $key)) { |
$fixed = preg_replace('/'.$ns.'_/', $ns.'.', $fixed); |
} |
} |
|
if ($fixed != $key) { |
$val = $args[$key]; |
unset($args[$key]); |
$args[$fixed] = $val; |
} |
} |
} |
|
return $args; |
} |
|
/** |
* Create dir_name as a directory if it does not exist. If it |
* exists, make sure that it is, in fact, a directory. Returns |
* true if the operation succeeded; false if not. |
* |
* @access private |
*/ |
function ensureDir($dir_name) |
{ |
if (is_dir($dir_name) || @mkdir($dir_name)) { |
return true; |
} else { |
if (Auth_OpenID::ensureDir(dirname($dir_name))) { |
return is_dir($dir_name) || @mkdir($dir_name); |
} else { |
return false; |
} |
} |
} |
|
/** |
* Convenience function for getting array values. |
* |
* @access private |
*/ |
function arrayGet($arr, $key, $fallback = null) |
{ |
if (is_array($arr)) { |
if (array_key_exists($key, $arr)) { |
return $arr[$key]; |
} else { |
return $fallback; |
} |
} else { |
trigger_error("Auth_OpenID::arrayGet expected " . |
"array as first parameter", E_USER_WARNING); |
return false; |
} |
} |
|
/** |
* Implements the PHP 5 'http_build_query' functionality. |
* |
* @access private |
* @param array $data Either an array key/value pairs or an array |
* of arrays, each of which holding two values: a key and a value, |
* sequentially. |
* @return string $result The result of url-encoding the key/value |
* pairs from $data into a URL query string |
* (e.g. "username=bob&id=56"). |
*/ |
function httpBuildQuery($data) |
{ |
$pairs = array(); |
foreach ($data as $key => $value) { |
if (is_array($value)) { |
$pairs[] = urlencode($value[0])."=".urlencode($value[1]); |
} else { |
$pairs[] = urlencode($key)."=".urlencode($value); |
} |
} |
return implode("&", $pairs); |
} |
|
/** |
* "Appends" query arguments onto a URL. The URL may or may not |
* already have arguments (following a question mark). |
* |
* @param string $url A URL, which may or may not already have |
* arguments. |
* @param array $args Either an array key/value pairs or an array of |
* arrays, each of which holding two values: a key and a value, |
* sequentially. If $args is an ordinary key/value array, the |
* parameters will be added to the URL in sorted alphabetical order; |
* if $args is an array of arrays, their order will be preserved. |
* @return string $url The original URL with the new parameters added. |
* |
*/ |
function appendArgs($url, $args) |
{ |
if (count($args) == 0) { |
return $url; |
} |
|
// Non-empty array; if it is an array of arrays, use |
// multisort; otherwise use sort. |
if (array_key_exists(0, $args) && |
is_array($args[0])) { |
// Do nothing here. |
} else { |
$keys = array_keys($args); |
sort($keys); |
$new_args = array(); |
foreach ($keys as $key) { |
$new_args[] = array($key, $args[$key]); |
} |
$args = $new_args; |
} |
|
$sep = '?'; |
if (strpos($url, '?') !== false) { |
$sep = '&'; |
} |
|
return $url . $sep . Auth_OpenID::httpBuildQuery($args); |
} |
|
/** |
* Turn a string into an ASCII string. |
* |
* Replace non-ascii characters with a %-encoded, UTF-8 |
* encoding. This function will fail if the input is a string and |
* there are non-7-bit-safe characters. It is assumed that the |
* caller will have already translated the input into a Unicode |
* character sequence, according to the encoding of the HTTP POST |
* or GET. |
* |
* Do not escape anything that is already 7-bit safe, so we do the |
* minimal transform on the identity URL |
* |
* @access private |
*/ |
function quoteMinimal($s) |
{ |
$res = array(); |
for ($i = 0; $i < strlen($s); $i++) { |
$c = $s[$i]; |
if ($c >= "\x80") { |
for ($j = 0; $j < count(utf8_encode($c)); $j++) { |
array_push($res, sprintf("%02X", ord($c[$j]))); |
} |
} else { |
array_push($res, $c); |
} |
} |
|
return implode('', $res); |
} |
|
/** |
* Implements python's urlunparse, which is not available in PHP. |
* Given the specified components of a URL, this function rebuilds |
* and returns the URL. |
* |
* @access private |
* @param string $scheme The scheme (e.g. 'http'). Defaults to 'http'. |
* @param string $host The host. Required. |
* @param string $port The port. |
* @param string $path The path. |
* @param string $query The query. |
* @param string $fragment The fragment. |
* @return string $url The URL resulting from assembling the |
* specified components. |
*/ |
function urlunparse($scheme, $host, $port = null, $path = '/', |
$query = '', $fragment = '') |
{ |
|
if (!$scheme) { |
$scheme = 'http'; |
} |
|
if (!$host) { |
return false; |
} |
|
if (!$path) { |
$path = '/'; |
} |
|
$result = $scheme . "://" . $host; |
|
if ($port) { |
$result .= ":" . $port; |
} |
|
$result .= $path; |
|
if ($query) { |
$result .= "?" . $query; |
} |
|
if ($fragment) { |
$result .= "#" . $fragment; |
} |
|
return $result; |
} |
|
/** |
* Given a URL, this "normalizes" it by adding a trailing slash |
* and / or a leading http:// scheme where necessary. Returns |
* null if the original URL is malformed and cannot be normalized. |
* |
* @access private |
* @param string $url The URL to be normalized. |
* @return mixed $new_url The URL after normalization, or null if |
* $url was malformed. |
*/ |
function normalizeUrl($url) |
{ |
if ($url === null) { |
return null; |
} |
|
assert(is_string($url)); |
|
$old_url = $url; |
$url = trim($url); |
|
if (strpos($url, "://") === false) { |
$url = "http://" . $url; |
} |
|
$parsed = @parse_url($url); |
|
if ($parsed === false) { |
return null; |
} |
|
$defaults = array( |
'scheme' => '', |
'host' => '', |
'path' => '', |
'query' => '', |
'fragment' => '', |
'port' => '' |
); |
|
$parsed = array_merge($defaults, $parsed); |
|
if (($parsed['scheme'] == '') || |
($parsed['host'] == '')) { |
if ($parsed['path'] == '' && |
$parsed['query'] == '' && |
$parsed['fragment'] == '') { |
return null; |
} |
|
$url = 'http://' + $url; |
$parsed = parse_url($url); |
|
$parsed = array_merge($defaults, $parsed); |
} |
|
$tail = array_map(array('Auth_OpenID', 'quoteMinimal'), |
array($parsed['path'], |
$parsed['query'], |
$parsed['fragment'])); |
if ($tail[0] == '') { |
$tail[0] = '/'; |
} |
|
$url = Auth_OpenID::urlunparse($parsed['scheme'], $parsed['host'], |
$parsed['port'], $tail[0], $tail[1], |
$tail[2]); |
|
assert(is_string($url)); |
|
return $url; |
} |
} |
|
?> |