1<?php 2/** 3 * DokuWiki Plugin oauth (Auth Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class auth_plugin_oauth extends auth_plugin_authplain { 13 14 /** 15 * Constructor 16 * 17 * Sets capabilities. 18 */ 19 public function __construct() { 20 parent::__construct(); 21 22 $this->cando['external'] = true; 23 } 24 25 /** 26 * Handle the login 27 * 28 * This either trusts the session data (if any), processes the second oAuth step or simply 29 * executes a normal plugin against local users. 30 * 31 * @param string $user 32 * @param string $pass 33 * @param bool $sticky 34 * @return bool 35 */ 36 function trustExternal($user, $pass, $sticky = false) { 37 global $INPUT; 38 global $conf; 39 global $USERINFO; 40 41 $servicename = $INPUT->str('oa'); 42 43 // check session for existing oAuth login data 44 $session = $_SESSION[DOKU_COOKIE]['auth']; 45 if(!$servicename && isset($session['oauth'])) { 46 $servicename = $session['oauth']; 47 // check if session data is still considered valid 48 if(($session['time'] >= time() - $conf['auth_security_timeout']) && 49 ($session['buid'] == auth_browseruid()) 50 ) { 51 52 $_SERVER['REMOTE_USER'] = $session['user']; 53 $USERINFO = $session['info']; 54 return true; 55 } 56 } 57 58 // either we're in oauth login or a previous log needs to be rechecked 59 if($servicename) { 60 /** @var helper_plugin_oauth $hlp */ 61 $hlp = plugin_load('helper', 'oauth'); 62 $service = $hlp->loadService($servicename); 63 if(is_null($service)) return false; 64 65 // get the token 66 if($service->checkToken()) { 67 $uinfo = $service->getUser(); 68 69 // see if the user is known already 70 $user = $this->getUserByEmail($uinfo['mail']); 71 if($user) { 72 $sinfo = $this->getUserData($user); 73 $uinfo['user'] = $user; 74 $uinfo['name'] = $sinfo['name']; 75 $uinfo['grps'] = array_merge((array) $uinfo['grps'], $sinfo['grps']); 76 } else { 77 // new user, create him - making sure the login is unique by adding a number if needed 78 $user = $uinfo['user']; 79 $count = ''; 80 while($this->getUserData($user.$count)) { 81 if($count) { 82 $count++; 83 } else { 84 $count = 1; 85 } 86 } 87 $user = $user.$count; 88 $uinfo['user'] = $user; 89 $uinfo['grps'] = (array) $uinfo['grps']; 90 $uinfo['grps'][] = $conf['defaultgroup']; 91 92 $this->createUser($user, auth_pwgen($user), $uinfo['name'], $uinfo['mail'], $uinfo['grps']); 93 } 94 95 // set user session 96 $this->setUserSession($uinfo, $servicename); 97 return true; 98 } 99 100 return false; // something went wrong during oAuth login 101 } 102 103 // do the "normal" plain auth login via form 104 return auth_login($user, $pass, $sticky); 105 } 106 107 /** 108 * @param array $data 109 * @param string $service 110 */ 111 protected function setUserSession($data, $service) { 112 global $USERINFO; 113 global $conf; 114 115 // set up groups 116 if(!is_array($data['grps'])) { 117 $data['grps'] = array(); 118 } 119 $data['grps'][] = $this->cleanGroup($service); 120 $data['grps'] = array_unique($data['grps']); 121 122 $USERINFO = $data; 123 $_SERVER['REMOTE_USER'] = $data['user']; 124 $_SESSION[DOKU_COOKIE]['auth']['user'] = $data['user']; 125 $_SESSION[DOKU_COOKIE]['auth']['pass'] = $data['pass']; 126 $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 127 $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); 128 $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); 129 $_SESSION[DOKU_COOKIE]['auth']['oauth'] = $service; 130 } 131 132 /** 133 * Find a user by his email address 134 * 135 * @param $mail 136 * @return bool|string 137 */ 138 protected function getUserByEmail($mail) { 139 if($this->users === null) $this->_loadUserData(); 140 $mail = strtolower($mail); 141 142 foreach($this->users as $user => $uinfo) { 143 if(strtolower($uinfo['mail']) == $mail) return $user; 144 } 145 146 return false; 147 } 148 149 /** 150 * Enhance function to check aainst duplicate emails 151 * 152 * @param string $user 153 * @param string $pwd 154 * @param string $name 155 * @param string $mail 156 * @param null $grps 157 * @return bool|null|string 158 */ 159 public function createUser($user, $pwd, $name, $mail, $grps = null) { 160 if($this->getUserByEmail($mail)) { 161 msg($this->getLang('emailduplicate'), -1); 162 return false; 163 } 164 165 return parent::createUser($user, $pwd, $name, $mail, $grps); 166 } 167 168 /** 169 * Enhance function to check aainst duplicate emails 170 * 171 * @param string $user 172 * @param array $changes 173 * @return bool 174 */ 175 public function modifyUser($user, $changes) { 176 if(isset($changes['mail']) && $this->getUserByEmail($changes['mail'])) { 177 msg($this->getLang('emailduplicate'), -1); 178 return false; 179 } 180 181 return parent::modifyUser($user, $changes); 182 } 183 184} 185 186// vim:ts=4:sw=4:et: