1<?php
2/**
3 * Federated Login for DokuWiki - handles login form 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 * Class responsible for rendering the fededated login form.
12 *
13 * @author     Aoi Karasu <aoikarasu@gmail.com>
14 */
15class fa_login extends fa_base {
16
17    /**
18     * Creates the class instance bound to a plugin instance and an authentication provider.
19     *
20     * @param objref $manager object reference to the action plugin
21     * @param string $cmd name of the command to handle
22     * @param string $provid (optional) an authentication provider id
23     */
24    function __construct(&$manager, $cmd, $provid='') {
25        parent::__construct(&$manager, $cmd, $provid);
26    }
27
28    /**
29     * No pocessing when displaying federated login form.
30     * This method is intended to suppress the 'unknown command' message only.
31     */
32    function process_login() {
33        $this->success = true;
34        return null;
35    }
36
37    /**
38     * Renders the feredated login form.
39     */
40    function html_login() {
41        $this->html_login_service_from();
42    }
43
44    /**
45     * Returns the 'click to ...' text.
46     */
47    function getLoginText() {
48        return empty($_SERVER['REMOTE_USER']) ? $this->lang['clicktologin'] : $this->lang['clicktoadd'];
49    }
50
51    /**
52     * Returns the user authentication data storage manager.
53     *
54     * @return the user authentication data storage manager object
55     */
56    function &getUserStore() {
57        $hfile = FEDAUTH_PLUGIN . "classes/usr/fa_filestore.class.php";
58        require_once($hfile);
59        return new fa_filestore();
60    }
61
62    /**
63     * Returns the service consumer depending on provider's service type.
64     *
65     * @param object $pro the authentication service provider configuration object
66     * @return the service consumer object
67     */
68    function &getService($pro) {
69        // TODO: change to getType() once it is implemented in the fa_provider class
70        $id = "fa_" . "openid" /*$pro->getType()*/;
71        $hfile = FEDAUTH_PLUGIN . "classes/svc/$id.svc.class.php";
72        require_once($hfile);
73        $class = $id . "_svc";
74        return new $class($pro);
75    }
76
77    /**
78     * Builds an URL to redirect to, based on arbitrary conditions:
79     *  - uses $_GET value stored in session before authentication request, if it's available
80     *  - sets command to display logins management, if a new identity has been added
81     *  - or else uses current page $ID only
82     *
83     * @return string URL to be used as the redirect location
84     */
85    function restoreLocation() {
86        global $ID;
87
88        if (isset($_SESSION[DOKU_COOKIE]['fedauth']['stor'])) {
89            $get = $_SESSION[DOKU_COOKIE]['fedauth']['stor']['gt'];
90            $get = array_diff_key($get, array('id' => ''));
91            if (!empty($get)) {
92                $params = array_implode($get);
93                return wl($ID, $params, true, '&');
94            }
95        }
96        if (($_REQUEST['mode'] == 'add') || ($_REQUEST['mode'] == 'removed')) {
97            return wl($ID, 'do=fedauth', true, '&');
98        }
99        if ($_REQUEST['mode'] == 'register') {
100            return wl($ID, 'do=fedauth', true, '&') . '&fa[register]';
101        }
102        return wl($ID);
103    }
104
105    /**
106     * Renders the feredated login form.
107     *
108     * @param bool $return (optional) indicates whether the form should be returned as string or printed
109     * @return mixed generated form string or true, if printed
110     */
111    function html_login_service_from($return=false) {
112        global $ID, $conf, $auth;
113
114        $user = $_SERVER['REMOTE_USER'];
115
116        $out = '<div id="fa__authform">'
117             . '<p>'.$this->lang['gotlogin'].' '.$this->getLoginText().'</p>'
118             . '<form action="'.wl($ID, 'do=fedauth').'" method="post">'
119             . '  <fieldset class="hidden">'
120//             . '    <input type="hidden" name="do" value="fedauth" />'
121             . formSecurityToken(false)
122             . '  </fieldset>'
123             . '  <div id="axwrap__large"><fieldset>'
124             . $this->html_providers_list($this->manager->providers->getLarge(), true)
125             . '  </fieldset></div>'
126             . '  <div id="axwrap__small"><fieldset>'
127             . $this->html_providers_list($this->manager->providers->getSmall(), false)
128             . '  </fieldset></div>'
129             . $this->html_service_signin()
130             . $this->html_general_openid()
131             . '</form></div>';
132
133        if ($return) return $out;
134        print $out;
135        return true;
136    }
137
138    /**
139     * Renders the service provider link buttons.
140     *
141     * @param arrayref $source the source providers array
142     * @param bool $large (optional) true for large buttons, false for small
143     */
144    function html_providers_list(&$source, $large=false) {
145        global $ID, $do;
146
147        if (!is_array($source)) return '';
148
149        $out = '';
150        $sectok = getSecurityToken();
151
152        foreach ($source as $id => $pro) {
153            if (!$pro->isEnabled() || ($pro->getURL() == null)) continue;
154
155            $btn = $this->cmd;
156            $class = $large ? 'btnplarge' : 'btnpsmall';
157            $mode  = $large ? PROV_LARGE : PROV_SMALL;
158            $class .= $this->provid == $id ? ' selected' : '';
159
160            if ($pro->hasUsername()) {
161                $act = $do;
162                $cmd = 'select';
163            }
164            else {
165                $act = 'fedauth';
166                $cmd = 'signin';
167            }
168
169            $out .= '<a href="'.wl($ID, array('do'=> $act, 'sectok' => $sectok)).'&fa['.$cmd.']['.$id.']">'
170                 .  $pro->getImageXHTML($mode, $class) . '</a>';
171        }
172        return $out;
173    }
174
175    /**
176     * Renders the form part with username input, if the service requires it.
177     */
178    function html_service_signin() {
179        if (!($pro = $this->manager->providers->get($this->provid))) {
180            return '';
181        }
182        if (!$pro->isEnabled() || !$pro->hasUsername()) {
183            return '';
184        }
185        $out = '  <div id="axwrap__enterlogin"><fieldset>'
186             . '    <p>'.str_replace('@PROVID@', $pro->getName(), $this->lang['enterlogin']).'</p>'
187             . '<input type="text" name="fa_signinname" class="edit">'
188             . '<input type="submit" class="button" name="fa[signin]['.$this->provid.']" value="' . $this->lang['btn_signin'] . '" />'
189             . '  </fieldset></div>';
190
191        return $out;
192    }
193
194    /**
195     * Renders the form part for general OpenID login.
196     */
197    function html_general_openid() {
198        if (!($pro = $this->manager->providers->get('openid'))) {
199            return '';
200        }
201        if (!$pro->isEnabled()) {
202            return '';
203        }
204
205        $out = '  <div id="axwrap__openid"><fieldset>'
206             . '    <p>'.$this->lang['manualopenid'].':</p>'
207             . $pro->getImageXHTML(PROV_SMALL, 'manualoid')
208             . '<input type="text" name="fa_openidurl" class="edit" value="http://">'
209             . '<input type="submit" class="button" name="fa[signin][openid]" value="' . $this->lang['btn_login'] . '" />'
210             . '  </fieldset></div>';
211
212        return $out;
213    }
214
215} /* fa_login */
216
217/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
218
219