1<?php 2/** 3 * django auth backend 4 * 5 * @author Andreas Gohr <andi@splitbrain.org> 6 * @author Michael Luggen <michael.luggen at unifr.ch> 7 * @author Robert Czechowski <zgtm at zgtm.de> 8 */ 9 10define('DOKU_AUTH', dirname(__FILE__)); 11define('AUTH_USERFILE',DOKU_CONF.'users.auth.php'); 12 13class auth_plugin_authdjango extends DokuWiki_Auth_Plugin { 14 15 var $dbh = null; // db handle 16 17 /** 18 * Constructor. 19 * 20 * Sets additional capabilities and config strings 21 * @author Michael Luggen <michael.luggen at rhone.ch> 22 * @author Robert Czechowski <zgtm at zgtm.de> 23 */ 24 public function __construct() 25 { 26 parent::__construct(); 27 28 global $config_cascade; 29 global $dbh; 30 31 $this->cando['external'] = true; 32 $this->cando['getGroups'] = true; 33 34 $this->cando['logout'] = !empty($this->getConf('logoff_uri')); 35 36 try { 37 // Connecting, selecting database 38 if ($this->getConf('protocol') == 'sqlite') { 39 $this->dbh = new PDO('sqlite:' . $this->getConf('server')); 40 } 41 else { 42 $this->dbh = new PDO($this->getConf('protocol') . ':host=' . $this->getConf('server') . ';dbname=' . $this->getConf('db'), $this->getConf('user'), $this->getConf('password')); 43 } 44 } catch (PDOException $e) { 45 msg("Can not connect to database!", -1); 46 dbg($e); 47 $this->success = false; 48 } 49 $this->success = true; 50 } 51 52 53 function trustExternal($user,$pass,$sticky=false){ 54 global $USERINFO; 55 global $conf; 56 global $dbh; 57 58 $sticky ? $sticky = true : $sticky = false; //sanity check 59 60 /** 61 * Just checks against the django sessionid variable, 62 * gets user info from django-database 63 */ 64 65 if (isset($_COOKIE['sessionid']) && $this->dbh) { 66 67 $s_id = $_COOKIE['sessionid']; 68 69 // Look the cookie up in the db 70 $query = 'SELECT session_data FROM django_session WHERE session_key=' . $this->dbh->quote($s_id) . ' LIMIT 1;'; 71 $result = $this->dbh->query($query) or die('Query failed1: ' . $this->dbh->errorInfo()); 72 $ar = $result->fetch(PDO::FETCH_ASSOC); 73 $session_data = $ar['session_data']; 74 75 // TODO: $session_data can now be empty if the session does not exist in database, handle correctly instead of just dying 76 if (strlen($session_data) == 0) { 77 return false; 78 } 79 80 $compressed = false; 81 82 if (str_contains($session_data, ":")) { 83 // New django session encoding since django 4 84 if ($session_data[0] == '.') { 85 $compressed = true; 86 $session_data = substr($session_data, 1); 87 } 88 89 $session_json = base64_decode(strtr(preg_split('/:/', $session_data, 2)[0], "-_", "+/"), true); 90 91 if ($compressed) { 92 $session_json = zlib_decode($session_json); 93 } 94 95 } else { 96 // Old django session enconding until django 3 97 // Decoding the session data: 98 99 $session_json = preg_split('/:/', base64_decode($session_data), 2)[1]; 100 } 101 $userid = json_decode($session_json, true)['_auth_user_id']; 102 $query2 = 'SELECT username, first_name, last_name, email, is_superuser, is_staff FROM auth_user WHERE id=' . $this->dbh->quote($userid) . ' LIMIT 1;'; 103 104 $result2 = $this->dbh->query($query2) or die('Query failed2: ' . print_r($this->dbh->errorInfo())); 105 $user = $result2->fetch(PDO::FETCH_ASSOC); 106 107 $username = $user['username']; 108 $userfullname = $user['first_name'] . " " . $user['last_name']; 109 $useremail = $user['email']; 110 111 // okay we're logged in - set the globals 112 $groups = $this->_getUserGroups($username); 113 114 $USERINFO['name'] = $username; 115 $USERINFO['pass'] = ''; 116 $USERINFO['mail'] = $useremail; 117 118 if (($user['is_superuser'] && $this->getConf('admin_admin') == 1) 119 || ($user['is_staff'] && $this->getConf('staff_admin') == 1)) 120 { 121 $groups[] = 'admin'; 122 } else { 123 foreach ($this->getConf('groups_admin') as $admin_group) { 124 foreach ($groups as $group) { 125 if ($group == $admin_group && $group != "") { 126 $groups[] = 'admin'; 127 break 2; // break both for loops 128 } 129 } 130 } 131 } 132 $USERINFO['grps'] = $groups; 133 134 $_SERVER['REMOTE_USER'] = $username; 135 136 $_SESSION[DOKU_COOKIE]['auth']['user'] = $username; 137 $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 138 139 return true; 140 } 141 return false; 142 } 143 144 function _getUserGroups($user){ 145 $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;'; 146 147 $result = $this->dbh->query($query) or die('Query failed3: ' . $this->dbh->errorInfo()); 148 149 $groups = []; 150 foreach ($result as $row) { 151 $groups[] = $row[0]; 152 }; 153 154 if (!in_array("user", $groups)) { 155 $groups[] = "user"; 156 } 157 158 return $groups; 159 } 160 161 162 function retrieveGroups($start=0,$limit=0){ 163 $query = 'SELECT auth_group.name FROM auth_group'; 164 165 $result = $this->dbh->query($query) or die('Query failed4: ' . $this->dbh->errorInfo()); 166 167 $groups = []; 168 foreach ($result as $row) { 169 $groups[] = $row[0]; 170 }; 171 172 if (!in_array("user", $groups)) { 173 $groups[] = "user"; 174 } 175 176 if (!in_array("admin", $groups)) { 177 $groups[] = "admin"; 178 } 179 180 return $groups; 181 } 182 183 184 function logOff() { 185 header("Location: " . $this->getConf('logoff_uri')); 186 die(); 187 } 188 189 190 function __destruct() { 191 $this->dbh = null; 192 } 193} 194