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 */ 241e8dcca0SRobert Czechowski public function __construct() 251e8dcca0SRobert Czechowski { 261e8dcca0SRobert Czechowski parent::__construct(); 271e8dcca0SRobert 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 3448dffebbSRobert Czechowski $this->cando['logout'] = !empty($this->getConf('logoff_uri')); 352918a769SRobert Czechowski 362918a769SRobert Czechowski try { 372918a769SRobert Czechowski // Connecting, selecting database 3881c93b21SRobert Czechowski if ($this->getConf('protocol') == 'sqlite') { 3981c93b21SRobert Czechowski $this->dbh = new PDO('sqlite:' . $this->getConf('server')); 4053a02df5SRobert Czechowski } 4153a02df5SRobert Czechowski else { 4281c93b21SRobert Czechowski $this->dbh = new PDO($this->getConf('protocol') . ':host=' . $this->getConf('server') . ';dbname=' . $this->getConf('db'), $this->getConf('user'), $this->getConf('password')); 4353a02df5SRobert Czechowski } 442918a769SRobert Czechowski } catch (PDOException $e) { 452918a769SRobert Czechowski msg("Can not connect to database!", -1); 461e8dcca0SRobert Czechowski dbg($e); 472918a769SRobert Czechowski $this->success = false; 482918a769SRobert Czechowski } 492918a769SRobert Czechowski $this->success = true; 502918a769SRobert Czechowski } 512918a769SRobert Czechowski 52*b866db0fSzgtm 532918a769SRobert Czechowski function trustExternal($user,$pass,$sticky=false){ 542918a769SRobert Czechowski global $USERINFO; 552918a769SRobert Czechowski global $conf; 562918a769SRobert Czechowski global $dbh; 572918a769SRobert Czechowski 582918a769SRobert Czechowski $sticky ? $sticky = true : $sticky = false; //sanity check 592918a769SRobert Czechowski 602918a769SRobert Czechowski /** 612918a769SRobert Czechowski * Just checks against the django sessionid variable, 622918a769SRobert Czechowski * gets user info from django-database 632918a769SRobert Czechowski */ 641e8dcca0SRobert Czechowski 652918a769SRobert Czechowski if (isset($_COOKIE['sessionid']) && $this->dbh) { 662918a769SRobert Czechowski 672918a769SRobert Czechowski $s_id = $_COOKIE['sessionid']; 682918a769SRobert Czechowski 692918a769SRobert Czechowski // Look the cookie up in the db 702918a769SRobert Czechowski $query = 'SELECT session_data FROM django_session WHERE session_key=' . $this->dbh->quote($s_id) . ' LIMIT 1;'; 712918a769SRobert Czechowski $result = $this->dbh->query($query) or die('Query failed1: ' . $this->dbh->errorInfo()); 722918a769SRobert Czechowski $ar = $result->fetch(PDO::FETCH_ASSOC); 732918a769SRobert Czechowski $session_data = $ar['session_data']; 742918a769SRobert Czechowski 758375d074SRobert Czechowski // TODO: $session_data can now be empty if the session does not exist in database, handle correctly instead of just dying 768375d074SRobert Czechowski if (strlen($session_data) == 0) { 778375d074SRobert Czechowski return false; 788375d074SRobert Czechowski } 798375d074SRobert Czechowski 808375d074SRobert Czechowski $compressed = false; 818375d074SRobert Czechowski 828375d074SRobert Czechowski if (str_contains($session_data, ":")) { 838375d074SRobert Czechowski // New django session encoding since django 4 848375d074SRobert Czechowski if ($session_data[0] == '.') { 858375d074SRobert Czechowski $compressed = true; 868375d074SRobert Czechowski $session_data = substr($session_data, 1); 878375d074SRobert Czechowski } 888375d074SRobert Czechowski 898375d074SRobert Czechowski $session_json = base64_decode(strtr(preg_split('/:/', $session_data, 2)[0], "-_", "+/"), true); 908375d074SRobert Czechowski 918375d074SRobert Czechowski if ($compressed) { 928375d074SRobert Czechowski $session_json = zlib_decode($session_json); 938375d074SRobert Czechowski } 948375d074SRobert Czechowski 958375d074SRobert Czechowski } else { 968375d074SRobert Czechowski // Old django session enconding until django 3 978375d074SRobert Czechowski // Decoding the session data: 988375d074SRobert Czechowski 992918a769SRobert Czechowski $session_json = preg_split('/:/', base64_decode($session_data), 2)[1]; 1008375d074SRobert Czechowski } 1012918a769SRobert Czechowski $userid = json_decode($session_json, true)['_auth_user_id']; 10279dc6f2bSRobert Czechowski $query2 = 'SELECT username, first_name, last_name, email, is_superuser, is_staff FROM auth_user WHERE id=' . $this->dbh->quote($userid) . ' LIMIT 1;'; 1032918a769SRobert Czechowski 1042918a769SRobert Czechowski $result2 = $this->dbh->query($query2) or die('Query failed2: ' . print_r($this->dbh->errorInfo())); 1052918a769SRobert Czechowski $user = $result2->fetch(PDO::FETCH_ASSOC); 1062918a769SRobert Czechowski 1072918a769SRobert Czechowski $username = $user['username']; 1082918a769SRobert Czechowski $userfullname = $user['first_name'] . " " . $user['last_name']; 1092918a769SRobert Czechowski $useremail = $user['email']; 1102918a769SRobert Czechowski 1112918a769SRobert Czechowski // okay we're logged in - set the globals 1122918a769SRobert Czechowski $groups = $this->_getUserGroups($username); 1132918a769SRobert Czechowski 1142918a769SRobert Czechowski $USERINFO['name'] = $username; 1152918a769SRobert Czechowski $USERINFO['pass'] = ''; 1162918a769SRobert Czechowski $USERINFO['mail'] = $useremail; 1174abf80ebSRobert Czechowski 1184abf80ebSRobert Czechowski if (($user['is_superuser'] && $this->getConf('admin_admin') == 1) 1194abf80ebSRobert Czechowski || ($user['is_staff'] && $this->getConf('staff_admin') == 1)) 1204abf80ebSRobert Czechowski { 1214abf80ebSRobert Czechowski $groups[] = 'admin'; 122*b866db0fSzgtm } else { 123*b866db0fSzgtm foreach ($this->getConf('groups_admin') as $admin_group) { 124*b866db0fSzgtm foreach ($groups as $group) { 125*b866db0fSzgtm if ($group == $admin_group && $group != "") { 126*b866db0fSzgtm $groups[] = 'admin'; 127*b866db0fSzgtm break 2; // break both for loops 128*b866db0fSzgtm } 129*b866db0fSzgtm } 130*b866db0fSzgtm } 1314abf80ebSRobert Czechowski } 1322918a769SRobert Czechowski $USERINFO['grps'] = $groups; 1332918a769SRobert Czechowski 1342918a769SRobert Czechowski $_SERVER['REMOTE_USER'] = $username; 1352918a769SRobert Czechowski 1362918a769SRobert Czechowski $_SESSION[DOKU_COOKIE]['auth']['user'] = $username; 1372918a769SRobert Czechowski $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 1382918a769SRobert Czechowski 1392918a769SRobert Czechowski return true; 1402918a769SRobert Czechowski } 1412918a769SRobert Czechowski return false; 1422918a769SRobert Czechowski } 1432918a769SRobert Czechowski 1442918a769SRobert Czechowski function _getUserGroups($user){ 1452918a769SRobert 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;'; 1462918a769SRobert Czechowski 1472918a769SRobert Czechowski $result = $this->dbh->query($query) or die('Query failed3: ' . $this->dbh->errorInfo()); 1484abf80ebSRobert Czechowski 1494abf80ebSRobert Czechowski $groups = []; 1502918a769SRobert Czechowski foreach ($result as $row) { 1514abf80ebSRobert Czechowski $groups[] = $row[0]; 1522918a769SRobert Czechowski }; 1532918a769SRobert Czechowski 1544abf80ebSRobert Czechowski if (!in_array("user", $groups)) { 1554abf80ebSRobert Czechowski $groups[] = "user"; 1564abf80ebSRobert Czechowski } 1574abf80ebSRobert Czechowski 1582918a769SRobert Czechowski return $groups; 1592918a769SRobert Czechowski } 1602918a769SRobert Czechowski 161*b866db0fSzgtm 1622918a769SRobert Czechowski function retrieveGroups($start=0,$limit=0){ 1632918a769SRobert Czechowski $query = 'SELECT auth_group.name FROM auth_group'; 1642918a769SRobert Czechowski 1652918a769SRobert Czechowski $result = $this->dbh->query($query) or die('Query failed4: ' . $this->dbh->errorInfo()); 1664abf80ebSRobert Czechowski 1674abf80ebSRobert Czechowski $groups = []; 1682918a769SRobert Czechowski foreach ($result as $row) { 1694abf80ebSRobert Czechowski $groups[] = $row[0]; 1702918a769SRobert Czechowski }; 1712918a769SRobert Czechowski 1724abf80ebSRobert Czechowski if (!in_array("user", $groups)) { 1734abf80ebSRobert Czechowski $groups[] = "user"; 1744abf80ebSRobert Czechowski } 1754abf80ebSRobert Czechowski 1764abf80ebSRobert Czechowski if (!in_array("admin", $groups)) { 1774abf80ebSRobert Czechowski $groups[] = "admin"; 1784abf80ebSRobert Czechowski } 1794abf80ebSRobert Czechowski 1802918a769SRobert Czechowski return $groups; 1812918a769SRobert Czechowski } 1822918a769SRobert Czechowski 183*b866db0fSzgtm 184557e3fdcSRobert Czechowski function logOff() { 185557e3fdcSRobert Czechowski header("Location: " . $this->getConf('logoff_uri')); 186557e3fdcSRobert Czechowski die(); 187557e3fdcSRobert Czechowski } 188557e3fdcSRobert Czechowski 189557e3fdcSRobert Czechowski 1902918a769SRobert Czechowski function __destruct() { 1912918a769SRobert Czechowski $this->dbh = null; 1922918a769SRobert Czechowski } 1932918a769SRobert Czechowski} 194