1<?php
2
3/**
4 * DokuWiki Plugin authshibboleth (Action Component)
5 *
6 * Intercepts the 'login' action and redirects the user to the Shibboleth Session Initiator Handler
7 * instead of showing the login form.
8 *
9 * @author  Ivan Novakov http://novakov.cz/
10 * @license http://debug.cz/license/bsd-3-clause BSD 3 Clause
11 * @link https://github.com/ivan-novakov/dokuwiki-shibboleth-auth
12 */
13
14// must be run within Dokuwiki
15if (! defined('DOKU_INC'))
16    die();
17
18if (! defined('DOKU_LF'))
19    define('DOKU_LF', "\n");
20if (! defined('DOKU_TAB'))
21    define('DOKU_TAB', "\t");
22if (! defined('DOKU_PLUGIN'))
23    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
24
25require_once DOKU_PLUGIN . 'action.php';
26
27
28class action_plugin_authshibboleth extends DokuWiki_Action_Plugin
29{
30
31    const CONF_SHIBBOLETH_HANDLER_BASE = 'shibboleth_handler_base';
32
33    const CONF_LOGIN_HANDLER = 'login_handler';
34
35    const CONF_LOGIN_TARGET = 'login_target';
36
37    const CONF_LOGIN_HANDLER_LOCATION = 'login_handler_location';
38
39
40    public function register(Doku_Event_Handler &$controller)
41    {
42        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'redirectToLoginHandler');
43    }
44
45
46    public function redirectToLoginHandler($event, $param)
47    {
48        global $ACT;
49
50        if ('login' == $ACT) {
51            $loginHandlerLocation = $this->getConf(self::CONF_LOGIN_HANDLER_LOCATION);
52            if (! $loginHandlerLocation) {
53                $loginTarget = $this->getConf(self::CONF_LOGIN_TARGET);
54                if (! $loginTarget) {
55                    $loginTarget = $this->mkRefererUrl();
56                }
57
58                $loginHandlerLocation = $this->mkUrl($_SERVER['HTTP_HOST'], $this->mkShibHandler(), array(
59                    'target' => $loginTarget
60                ));
61            }
62
63            header("Location: " . $loginHandlerLocation);
64            exit();
65        }
66    }
67
68
69    protected function mkShibHandler()
70    {
71        return sprintf("%s%s", $this->getConf(self::CONF_SHIBBOLETH_HANDLER_BASE), $this->getConf(self::CONF_LOGIN_HANDLER));
72    }
73
74
75    protected function mkUrl($host, $path, $params = array(), $ssl = true)
76    {
77        return sprintf("%s://%s%s%s", $ssl ? 'https' : 'http', $host, $path, $this->mkQueryString($params));
78    }
79
80
81    protected function mkRefererUrl($ssl = true)
82    {
83        $urlParts = parse_url($_SERVER['HTTP_REFERER']);
84
85        $host = $urlParts['host'];
86        if ($urlParts['port'] && $urlParts['port'] != '80' && $urlParts['port'] != '443') {
87            $host .= ':' . $urlParts['port'];
88        }
89
90        $query = array();
91        parse_str($urlParts['query'], $query);
92
93        return $this->mkUrl($host, $urlParts['path'], $query, $ssl);
94    }
95
96
97    protected function mkQueryString($params = array())
98    {
99        if (empty($params)) {
100            return '';
101        }
102
103        $queryParams = array();
104        foreach ($params as $key => $value) {
105            $queryParams[] = sprintf("%s=%s", $key, urlencode($value));
106        }
107
108        return '?' . implode('amp;', $queryParams);
109    }
110}