Licence and jqmobile beta 3 upgrade
[busui.git] / lib / openid-php / Auth / Yadis / Manager.php
blob:a/lib/openid-php/Auth/Yadis/Manager.php -> blob:b/lib/openid-php/Auth/Yadis/Manager.php
<?php <?php
   
/** /**
* Yadis service manager to be used during yadis-driven authentication * Yadis service manager to be used during yadis-driven authentication
* attempts. * attempts.
* *
* @package OpenID * @package OpenID
*/ */
   
/** /**
* The base session class used by the Auth_Yadis_Manager. This * The base session class used by the Auth_Yadis_Manager. This
* class wraps the default PHP session machinery and should be * class wraps the default PHP session machinery and should be
* subclassed if your application doesn't use PHP sessioning. * subclassed if your application doesn't use PHP sessioning.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_Yadis_PHPSession { class Auth_Yadis_PHPSession {
/** /**
* Set a session key/value pair. * Set a session key/value pair.
* *
* @param string $name The name of the session key to add. * @param string $name The name of the session key to add.
* @param string $value The value to add to the session. * @param string $value The value to add to the session.
*/ */
function set($name, $value) function set($name, $value)
{ {
$_SESSION[$name] = $value; $_SESSION[$name] = $value;
} }
   
/** /**
* Get a key's value from the session. * Get a key's value from the session.
* *
* @param string $name The name of the key to retrieve. * @param string $name The name of the key to retrieve.
* @param string $default The optional value to return if the key * @param string $default The optional value to return if the key
* is not found in the session. * is not found in the session.
* @return string $result The key's value in the session or * @return string $result The key's value in the session or
* $default if it isn't found. * $default if it isn't found.
*/ */
function get($name, $default=null) function get($name, $default=null)
{ {
if (array_key_exists($name, $_SESSION)) { if (array_key_exists($name, $_SESSION)) {
return $_SESSION[$name]; return $_SESSION[$name];
} else { } else {
return $default; return $default;
} }
} }
   
/** /**
* Remove a key/value pair from the session. * Remove a key/value pair from the session.
* *
* @param string $name The name of the key to remove. * @param string $name The name of the key to remove.
*/ */
function del($name) function del($name)
{ {
unset($_SESSION[$name]); unset($_SESSION[$name]);
} }
   
/** /**
* Return the contents of the session in array form. * Return the contents of the session in array form.
*/ */
function contents() function contents()
{ {
return $_SESSION; return $_SESSION;
} }
} }
   
/** /**
* A session helper class designed to translate between arrays and * A session helper class designed to translate between arrays and
* objects. Note that the class used must have a constructor that * objects. Note that the class used must have a constructor that
* takes no parameters. This is not a general solution, but it works * takes no parameters. This is not a general solution, but it works
* for dumb objects that just need to have attributes set. The idea * for dumb objects that just need to have attributes set. The idea
* is that you'll subclass this and override $this->check($data) -> * is that you'll subclass this and override $this->check($data) ->
* bool to implement your own session data validation. * bool to implement your own session data validation.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_Yadis_SessionLoader { class Auth_Yadis_SessionLoader {
/** /**
* Override this. * Override this.
* *
* @access private * @access private
*/ */
function check($data) function check($data)
{ {
return true; return true;
} }
   
/** /**
* Given a session data value (an array), this creates an object * Given a session data value (an array), this creates an object
* (returned by $this->newObject()) whose attributes and values * (returned by $this->newObject()) whose attributes and values
* are those in $data. Returns null if $data lacks keys found in * are those in $data. Returns null if $data lacks keys found in
* $this->requiredKeys(). Returns null if $this->check($data) * $this->requiredKeys(). Returns null if $this->check($data)
* evaluates to false. Returns null if $this->newObject() * evaluates to false. Returns null if $this->newObject()
* evaluates to false. * evaluates to false.
* *
* @access private * @access private
*/ */
function fromSession($data) function fromSession($data)
{ {
if (!$data) { if (!$data) {
return null; return null;
} }
   
$required = $this->requiredKeys(); $required = $this->requiredKeys();
   
foreach ($required as $k) { foreach ($required as $k) {
if (!array_key_exists($k, $data)) { if (!array_key_exists($k, $data)) {
return null; return null;
} }
} }
   
if (!$this->check($data)) { if (!$this->check($data)) {
return null; return null;
} }
   
$data = array_merge($data, $this->prepareForLoad($data)); $data = array_merge($data, $this->prepareForLoad($data));
$obj = $this->newObject($data); $obj = $this->newObject($data);
   
if (!$obj) { if (!$obj) {
return null; return null;
} }
   
foreach ($required as $k) { foreach ($required as $k) {
$obj->$k = $data[$k]; $obj->$k = $data[$k];
} }
   
return $obj; return $obj;
} }
   
/** /**
* Prepares the data array by making any necessary changes. * Prepares the data array by making any necessary changes.
* Returns an array whose keys and values will be used to update * Returns an array whose keys and values will be used to update
* the original data array before calling $this->newObject($data). * the original data array before calling $this->newObject($data).
* *
* @access private * @access private
*/ */
function prepareForLoad($data) function prepareForLoad($data)
{ {
return array(); return array();
} }
   
/** /**
* Returns a new instance of this loader's class, using the * Returns a new instance of this loader's class, using the
* session data to construct it if necessary. The object need * session data to construct it if necessary. The object need
* only be created; $this->fromSession() will take care of setting * only be created; $this->fromSession() will take care of setting
* the object's attributes. * the object's attributes.
* *
* @access private * @access private
*/ */
function newObject($data) function newObject($data)
{ {
return null; return null;
} }
   
/** /**
* Returns an array of keys and values built from the attributes * Returns an array of keys and values built from the attributes
* of $obj. If $this->prepareForSave($obj) returns an array, its keys * of $obj. If $this->prepareForSave($obj) returns an array, its keys
* and values are used to update the $data array of attributes * and values are used to update the $data array of attributes
* from $obj. * from $obj.
* *
* @access private * @access private
*/ */
function toSession($obj) function toSession($obj)
{ {
$data = array(); $data = array();
foreach ($obj as $k => $v) { foreach ($obj as $k => $v) {
$data[$k] = $v; $data[$k] = $v;
} }
   
$extra = $this->prepareForSave($obj); $extra = $this->prepareForSave($obj);
   
if ($extra && is_array($extra)) { if ($extra && is_array($extra)) {
foreach ($extra as $k => $v) { foreach ($extra as $k => $v) {
$data[$k] = $v; $data[$k] = $v;
} }
} }
   
return $data; return $data;
} }
   
/** /**
* Override this. * Override this.
* *
* @access private * @access private
*/ */
function prepareForSave($obj) function prepareForSave($obj)
{ {
return array(); return array();
} }
} }
   
/** /**
* A concrete loader implementation for Auth_OpenID_ServiceEndpoints. * A concrete loader implementation for Auth_OpenID_ServiceEndpoints.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_ServiceEndpointLoader extends Auth_Yadis_SessionLoader { class Auth_OpenID_ServiceEndpointLoader extends Auth_Yadis_SessionLoader {
function newObject($data) function newObject($data)
{ {
return new Auth_OpenID_ServiceEndpoint(); return new Auth_OpenID_ServiceEndpoint();
} }
   
function requiredKeys() function requiredKeys()
{ {
$obj = new Auth_OpenID_ServiceEndpoint(); $obj = new Auth_OpenID_ServiceEndpoint();
$data = array(); $data = array();
foreach ($obj as $k => $v) { foreach ($obj as $k => $v) {
$data[] = $k; $data[] = $k;
} }
return $data; return $data;
} }
   
function check($data) function check($data)
{ {
return is_array($data['type_uris']); return is_array($data['type_uris']);
} }
} }
   
/** /**
* A concrete loader implementation for Auth_Yadis_Managers. * A concrete loader implementation for Auth_Yadis_Managers.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_Yadis_ManagerLoader extends Auth_Yadis_SessionLoader { class Auth_Yadis_ManagerLoader extends Auth_Yadis_SessionLoader {
function requiredKeys() function requiredKeys()
{ {
return array('starting_url', return array('starting_url',
'yadis_url', 'yadis_url',
'services', 'services',
'session_key', 'session_key',
'_current', '_current',
'stale'); 'stale');
} }
   
function newObject($data) function newObject($data)
{ {
return new Auth_Yadis_Manager($data['starting_url'], return new Auth_Yadis_Manager($data['starting_url'],
$data['yadis_url'], $data['yadis_url'],
$data['services'], $data['services'],
$data['session_key']); $data['session_key']);
} }
   
function check($data) function check($data)
{ {
return is_array($data['services']); return is_array($data['services']);
} }
   
function prepareForLoad($data) function prepareForLoad($data)
{ {
$loader = new Auth_OpenID_ServiceEndpointLoader(); $loader = new Auth_OpenID_ServiceEndpointLoader();
$services = array(); $services = array();
foreach ($data['services'] as $s) { foreach ($data['services'] as $s) {
$services[] = $loader->fromSession($s); $services[] = $loader->fromSession($s);
} }
return array('services' => $services); return array('services' => $services);
} }
   
function prepareForSave($obj) function prepareForSave($obj)
{ {
$loader = new Auth_OpenID_ServiceEndpointLoader(); $loader = new Auth_OpenID_ServiceEndpointLoader();
$services = array(); $services = array();
foreach ($obj->services as $s) { foreach ($obj->services as $s) {
$services[] = $loader->toSession($s); $services[] = $loader->toSession($s);
} }
return array('services' => $services); return array('services' => $services);
} }
} }
   
/** /**
* The Yadis service manager which stores state in a session and * The Yadis service manager which stores state in a session and
* iterates over <Service> elements in a Yadis XRDS document and lets * iterates over <Service> elements in a Yadis XRDS document and lets
* a caller attempt to use each one. This is used by the Yadis * a caller attempt to use each one. This is used by the Yadis
* library internally. * library internally.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_Yadis_Manager { class Auth_Yadis_Manager {
   
/** /**
* Intialize a new yadis service manager. * Intialize a new yadis service manager.
* *
* @access private * @access private
*/ */
function Auth_Yadis_Manager($starting_url, $yadis_url, function Auth_Yadis_Manager($starting_url, $yadis_url,
$services, $session_key) $services, $session_key)
{ {
// The URL that was used to initiate the Yadis protocol // The URL that was used to initiate the Yadis protocol
$this->starting_url = $starting_url; $this->starting_url = $starting_url;
   
// The URL after following redirects (the identifier) // The URL after following redirects (the identifier)
$this->yadis_url = $yadis_url; $this->yadis_url = $yadis_url;
   
// List of service elements // List of service elements
$this->services = $services; $this->services = $services;
   
$this->session_key = $session_key; $this->session_key = $session_key;
   
// Reference to the current service object // Reference to the current service object
$this->_current = null; $this->_current = null;
   
// Stale flag for cleanup if PHP lib has trouble. // Stale flag for cleanup if PHP lib has trouble.
$this->stale = false; $this->stale = false;
} }
   
/** /**
* @access private * @access private
*/ */
function length() function length()
{ {
// How many untried services remain? // How many untried services remain?
return count($this->services); return count($this->services);
} }
   
/** /**
* Return the next service * Return the next service
* *
* $this->current() will continue to return that service until the * $this->current() will continue to return that service until the
* next call to this method. * next call to this method.
*/ */
function nextService() function nextService()
{ {
   
if ($this->services) { if ($this->services) {
$this->_current = array_shift($this->services); $this->_current = array_shift($this->services);
} else { } else {
$this->_current = null; $this->_current = null;
} }
   
return $this->_current; return $this->_current;
} }
   
/** /**
* @access private * @access private
*/ */
function current() function current()
{ {
// Return the current service. // Return the current service.
// Returns None if there are no services left. // Returns None if there are no services left.
return $this->_current; return $this->_current;
} }
   
/** /**
* @access private * @access private
*/ */
function forURL($url) function forURL($url)
{ {
return in_array($url, array($this->starting_url, $this->yadis_url)); return in_array($url, array($this->starting_url, $this->yadis_url));
} }
   
/** /**
* @access private * @access private
*/ */
function started() function started()
{ {
// Has the first service been returned? // Has the first service been returned?
return $this->_current !== null; return $this->_current !== null;
} }
} }
   
/** /**
* State management for discovery. * State management for discovery.
* *
* High-level usage pattern is to call .getNextService(discover) in * High-level usage pattern is to call .getNextService(discover) in
* order to find the next available service for this user for this * order to find the next available service for this user for this
* session. Once a request completes, call .cleanup() to clean up the * session. Once a request completes, call .cleanup() to clean up the
* session state. * session state.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_Yadis_Discovery { class Auth_Yadis_Discovery {
   
/** /**
* @access private * @access private
*/ */
var $DEFAULT_SUFFIX = 'auth'; var $DEFAULT_SUFFIX = 'auth';
   
/** /**
* @access private * @access private
*/ */
var $PREFIX = '_yadis_services_'; var $PREFIX = '_yadis_services_';
   
/** /**
* Initialize a discovery object. * Initialize a discovery object.
* *
* @param Auth_Yadis_PHPSession $session An object which * @param Auth_Yadis_PHPSession $session An object which
* implements the Auth_Yadis_PHPSession API. * implements the Auth_Yadis_PHPSession API.
* @param string $url The URL on which to attempt discovery. * @param string $url The URL on which to attempt discovery.
* @param string $session_key_suffix The optional session key * @param string $session_key_suffix The optional session key
* suffix override. * suffix override.
*/ */
function Auth_Yadis_Discovery($session, $url, function Auth_Yadis_Discovery($session, $url,
$session_key_suffix = null) $session_key_suffix = null)
{ {
/// Initialize a discovery object /// Initialize a discovery object
$this->session = $session; $this->session = $session;
$this->url = $url; $this->url = $url;
if ($session_key_suffix === null) { if ($session_key_suffix === null) {
$session_key_suffix = $this->DEFAULT_SUFFIX; $session_key_suffix = $this->DEFAULT_SUFFIX;
} }
   
$this->session_key_suffix = $session_key_suffix; $this->session_key_suffix = $session_key_suffix;
$this->session_key = $this->PREFIX . $this->session_key_suffix; $this->session_key = $this->PREFIX . $this->session_key_suffix;
} }
   
/** /**
* Return the next authentication service for the pair of * Return the next authentication service for the pair of
* user_input and session. This function handles fallback. * user_input and session. This function handles fallback.