1<?php
2/**
3 * Federated Login for DokuWiki - OpenID authorization service client class
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @link       http://www.dokuwiki.org/plugin:fedauth
7 * @author     Aoi Karasu <aoikarasu@gmail.com>
8 */
9
10/**
11 * The OpenID authorization service client class.
12 *
13 * @author     Aoi Karasu <aoikarasu@gmail.com>
14 */
15class fa_openid_svc extends fa_service {
16
17    /**
18     * OpenID consumer object.
19     */
20    var $consumer = null;
21
22    /**
23     * Creates the class instance bound to a provider object.
24     *
25     * @param objref $provider authorization provider configuration object
26     */
27    function __construct(&$provider) {
28        parent::__construct(&$provider);
29    }
30
31    /**
32     * Returns the OpenID consumer.
33     *
34     * @author Aoi Karasu <aoikarasu@gmail.com>
35     * @author Original by François Hodierne (http://h6e.net/)
36     * @return the OpenID consumer object
37     */
38    function &getConsumer()
39    {
40        global $conf;
41
42        if (isset($this->consumer)) {
43            return $this->consumer;
44        }
45        define('Auth_OpenID_RAND_SOURCE', null);
46        set_include_path( get_include_path() . PATH_SEPARATOR . FEDAUTH_PLUGIN );
47        require_once("Auth/OpenID/Consumer.php");
48        require_once("Auth/OpenID/FileStore.php");
49        // start session (needed for YADIS)
50        session_start();
51        // create file storage area for OpenID data
52        $store = new Auth_OpenID_FileStore($conf['tmpdir'] . '/fedauth/openid');
53        // create OpenID consumer
54        $this->consumer = new Auth_OpenID_Consumer($store);
55        return $this->consumer;
56    }
57
58    /**
59     * Performs the OpenID authorization request.
60     *
61     * @param string $username an username or OpenID URL
62     * @param string $return_to an URL user by the authorization service to pass the response (result)
63     * @return mixed error code or fully configured authorization service request URL
64     */
65    function request($username, $return_to) {
66        global $ID;
67
68        // prepare service URL
69        $url = $this->provider->getURL();
70        if (empty($url)) {
71            $url = $username;
72        }
73        else {
74            $url = str_replace('{username}', $username, $url);
75        }
76
77        // try to login with the service URL
78        $consumer =& $this->getConsumer();
79        $auth = $consumer->begin($url);
80        if (!$auth) {
81            return -1; // invalid openid
82        }
83        // add an attribute query extension to get user details
84        require_once("Auth/OpenID/SReg.php");
85        $attrq = Auth_OpenID_SRegRequest::build(array(),array('nickname','email','fullname'));
86        $auth->addExtension($attrq);
87
88        $url = $auth->redirectURL(DOKU_URL, $return_to);
89        return $url;
90    }
91
92    /**
93     * Processes the OpenID authorization response.
94     *
95     * @param string $ref referer URL used to identify the authorization request
96     * @return mixed error code or claimed identity string
97     */
98    function response($ref) {
99        $consumer =& $this->getConsumer();
100        $response = $consumer->complete($ref);
101
102        if ($_REQUEST['openid_mode'] != 'id_res') {
103            // TODO: handle openid_mode == 'cancel'
104            return -1; // authorization failed
105        }
106
107        if ($response->status == Auth_OpenID_SUCCESS) {
108            $openid = isset($_REQUEST['openid_claimed_id']) ? $_REQUEST['openid_claimed_id'] : $_REQUEST['openid1_claimed_id'];
109            if (empty($openid)) {
110                return -2; // cannot find the claimed ID
111            }
112            return $openid; // return the claimed ID
113        }
114        return -1; // authorization failed
115    }
116
117} /* fa_openid_svc */
118
119/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
120