180852c15SAndreas Gohr<?php 23e7ac5b1SAndreas Gohr 3*b8ca6a42SAnna Dabrowskause dokuwiki\plugin\oauth\SessionManager; 4*b8ca6a42SAnna Dabrowska 580852c15SAndreas Gohr/** 680852c15SAndreas Gohr * DokuWiki Plugin oauth (Auth Component) 780852c15SAndreas Gohr * 880852c15SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 980852c15SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1080852c15SAndreas Gohr */ 113e7ac5b1SAndreas Gohrclass auth_plugin_oauth extends auth_plugin_authplain 123e7ac5b1SAndreas Gohr{ 1380852c15SAndreas Gohr 143e7ac5b1SAndreas Gohr /** @inheritDoc */ 153e7ac5b1SAndreas Gohr public function __construct() 163e7ac5b1SAndreas Gohr { 17f10e09e2SAndreas Gohr parent::__construct(); 1880852c15SAndreas Gohr 19f10e09e2SAndreas Gohr $this->cando['external'] = true; 2080852c15SAndreas Gohr } 2180852c15SAndreas Gohr 223e7ac5b1SAndreas Gohr /** @inheritDoc */ 23311a6606SAnna Dabrowska public function trustExternal($user, $pass, $sticky = false) 243e7ac5b1SAndreas Gohr { 25a02a5d81SAnna Dabrowska global $INPUT; 26438dcc52SMichael Grosse 27*b8ca6a42SAnna Dabrowska // handle redirects from farmer to animal wiki instances 28438dcc52SMichael Grosse if ($INPUT->has('state') && plugin_load('helper', 'farmer', false, true)) { 29438dcc52SMichael Grosse $this->handleState($INPUT->str('state')); 30438dcc52SMichael Grosse } 3180852c15SAndreas Gohr 32*b8ca6a42SAnna Dabrowska // first check in auth setup: is auth data present and still valid? 33a02a5d81SAnna Dabrowska if ($this->sessionLogin()) return true; 3480852c15SAndreas Gohr 35*b8ca6a42SAnna Dabrowska // if we have a service in session, either we're in oauth login or a previous login needs to be revalidated 36*b8ca6a42SAnna Dabrowska $servicename = SessionManager::getServiceName(); 37*b8ca6a42SAnna Dabrowska if ($servicename) { 38*b8ca6a42SAnna Dabrowska return $this->serviceLogin($servicename, 39*b8ca6a42SAnna Dabrowska $sticky, 40*b8ca6a42SAnna Dabrowska SessionManager::getPid(), 41*b8ca6a42SAnna Dabrowska SessionManager::getParams(), 42*b8ca6a42SAnna Dabrowska SessionManager::hasState() 43*b8ca6a42SAnna Dabrowska ); 44a7a8f46aSAndreas Gohr } 45a7a8f46aSAndreas Gohr 46a02a5d81SAnna Dabrowska // otherwise try cookie 47a02a5d81SAnna Dabrowska $this->cookieLogin(); 4880852c15SAndreas Gohr 49a7a8f46aSAndreas Gohr // do the "normal" plain auth login via form 50a7a8f46aSAndreas Gohr return auth_login($user, $pass, $sticky); 51a7a8f46aSAndreas Gohr } 5280852c15SAndreas Gohr 53f2e164b0SMichael Große /** 54311a6606SAnna Dabrowska * Enhance function to check against duplicate emails 55311a6606SAnna Dabrowska * 56311a6606SAnna Dabrowska * @param string $user 57311a6606SAnna Dabrowska * @param string $pwd 58311a6606SAnna Dabrowska * @param string $name 59311a6606SAnna Dabrowska * @param string $mail 60311a6606SAnna Dabrowska * @param null $grps 61311a6606SAnna Dabrowska * @return bool|null|string 62311a6606SAnna Dabrowska */ 63311a6606SAnna Dabrowska public function createUser($user, $pwd, $name, $mail, $grps = null) 64311a6606SAnna Dabrowska { 65311a6606SAnna Dabrowska if ($this->getUserByEmail($mail)) { 66311a6606SAnna Dabrowska msg($this->getLang('emailduplicate'), -1); 67311a6606SAnna Dabrowska return false; 68311a6606SAnna Dabrowska } 69311a6606SAnna Dabrowska 70311a6606SAnna Dabrowska return parent::createUser($user, $pwd, $name, $mail, $grps); 71311a6606SAnna Dabrowska } 72311a6606SAnna Dabrowska 73311a6606SAnna Dabrowska /** 74311a6606SAnna Dabrowska * Enhance function to check against duplicate emails 75311a6606SAnna Dabrowska * 76311a6606SAnna Dabrowska * @param string $user 77311a6606SAnna Dabrowska * @param array $changes 78311a6606SAnna Dabrowska * @return bool 79311a6606SAnna Dabrowska */ 80311a6606SAnna Dabrowska public function modifyUser($user, $changes) 81311a6606SAnna Dabrowska { 82311a6606SAnna Dabrowska global $conf; 83311a6606SAnna Dabrowska 84311a6606SAnna Dabrowska if (isset($changes['mail'])) { 85311a6606SAnna Dabrowska $found = $this->getUserByEmail($changes['mail']); 86311a6606SAnna Dabrowska if ($found && $found != $user) { 87311a6606SAnna Dabrowska msg($this->getLang('emailduplicate'), -1); 88311a6606SAnna Dabrowska return false; 89311a6606SAnna Dabrowska } 90311a6606SAnna Dabrowska } 91311a6606SAnna Dabrowska 92311a6606SAnna Dabrowska $ok = parent::modifyUser($user, $changes); 93311a6606SAnna Dabrowska 94311a6606SAnna Dabrowska // refresh session cache 95311a6606SAnna Dabrowska touch($conf['cachedir'] . '/sessionpurge'); 96311a6606SAnna Dabrowska 97311a6606SAnna Dabrowska return $ok; 98311a6606SAnna Dabrowska } 99311a6606SAnna Dabrowska 100311a6606SAnna Dabrowska /** 101311a6606SAnna Dabrowska * Unset additional stuff in session on logout 102311a6606SAnna Dabrowska */ 103311a6606SAnna Dabrowska public function logOff() 104311a6606SAnna Dabrowska { 105311a6606SAnna Dabrowska parent::logOff(); 106311a6606SAnna Dabrowska 107311a6606SAnna Dabrowska $this->cleanLogout(); 108311a6606SAnna Dabrowska } 109311a6606SAnna Dabrowska 110311a6606SAnna Dabrowska /** 111a02a5d81SAnna Dabrowska * check if auth data is present in session and is still considered valid 112f2e164b0SMichael Große * 113f2e164b0SMichael Große * @return bool 114f2e164b0SMichael Große */ 115a02a5d81SAnna Dabrowska protected function sessionLogin() 1163e7ac5b1SAndreas Gohr { 117a02a5d81SAnna Dabrowska global $USERINFO; 118a02a5d81SAnna Dabrowska $session = $_SESSION[DOKU_COOKIE]['auth']; 119*b8ca6a42SAnna Dabrowska // FIXME session can be null at this point (e.g. coming from sprintdoc svg.php) 120*b8ca6a42SAnna Dabrowska // FIXME and so the subsequent check for non-GET non-doku.php requests is not performed 121a02a5d81SAnna Dabrowska if (isset($session['oauth']) && $this->isSessionValid($session)) { 122a02a5d81SAnna Dabrowska $_SERVER['REMOTE_USER'] = $session['user']; 123a02a5d81SAnna Dabrowska $USERINFO = $session['info']; 124f2e164b0SMichael Große return true; 125f2e164b0SMichael Große } 126f2e164b0SMichael Große return false; 127f2e164b0SMichael Große } 128f2e164b0SMichael Große 129a02a5d81SAnna Dabrowska /** 130a02a5d81SAnna Dabrowska * Use cookie data to log in 131a02a5d81SAnna Dabrowska */ 132a02a5d81SAnna Dabrowska protected function cookieLogin() 133a02a5d81SAnna Dabrowska { 134a02a5d81SAnna Dabrowska if (isset($_COOKIE[DOKU_COOKIE])) { 135a02a5d81SAnna Dabrowska list($cookieuser, $cookiesticky, $auth, $servicename) = explode('|', $_COOKIE[DOKU_COOKIE]); 136a02a5d81SAnna Dabrowska $auth = base64_decode($auth, true); 137a02a5d81SAnna Dabrowska $servicename = base64_decode($servicename, true); 138a02a5d81SAnna Dabrowska if ($auth === 'oauth') { 139*b8ca6a42SAnna Dabrowska $this->relogin($servicename); 140a02a5d81SAnna Dabrowska } 141a02a5d81SAnna Dabrowska } 142a02a5d81SAnna Dabrowska } 143a02a5d81SAnna Dabrowska 144a02a5d81SAnna Dabrowska /** 145a02a5d81SAnna Dabrowska * Use the OAuth service 146a02a5d81SAnna Dabrowska * 147a02a5d81SAnna Dabrowska * @param $servicename 148b2b9fbc7SMichael Große * @param $sticky 149a02a5d81SAnna Dabrowska * @param $page 150a02a5d81SAnna Dabrowska * @param $params 151a02a5d81SAnna Dabrowska * @param $existingLoginProcess 152a02a5d81SAnna Dabrowska * @return bool 153a02a5d81SAnna Dabrowska * @throws \OAuth\Common\Exception\Exception 154a02a5d81SAnna Dabrowska * @throws \OAuth\Common\Http\Exception\TokenResponseException 155a02a5d81SAnna Dabrowska * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException 156a02a5d81SAnna Dabrowska */ 157a02a5d81SAnna Dabrowska protected function serviceLogin($servicename, $sticky, $page, $params, $existingLoginProcess) 158a02a5d81SAnna Dabrowska { 159a02a5d81SAnna Dabrowska $service = $this->getService($servicename); 160a02a5d81SAnna Dabrowska if (is_null($service)) { 161a02a5d81SAnna Dabrowska $this->cleanLogout(); 162a02a5d81SAnna Dabrowska return false; 163a02a5d81SAnna Dabrowska } 164a02a5d81SAnna Dabrowska 165a02a5d81SAnna Dabrowska if ($service->checkToken()) { 166a02a5d81SAnna Dabrowska if (!$this->processLogin($sticky, $service, $servicename, $page, $params)) { 167a02a5d81SAnna Dabrowska $this->cleanLogout(); 168a02a5d81SAnna Dabrowska return false; 169a02a5d81SAnna Dabrowska } 170a02a5d81SAnna Dabrowska return true; 171a02a5d81SAnna Dabrowska } else { 172a02a5d81SAnna Dabrowska if ($existingLoginProcess) { 173a02a5d81SAnna Dabrowska msg($this->getLang('oauth login failed'), 0); 174a02a5d81SAnna Dabrowska $this->cleanLogout(); 175a02a5d81SAnna Dabrowska return false; 176a02a5d81SAnna Dabrowska } else { 177a02a5d81SAnna Dabrowska // first time here 178*b8ca6a42SAnna Dabrowska $this->relogin($servicename); 179a02a5d81SAnna Dabrowska } 180a02a5d81SAnna Dabrowska } 181a02a5d81SAnna Dabrowska 182a02a5d81SAnna Dabrowska $this->cleanLogout(); 183a02a5d81SAnna Dabrowska return false; // something went wrong during oAuth login 184a02a5d81SAnna Dabrowska } 185a02a5d81SAnna Dabrowska 186a02a5d81SAnna Dabrowska /** 187*b8ca6a42SAnna Dabrowska * Relogin using auth info read from session / cookie 188*b8ca6a42SAnna Dabrowska * 189a02a5d81SAnna Dabrowska * @param string $servicename 190a02a5d81SAnna Dabrowska * @return void|false 191a02a5d81SAnna Dabrowska * @throws \OAuth\Common\Http\Exception\TokenResponseException 192a02a5d81SAnna Dabrowska */ 193*b8ca6a42SAnna Dabrowska protected function relogin($servicename) 194a02a5d81SAnna Dabrowska { 195a02a5d81SAnna Dabrowska $service = $this->getService($servicename); 196a02a5d81SAnna Dabrowska if (is_null($service)) return false; 197a02a5d81SAnna Dabrowska 198a02a5d81SAnna Dabrowska $this->writeSession($servicename); 199a02a5d81SAnna Dabrowska $service->login(); 200a02a5d81SAnna Dabrowska } 201a02a5d81SAnna Dabrowska 202a02a5d81SAnna Dabrowska 203a02a5d81SAnna Dabrowska /** 204a02a5d81SAnna Dabrowska * @param bool $sticky 205a02a5d81SAnna Dabrowska * @param \dokuwiki\plugin\oauth\Service $service 2069928f5efSMichael Große * @param string $servicename 207b2b9fbc7SMichael Große * @param string $page 208188ba446SMichael Große * @param array $params 209f07c7607SMichael Große * 210f07c7607SMichael Große * @return bool 211a02a5d81SAnna Dabrowska * @throws \OAuth\Common\Exception\Exception 212f07c7607SMichael Große */ 213a02a5d81SAnna Dabrowska protected function processLogin($sticky, $service, $servicename, $page, $params = []) 2143e7ac5b1SAndreas Gohr { 215a02a5d81SAnna Dabrowska $userinfo = $service->getUser(); 216a02a5d81SAnna Dabrowska $ok = $this->processUserinfo($userinfo, $servicename); 217f07c7607SMichael Große if (!$ok) { 218f07c7607SMichael Große return false; 219f07c7607SMichael Große } 220a02a5d81SAnna Dabrowska $this->setUserSession($userinfo, $servicename); 221a02a5d81SAnna Dabrowska $this->setUserCookie($userinfo['user'], $sticky, $servicename); 222b2b9fbc7SMichael Große if (isset($page)) { 223188ba446SMichael Große if (!empty($params['id'])) unset($params['id']); 224188ba446SMichael Große send_redirect(wl($page, $params, false, '&')); 225b2b9fbc7SMichael Große } 226f07c7607SMichael Große return true; 227f07c7607SMichael Große } 228f07c7607SMichael Große 2299928f5efSMichael Große /** 230a02a5d81SAnna Dabrowska * process the user and update the user info array 2319928f5efSMichael Große * 232a02a5d81SAnna Dabrowska * @param array $userinfo User info received from authentication 233a02a5d81SAnna Dabrowska * @param string $servicename Auth service 2349928f5efSMichael Große * 2359928f5efSMichael Große * @return bool 2369928f5efSMichael Große */ 237a02a5d81SAnna Dabrowska protected function processUserinfo(&$userinfo, $servicename) 2383e7ac5b1SAndreas Gohr { 239a02a5d81SAnna Dabrowska $userinfo['user'] = $this->cleanUser((string)$userinfo['user']); 240a02a5d81SAnna Dabrowska if (!$userinfo['name']) $userinfo['name'] = $userinfo['user']; 2419928f5efSMichael Große 242a02a5d81SAnna Dabrowska if (!$userinfo['user'] || !$userinfo['mail']) { 2439928f5efSMichael Große msg("$servicename did not provide the needed user info. Can't log you in", -1); 2449928f5efSMichael Große return false; 2459928f5efSMichael Große } 2469928f5efSMichael Große 2479928f5efSMichael Große // see if the user is known already 248a02a5d81SAnna Dabrowska $localUser = $this->getUserByEmail($userinfo['mail']); 249a02a5d81SAnna Dabrowska if ($localUser) { 250a02a5d81SAnna Dabrowska $localUserInfo = $this->getUserData($localUser); 2519928f5efSMichael Große // check if the user allowed access via this service 252a02a5d81SAnna Dabrowska if (!in_array($this->cleanGroup($servicename), $localUserInfo['grps'])) { 2539928f5efSMichael Große msg(sprintf($this->getLang('authnotenabled'), $servicename), -1); 2549928f5efSMichael Große return false; 2559928f5efSMichael Große } 256a02a5d81SAnna Dabrowska $userinfo['user'] = $localUser; 257a02a5d81SAnna Dabrowska $userinfo['name'] = $localUserInfo['name']; 258a02a5d81SAnna Dabrowska $userinfo['grps'] = array_merge((array)$userinfo['grps'], $localUserInfo['grps']); 259d313403cSAnna Dabrowska } elseif (actionOK('register') || $this->getConf('register-on-auth')) { 260a02a5d81SAnna Dabrowska $ok = $this->addUser($userinfo, $servicename); 2619928f5efSMichael Große if (!$ok) { 2629928f5efSMichael Große msg('something went wrong creating your user account. please try again later.', -1); 2639928f5efSMichael Große return false; 2649928f5efSMichael Große } 2659928f5efSMichael Große } else { 2669928f5efSMichael Große msg($this->getLang('addUser not possible'), -1); 2679928f5efSMichael Große return false; 2689928f5efSMichael Große } 2699928f5efSMichael Große return true; 2709928f5efSMichael Große } 2719928f5efSMichael Große 2729928f5efSMichael Große /** 273b2b9fbc7SMichael Große * new user, create him - making sure the login is unique by adding a number if needed 274b2b9fbc7SMichael Große * 275a02a5d81SAnna Dabrowska * @param array $userinfo user info received from the oAuth service 276b2b9fbc7SMichael Große * @param string $servicename 277b2b9fbc7SMichael Große * 278b2b9fbc7SMichael Große * @return bool 279b2b9fbc7SMichael Große */ 280a02a5d81SAnna Dabrowska protected function addUser(&$userinfo, $servicename) 2813e7ac5b1SAndreas Gohr { 282b2b9fbc7SMichael Große global $conf; 283a02a5d81SAnna Dabrowska $user = $userinfo['user']; 284b2b9fbc7SMichael Große $count = ''; 285b2b9fbc7SMichael Große while ($this->getUserData($user . $count)) { 286b2b9fbc7SMichael Große if ($count) { 287b2b9fbc7SMichael Große $count++; 288b2b9fbc7SMichael Große } else { 289b2b9fbc7SMichael Große $count = 1; 290b2b9fbc7SMichael Große } 291b2b9fbc7SMichael Große } 292b2b9fbc7SMichael Große $user = $user . $count; 293a02a5d81SAnna Dabrowska $userinfo['user'] = $user; 294b2b9fbc7SMichael Große $groups_on_creation = array(); 295b2b9fbc7SMichael Große $groups_on_creation[] = $conf['defaultgroup']; 296b2b9fbc7SMichael Große $groups_on_creation[] = $this->cleanGroup($servicename); // add service as group 297a02a5d81SAnna Dabrowska $userinfo['grps'] = array_merge((array)$userinfo['grps'], $groups_on_creation); 298b2b9fbc7SMichael Große 299b2b9fbc7SMichael Große $ok = $this->triggerUserMod( 300b2b9fbc7SMichael Große 'create', 301a02a5d81SAnna Dabrowska array($user, auth_pwgen($user), $userinfo['name'], $userinfo['mail'], $groups_on_creation,) 302b2b9fbc7SMichael Große ); 303b2b9fbc7SMichael Große if (!$ok) { 304b2b9fbc7SMichael Große return false; 305b2b9fbc7SMichael Große } 306b2b9fbc7SMichael Große 307b2b9fbc7SMichael Große // send notification about the new user 308b2b9fbc7SMichael Große $subscription = new Subscription(); 309a02a5d81SAnna Dabrowska $subscription->send_register($user, $userinfo['name'], $userinfo['mail']); 310b2b9fbc7SMichael Große return true; 311b2b9fbc7SMichael Große } 312b2b9fbc7SMichael Große 313b2b9fbc7SMichael Große /** 314a02a5d81SAnna Dabrowska * Find a user by email address 315b2b9fbc7SMichael Große * 316b2b9fbc7SMichael Große * @param $mail 317b2b9fbc7SMichael Große * @return bool|string 318b2b9fbc7SMichael Große */ 3193e7ac5b1SAndreas Gohr protected function getUserByEmail($mail) 3203e7ac5b1SAndreas Gohr { 3218b214edcSAndreas Gohr if ($this->users === null) { 3228b214edcSAndreas Gohr if (is_callable([$this, '_loadUserData'])) { 3238b214edcSAndreas Gohr $this->_loadUserData(); 3248b214edcSAndreas Gohr } else { 3258b214edcSAndreas Gohr $this->loadUserData(); 3268b214edcSAndreas Gohr } 3278b214edcSAndreas Gohr } 328b2b9fbc7SMichael Große $mail = strtolower($mail); 329b2b9fbc7SMichael Große 330a02a5d81SAnna Dabrowska foreach ($this->users as $user => $userinfo) { 331a02a5d81SAnna Dabrowska if (strtolower($userinfo['mail']) == $mail) return $user; 332b2b9fbc7SMichael Große } 333b2b9fbc7SMichael Große 334b2b9fbc7SMichael Große return false; 335b2b9fbc7SMichael Große } 336b2b9fbc7SMichael Große 337b2b9fbc7SMichael Große /** 338a02a5d81SAnna Dabrowska * unset auth cookies and session information 339a02a5d81SAnna Dabrowska */ 340a02a5d81SAnna Dabrowska private function cleanLogout() 341a02a5d81SAnna Dabrowska { 342a02a5d81SAnna Dabrowska if (isset($_SESSION[DOKU_COOKIE]['oauth-done'])) { 343a02a5d81SAnna Dabrowska unset($_SESSION[DOKU_COOKIE]['oauth-done']); 344a02a5d81SAnna Dabrowska } 345a02a5d81SAnna Dabrowska if (isset($_SESSION[DOKU_COOKIE]['auth'])) { 346a02a5d81SAnna Dabrowska unset($_SESSION[DOKU_COOKIE]['auth']); 347a02a5d81SAnna Dabrowska } 348a02a5d81SAnna Dabrowska $this->setUserCookie('', true, '', -60); 349a02a5d81SAnna Dabrowska } 350a02a5d81SAnna Dabrowska 351a02a5d81SAnna Dabrowska /** 352a02a5d81SAnna Dabrowska * @param string $servicename 353a02a5d81SAnna Dabrowska * @return \dokuwiki\plugin\oauth\Service 354a02a5d81SAnna Dabrowska */ 355a02a5d81SAnna Dabrowska protected function getService($servicename) 356a02a5d81SAnna Dabrowska { 357a02a5d81SAnna Dabrowska /** @var helper_plugin_oauth $hlp */ 358a02a5d81SAnna Dabrowska $hlp = plugin_load('helper', 'oauth'); 359a02a5d81SAnna Dabrowska 360a02a5d81SAnna Dabrowska return $hlp->loadService($servicename); 361a02a5d81SAnna Dabrowska } 362a02a5d81SAnna Dabrowska 363a02a5d81SAnna Dabrowska 364a02a5d81SAnna Dabrowska /** 365a02a5d81SAnna Dabrowska * Save user and auth data 366a02a5d81SAnna Dabrowska * 367b2b9fbc7SMichael Große * @param array $data 368b2b9fbc7SMichael Große * @param string $service 369b2b9fbc7SMichael Große */ 3703e7ac5b1SAndreas Gohr protected function setUserSession($data, $service) 3713e7ac5b1SAndreas Gohr { 372b2b9fbc7SMichael Große global $USERINFO; 373b2b9fbc7SMichael Große 374b2b9fbc7SMichael Große // set up groups 375b2b9fbc7SMichael Große if (!is_array($data['grps'])) { 376b2b9fbc7SMichael Große $data['grps'] = array(); 377b2b9fbc7SMichael Große } 378b2b9fbc7SMichael Große $data['grps'][] = $this->cleanGroup($service); 379b2b9fbc7SMichael Große $data['grps'] = array_unique($data['grps']); 380b2b9fbc7SMichael Große 381b2b9fbc7SMichael Große $USERINFO = $data; 382b2b9fbc7SMichael Große $_SERVER['REMOTE_USER'] = $data['user']; 383b2b9fbc7SMichael Große $_SESSION[DOKU_COOKIE]['auth']['user'] = $data['user']; 384b2b9fbc7SMichael Große $_SESSION[DOKU_COOKIE]['auth']['pass'] = $data['pass']; 385b2b9fbc7SMichael Große $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 386b2b9fbc7SMichael Große $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); 387b2b9fbc7SMichael Große $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); 388b2b9fbc7SMichael Große $_SESSION[DOKU_COOKIE]['auth']['oauth'] = $service; 389b2b9fbc7SMichael Große } 390b2b9fbc7SMichael Große 391b2b9fbc7SMichael Große /** 3929928f5efSMichael Große * @param string $user 393523e6571SMichael Große * @param bool $sticky 3949928f5efSMichael Große * @param string $servicename 395523e6571SMichael Große * @param int $validityPeriodInSeconds optional, per default 1 Year 3969928f5efSMichael Große */ 3973e7ac5b1SAndreas Gohr private function setUserCookie($user, $sticky, $servicename, $validityPeriodInSeconds = 31536000) 3983e7ac5b1SAndreas Gohr { 3999928f5efSMichael Große $cookie = base64_encode($user) . '|' . ((int)$sticky) . '|' . base64_encode('oauth') . '|' . base64_encode($servicename); 4009928f5efSMichael Große $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; 401523e6571SMichael Große $time = $sticky ? (time() + $validityPeriodInSeconds) : 0; 4029928f5efSMichael Große setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true); 4039928f5efSMichael Große } 4049928f5efSMichael Große 405827232fcSMichael Große /** 406a02a5d81SAnna Dabrowska * @param array $session cookie auth session 407a02a5d81SAnna Dabrowska * 408a02a5d81SAnna Dabrowska * @return bool 409b2b9fbc7SMichael Große */ 410a02a5d81SAnna Dabrowska protected function isSessionValid($session) 4113e7ac5b1SAndreas Gohr { 412a02a5d81SAnna Dabrowska /** @var helper_plugin_oauth $hlp */ 413a02a5d81SAnna Dabrowska $hlp = plugin_load('helper', 'oauth'); 414a02a5d81SAnna Dabrowska if ($hlp->validBrowserID($session)) { 415a02a5d81SAnna Dabrowska if (!$hlp->isSessionTimedOut($session)) { 416a02a5d81SAnna Dabrowska return true; 417a02a5d81SAnna Dabrowska } elseif (!($hlp->isGETRequest() && $hlp->isDokuPHP())) { 418a02a5d81SAnna Dabrowska // only force a recheck on a timed-out session during a GET request on the main script doku.php 419a02a5d81SAnna Dabrowska return true; 420af2a4e8fSMichael Große } 421af2a4e8fSMichael Große } 422a02a5d81SAnna Dabrowska return false; 423a02a5d81SAnna Dabrowska } 424a02a5d81SAnna Dabrowska 425a02a5d81SAnna Dabrowska /** 426a02a5d81SAnna Dabrowska * Save login info in session 427a02a5d81SAnna Dabrowska * 428a02a5d81SAnna Dabrowska * @param string $servicename 429a02a5d81SAnna Dabrowska */ 430a02a5d81SAnna Dabrowska protected function writeSession($servicename) 431a02a5d81SAnna Dabrowska { 432a02a5d81SAnna Dabrowska global $INPUT; 433a02a5d81SAnna Dabrowska 434*b8ca6a42SAnna Dabrowska // FIXME delegate to SessionManager? in action/login.php as well? 435a02a5d81SAnna Dabrowska session_start(); 436a02a5d81SAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-inprogress']['service'] = $servicename; 437a02a5d81SAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-inprogress']['id'] = $INPUT->str('id'); 438*b8ca6a42SAnna Dabrowska 439a02a5d81SAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-inprogress']['params'] = $_GET; 440a02a5d81SAnna Dabrowska 441a02a5d81SAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-done']['$_REQUEST'] = $_REQUEST; 442a02a5d81SAnna Dabrowska 443a02a5d81SAnna Dabrowska if (is_array($INPUT->post->param('do'))) { 444a02a5d81SAnna Dabrowska $doPost = key($INPUT->post->arr('do')); 445a02a5d81SAnna Dabrowska } else { 446a02a5d81SAnna Dabrowska $doPost = $INPUT->post->str('do'); 447a02a5d81SAnna Dabrowska } 448a02a5d81SAnna Dabrowska $doGet = $INPUT->get->str('do'); 449a02a5d81SAnna Dabrowska if (!empty($doPost)) { 450a02a5d81SAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-done']['do'] = $doPost; 451a02a5d81SAnna Dabrowska } elseif (!empty($doGet)) { 452a02a5d81SAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-done']['do'] = $doGet; 453a02a5d81SAnna Dabrowska } 454a02a5d81SAnna Dabrowska 455a02a5d81SAnna Dabrowska session_write_close(); 456b2b9fbc7SMichael Große } 457b2b9fbc7SMichael Große 458b2b9fbc7SMichael Große /** 459*b8ca6a42SAnna Dabrowska * Farmer plugin support 460*b8ca6a42SAnna Dabrowska * 461*b8ca6a42SAnna Dabrowska * When coming back to farmer instance via OAUTH redirectURI, we need to redirect again 462*b8ca6a42SAnna Dabrowska * to a proper animal instance detected from $state 463b2b9fbc7SMichael Große * 464311a6606SAnna Dabrowska * @param $state 465b2b9fbc7SMichael Große */ 466311a6606SAnna Dabrowska private function handleState($state) 4673e7ac5b1SAndreas Gohr { 468311a6606SAnna Dabrowska /** @var \helper_plugin_farmer $farmer */ 469311a6606SAnna Dabrowska $farmer = plugin_load('helper', 'farmer', false, true); 470311a6606SAnna Dabrowska $data = json_decode(base64_decode(urldecode($state))); 471311a6606SAnna Dabrowska if (empty($data->animal) || $farmer->getAnimal() == $data->animal) { 472311a6606SAnna Dabrowska return; 473827232fcSMichael Große } 474311a6606SAnna Dabrowska $animal = $data->animal; 475311a6606SAnna Dabrowska $allAnimals = $farmer->getAllAnimals(); 476311a6606SAnna Dabrowska if (!in_array($animal, $allAnimals)) { 477311a6606SAnna Dabrowska msg('Animal ' . $animal . ' does not exist!'); 478311a6606SAnna Dabrowska return; 479827232fcSMichael Große } 480311a6606SAnna Dabrowska global $INPUT; 481311a6606SAnna Dabrowska $url = $farmer->getAnimalURL($animal) . '/doku.php?' . $INPUT->server->str('QUERY_STRING'); 482311a6606SAnna Dabrowska send_redirect($url); 483b2b9fbc7SMichael Große } 484b2b9fbc7SMichael Große} 485b2b9fbc7SMichael Große 48680852c15SAndreas Gohr// vim:ts=4:sw=4:et: 487