1<?php
2/**
3 * DokuWiki Plugin authjoomla (Auth Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <dokuwiki@cosmocode.de>
7 */
8
9/**
10 * Class auth_plugin_authjoomla
11 *
12 */
13class auth_plugin_authjoomla extends auth_plugin_authpdo
14{
15
16    /** @inheritdoc */
17    public function __construct()
18    {
19        $this->initializeConfiguration();
20        parent::__construct(); // PDO setup
21        $this->ssoByCookie();
22    }
23
24    /** @inheritdoc */
25    public function checkPass($user, $pass)
26    {
27        // username already set by SSO
28        if ($_SERVER['REMOTE_USER'] &&
29            $_SERVER['REMOTE_USER'] == $user &&
30            !empty($this->getConf('cookiename'))
31        ) return true;
32
33        return parent::checkPass($user, $pass);
34    }
35
36    /**
37     * Check if Joomla Cookies exist and use them to auto login
38     */
39    protected function ssoByCookie()
40    {
41        global $INPUT;
42
43        if (!empty($_COOKIE[DOKU_COOKIE])) return; // DokuWiki auth cookie found
44        if (empty($_COOKIE['joomla_user_state'])) return;
45        if ($_COOKIE['joomla_user_state'] !== 'logged_in') return;
46        if (empty($this->getConf('cookiename'))) return;
47        if (empty($_COOKIE[$this->getConf('cookiename')])) return;
48
49        // check session in Joomla DB
50        $session = $_COOKIE[$this->getConf('cookiename')];
51        $sql = $this->getConf('select-session');
52        $result = $this->_query($sql, ['session' => $session]);
53        if ($result === false) return;
54
55        // force login
56        $_SERVER['REMOTE_USER'] = $result[0]['user'];
57        $INPUT->set('u', $_SERVER['REMOTE_USER']);
58        $INPUT->set('p', 'sso_only');
59    }
60
61    /**
62     * Remove the joomla cookie
63     */
64    public function logOff()
65    {
66        parent::logOff();
67        setcookie('joomla_user_state', '', time() - 3600, '/');
68    }
69
70    /**
71     * Initialize database configuration
72     */
73    protected function initializeConfiguration()
74    {
75        $prefix = $this->getConf('tableprefix');
76
77        /** @noinspection SqlNoDataSourceInspection */
78        /** @noinspection SqlResolve */
79        $this->conf['select-user'] = '
80            SELECT `id` AS `uid`,
81                   `username` AS `user`,
82                   `name` AS `name`,
83                   `password` AS `hash`,
84                   `email` AS `mail`
85              FROM `' . $prefix . 'users`
86             WHERE `username` = :user
87               AND `block` = 0
88               AND `activation` = 0
89        ';
90
91        /** @noinspection SqlNoDataSourceInspection */
92        /** @noinspection SqlResolve */
93        $this->conf['select-user-groups'] = '
94            SELECT
95              p.id AS `gid`,
96              (
97                SELECT GROUP_CONCAT(xp.`title` ORDER BY xp.`lft` SEPARATOR \'/\')
98                  FROM `' . $prefix . 'usergroups` AS xp
99                WHERE p.`lft` BETWEEN xp.`lft` AND xp.`rgt`
100              ) AS `group`
101              FROM `' . $prefix . 'user_usergroup_map` AS m,
102                   `' . $prefix . 'usergroups` AS g,
103                   `' . $prefix . 'usergroups` AS p
104             WHERE m.`user_id`  = :uid
105               AND g.`id` = m.`group_id`
106               AND p.`lft` <= g.`lft`
107               AND p.`rgt` >= g.`rgt`
108        ';
109
110        /** @noinspection SqlNoDataSourceInspection */
111        /** @noinspection SqlResolve */
112        $this->conf['select-groups'] = '
113            SELECT n.id AS `gid`, GROUP_CONCAT(p.`title` ORDER BY p.lft SEPARATOR \'/\') as `group`
114              FROM `' . $prefix . 'usergroups` AS n, `' . $prefix . 'usergroups` AS p
115             WHERE n.lft BETWEEN p.lft AND p.rgt
116          GROUP BY n.id
117          ORDER BY n.id
118        ';
119
120        /** @noinspection SqlNoDataSourceInspection */
121        /** @noinspection SqlResolve */
122        $this->conf['select-session'] = '
123            SELECT s.`username` as `user`
124              FROM `' . $prefix . 'session` AS s,
125                   `' . $prefix . 'users` AS u
126             WHERE s.`session_id` = :session
127               AND s.`userid` = u.`id`
128               AND `block` = 0
129               AND `activation` = 0
130        ';
131    }
132
133    /**
134     * Sets up the language strings
135     *
136     * Needed to inherit from the parent class. It's abit ugly but currently no better way exists.
137     */
138    public function setupLocale()
139    {
140        if ($this->localised) return;
141        global $conf;
142
143        // load authpdo language files
144        /** @var array $lang is loaded by include */
145        $path = DOKU_PLUGIN . 'authpdo/lang/';
146        @include($path . 'en/lang.php');
147        if ($conf['lang'] != 'en') @include($path . $conf['lang'] . '/lang.php');
148        $pdolang = $lang;
149
150        // load our authloomla language files and config overrides
151        parent::setupLocale();
152
153        // merge them both
154        $this->lang = array_merge($this->lang, $pdolang);
155    }
156
157    /** @inheritdoc */
158    public function isCaseSensitive()
159    {
160        return false;
161    }
162
163
164}
165
166// vim:ts=4:sw=4:et:
167