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