xref: /plugin/authdjango/auth.php (revision 1e8dcca0d9d2cea8d6afede29685d62a7ebf1993)
12918a769SRobert Czechowski<?php
22918a769SRobert Czechowski/**
32918a769SRobert Czechowski * django auth backend
42918a769SRobert Czechowski *
52918a769SRobert Czechowski * @author    Andreas Gohr <andi@splitbrain.org>
62918a769SRobert Czechowski * @author    Michael Luggen <michael.luggen at unifr.ch>
72918a769SRobert Czechowski * @author    Robert Czechowski <zgtm at zgtm.de>
82918a769SRobert Czechowski */
92918a769SRobert Czechowski
102918a769SRobert Czechowskidefine('DOKU_AUTH', dirname(__FILE__));
112918a769SRobert Czechowskidefine('AUTH_USERFILE',DOKU_CONF.'users.auth.php');
122918a769SRobert Czechowski
132918a769SRobert Czechowskiclass auth_plugin_authdjango extends DokuWiki_Auth_Plugin  {
142918a769SRobert Czechowski
152918a769SRobert Czechowski    var $dbh = null; // db handle
162918a769SRobert Czechowski
172918a769SRobert Czechowski    /**
182918a769SRobert Czechowski     * Constructor.
192918a769SRobert Czechowski     *
202918a769SRobert Czechowski     * Sets additional capabilities and config strings
212918a769SRobert Czechowski     * @author    Michael Luggen <michael.luggen at rhone.ch>
222918a769SRobert Czechowski     * @author    Robert Czechowski <zgtm at zgtm.de>
232918a769SRobert Czechowski     */
24*1e8dcca0SRobert Czechowski    public function __construct()
25*1e8dcca0SRobert Czechowski    {
26*1e8dcca0SRobert Czechowski        parent::__construct();
27*1e8dcca0SRobert Czechowski
282918a769SRobert Czechowski        global $config_cascade;
292918a769SRobert Czechowski        global $dbh;
302918a769SRobert Czechowski
312918a769SRobert Czechowski        $this->cando['external'] = true;
322918a769SRobert Czechowski        $this->cando['getGroups'] = true;
33557e3fdcSRobert Czechowski
34557e3fdcSRobert Czechowski        if (!empty($this->getConf('logoff_uri'))) {
35557e3fdcSRobert Czechowski            $this->cando['logout'] = true;
36557e3fdcSRobert Czechowski        }
372918a769SRobert Czechowski
382918a769SRobert Czechowski        try {
392918a769SRobert Czechowski            // Connecting, selecting database
4081c93b21SRobert Czechowski            if ($this->getConf('protocol') == 'sqlite') {
4181c93b21SRobert Czechowski                $this->dbh = new PDO('sqlite:' . $this->getConf('server'));
4253a02df5SRobert Czechowski            }
4353a02df5SRobert Czechowski            else {
4481c93b21SRobert Czechowski                $this->dbh = new PDO($this->getConf('protocol') . ':host=' . $this->getConf('server') . ';dbname=' . $this->getConf('db'), $this->getConf('user'), $this->getConf('password'));
4553a02df5SRobert Czechowski            }
462918a769SRobert Czechowski        } catch (PDOException $e) {
472918a769SRobert Czechowski            msg("Can not connect to database!", -1);
48*1e8dcca0SRobert Czechowski            dbg($e);
492918a769SRobert Czechowski            $this->success = false;
502918a769SRobert Czechowski        }
512918a769SRobert Czechowski        $this->success = true;
522918a769SRobert Czechowski    }
532918a769SRobert Czechowski
542918a769SRobert Czechowski    function trustExternal($user,$pass,$sticky=false){
552918a769SRobert Czechowski        global $USERINFO;
562918a769SRobert Czechowski        global $conf;
572918a769SRobert Czechowski        global $dbh;
582918a769SRobert Czechowski
592918a769SRobert Czechowski        $sticky ? $sticky = true : $sticky = false; //sanity check
602918a769SRobert Czechowski
612918a769SRobert Czechowski        /**
622918a769SRobert Czechowski         * Just checks against the django sessionid variable,
632918a769SRobert Czechowski         * gets user info from django-database
642918a769SRobert Czechowski         */
65*1e8dcca0SRobert Czechowski
662918a769SRobert Czechowski        if (isset($_COOKIE['sessionid']) && $this->dbh) {
672918a769SRobert Czechowski
682918a769SRobert Czechowski            $s_id =  $_COOKIE['sessionid'];
692918a769SRobert Czechowski
702918a769SRobert Czechowski            // Look the cookie up in the db
712918a769SRobert Czechowski            $query = 'SELECT session_data FROM django_session WHERE session_key=' . $this->dbh->quote($s_id) . ' LIMIT 1;';
722918a769SRobert Czechowski            $result = $this->dbh->query($query) or die('Query failed1: ' . $this->dbh->errorInfo());
732918a769SRobert Czechowski            $ar = $result->fetch(PDO::FETCH_ASSOC);
742918a769SRobert Czechowski            $session_data = $ar['session_data'];
752918a769SRobert Czechowski
768375d074SRobert Czechowski            // TODO: $session_data can now be empty if the session does not exist in database, handle correctly instead of just dying
778375d074SRobert Czechowski            if (strlen($session_data) == 0) {
788375d074SRobert Czechowski                return false;
798375d074SRobert Czechowski            }
808375d074SRobert Czechowski
818375d074SRobert Czechowski            $compressed = false;
828375d074SRobert Czechowski
838375d074SRobert Czechowski            if (str_contains($session_data, ":")) {
848375d074SRobert Czechowski                // New django session encoding since django 4
858375d074SRobert Czechowski                if ($session_data[0] == '.') {
868375d074SRobert Czechowski                    $compressed = true;
878375d074SRobert Czechowski                    $session_data = substr($session_data, 1);
888375d074SRobert Czechowski                }
898375d074SRobert Czechowski
908375d074SRobert Czechowski                $session_json = base64_decode(strtr(preg_split('/:/', $session_data, 2)[0], "-_", "+/"), true);
918375d074SRobert Czechowski
928375d074SRobert Czechowski                if ($compressed) {
938375d074SRobert Czechowski                       $session_json = zlib_decode($session_json);
948375d074SRobert Czechowski                }
958375d074SRobert Czechowski
968375d074SRobert Czechowski            } else {
978375d074SRobert Czechowski                // Old django session enconding until django 3
988375d074SRobert Czechowski                // Decoding the session data:
998375d074SRobert Czechowski
1002918a769SRobert Czechowski                $session_json = preg_split('/:/', base64_decode($session_data), 2)[1];
1018375d074SRobert Czechowski            }
1022918a769SRobert Czechowski            $userid = json_decode($session_json, true)['_auth_user_id'];
1034abf80ebSRobert Czechowski            $query2 = 'SELECT username, first_name, last_name, email is_superuser, is_staff FROM auth_user WHERE id=' . $this->dbh->quote($userid) . ' LIMIT 1;';
1042918a769SRobert Czechowski
1052918a769SRobert Czechowski            $result2 = $this->dbh->query($query2) or die('Query failed2: ' . print_r($this->dbh->errorInfo()));
1062918a769SRobert Czechowski            $user = $result2->fetch(PDO::FETCH_ASSOC);
1072918a769SRobert Czechowski
1082918a769SRobert Czechowski            $username =  $user['username'];
1092918a769SRobert Czechowski            $userfullname = $user['first_name'] . " " . $user['last_name'];
1102918a769SRobert Czechowski            $useremail = $user['email'];
1112918a769SRobert Czechowski
1122918a769SRobert Czechowski            // okay we're logged in - set the globals
1132918a769SRobert Czechowski            $groups = $this->_getUserGroups($username);
1142918a769SRobert Czechowski
1152918a769SRobert Czechowski            $USERINFO['name'] = $username;
1162918a769SRobert Czechowski            $USERINFO['pass'] = '';
1172918a769SRobert Czechowski            $USERINFO['mail'] = $useremail;
1184abf80ebSRobert Czechowski
1194abf80ebSRobert Czechowski            if (($user['is_superuser'] && $this->getConf('admin_admin') == 1)
1204abf80ebSRobert Czechowski                || ($user['is_staff'] && $this->getConf('staff_admin') == 1))
1214abf80ebSRobert Czechowski            {
1224abf80ebSRobert Czechowski                $groups[] = 'admin';
1234abf80ebSRobert Czechowski            }
1242918a769SRobert Czechowski            $USERINFO['grps'] = $groups;
1252918a769SRobert Czechowski
1262918a769SRobert Czechowski            $_SERVER['REMOTE_USER'] = $username;
1272918a769SRobert Czechowski
1282918a769SRobert Czechowski            $_SESSION[DOKU_COOKIE]['auth']['user'] = $username;
1292918a769SRobert Czechowski            $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
1302918a769SRobert Czechowski
1312918a769SRobert Czechowski            return true;
1322918a769SRobert Czechowski        }
1332918a769SRobert Czechowski        return false;
1342918a769SRobert Czechowski    }
1352918a769SRobert Czechowski
1362918a769SRobert Czechowski    function _getUserGroups($user){
1372918a769SRobert Czechowski        $query = 'SELECT auth_group.name FROM auth_user, auth_user_groups, auth_group where auth_user.username = ' . $this->dbh->quote($user) . ' AND auth_user.id = auth_user_groups.user_id AND auth_user_groups.group_id = auth_group.id;';
1382918a769SRobert Czechowski
1392918a769SRobert Czechowski        $result = $this->dbh->query($query) or die('Query failed3: ' . $this->dbh->errorInfo());
1404abf80ebSRobert Czechowski
1414abf80ebSRobert Czechowski        $groups = [];
1422918a769SRobert Czechowski        foreach ($result as $row) {
1434abf80ebSRobert Czechowski            $groups[] = $row[0];
1442918a769SRobert Czechowski        };
1452918a769SRobert Czechowski
1464abf80ebSRobert Czechowski        if (!in_array("user", $groups)) {
1474abf80ebSRobert Czechowski            $groups[] = "user";
1484abf80ebSRobert Czechowski        }
1494abf80ebSRobert Czechowski
1502918a769SRobert Czechowski        return $groups;
1512918a769SRobert Czechowski    }
1522918a769SRobert Czechowski
1532918a769SRobert Czechowski    function retrieveGroups($start=0,$limit=0){
1542918a769SRobert Czechowski        $query = 'SELECT auth_group.name FROM auth_group';
1552918a769SRobert Czechowski
1562918a769SRobert Czechowski        $result = $this->dbh->query($query) or die('Query failed4: ' . $this->dbh->errorInfo());
1574abf80ebSRobert Czechowski
1584abf80ebSRobert Czechowski        $groups = [];
1592918a769SRobert Czechowski        foreach ($result as $row) {
1604abf80ebSRobert Czechowski            $groups[] = $row[0];
1612918a769SRobert Czechowski        };
1622918a769SRobert Czechowski
1634abf80ebSRobert Czechowski        if (!in_array("user", $groups)) {
1644abf80ebSRobert Czechowski            $groups[] = "user";
1654abf80ebSRobert Czechowski        }
1664abf80ebSRobert Czechowski
1674abf80ebSRobert Czechowski        if (!in_array("admin", $groups)) {
1684abf80ebSRobert Czechowski            $groups[] = "admin";
1694abf80ebSRobert Czechowski        }
1704abf80ebSRobert Czechowski
1712918a769SRobert Czechowski        return $groups;
1722918a769SRobert Czechowski    }
1732918a769SRobert Czechowski
174557e3fdcSRobert Czechowski    function logOff() {
175557e3fdcSRobert Czechowski        header("Location: " . $this->getConf('logoff_uri'));
176557e3fdcSRobert Czechowski        die();
177557e3fdcSRobert Czechowski    }
178557e3fdcSRobert Czechowski
179557e3fdcSRobert Czechowski
1802918a769SRobert Czechowski    function __destruct() {
1812918a769SRobert Czechowski        $this->dbh = null;
1822918a769SRobert Czechowski    }
1832918a769SRobert Czechowski}
184