174b4d4a4SAndreas Gohr<?php 274b4d4a4SAndreas Gohr 374b4d4a4SAndreas Gohrnamespace dokuwiki\plugin\oauth; 474b4d4a4SAndreas Gohr 574b4d4a4SAndreas Gohr/** 674b4d4a4SAndreas Gohr * Singleton to manage all oAuth related session and cookie data 774b4d4a4SAndreas Gohr */ 874b4d4a4SAndreas Gohrclass Session 974b4d4a4SAndreas Gohr{ 1074b4d4a4SAndreas Gohr /** @var Session */ 11*290e9b1fSAndreas Gohr protected static $instance; 1274b4d4a4SAndreas Gohr 1374b4d4a4SAndreas Gohr /** 1474b4d4a4SAndreas Gohr * hidden constructor 1574b4d4a4SAndreas Gohr */ 1674b4d4a4SAndreas Gohr protected function __construct() 1774b4d4a4SAndreas Gohr { 1874b4d4a4SAndreas Gohr } 1974b4d4a4SAndreas Gohr 2074b4d4a4SAndreas Gohr /** 2174b4d4a4SAndreas Gohr * Get Singleton Instance 2274b4d4a4SAndreas Gohr * 2374b4d4a4SAndreas Gohr * @return Session 2474b4d4a4SAndreas Gohr */ 2574b4d4a4SAndreas Gohr public static function getInstance() 2674b4d4a4SAndreas Gohr { 2774b4d4a4SAndreas Gohr if (self::$instance === null) { 2874b4d4a4SAndreas Gohr self::$instance = new Session(); 2974b4d4a4SAndreas Gohr } 3074b4d4a4SAndreas Gohr return self::$instance; 3174b4d4a4SAndreas Gohr } 3274b4d4a4SAndreas Gohr 3374b4d4a4SAndreas Gohr /** 3431039e80SAndreas Gohr * Set the environment needed to verify a login in progress 3574b4d4a4SAndreas Gohr * 3631039e80SAndreas Gohr * @param string $servicename the name of the service used 3731039e80SAndreas Gohr * @param string $id pageID to return to after login 3874b4d4a4SAndreas Gohr * @return void 3974b4d4a4SAndreas Gohr */ 4028002081SAndreas Gohr public function setLoginData($servicename, $id) 4174b4d4a4SAndreas Gohr { 4231039e80SAndreas Gohr $_SESSION[DOKU_COOKIE]['auth']['oauth'] = [ 4331039e80SAndreas Gohr 'servicename' => $servicename, 4431039e80SAndreas Gohr 'id' => $id, 4531039e80SAndreas Gohr ]; 4674b4d4a4SAndreas Gohr } 4774b4d4a4SAndreas Gohr 4874b4d4a4SAndreas Gohr /** 4931039e80SAndreas Gohr * Get the current login environment 5074b4d4a4SAndreas Gohr * 5128002081SAndreas Gohr * @return false|array Either [servicename=>*, id=>*] or false 5274b4d4a4SAndreas Gohr */ 5374b4d4a4SAndreas Gohr public function getLoginData() 5474b4d4a4SAndreas Gohr { 55*290e9b1fSAndreas Gohr return $_SESSION[DOKU_COOKIE]['auth']['oauth'] ?? false; 5674b4d4a4SAndreas Gohr } 5774b4d4a4SAndreas Gohr 5874b4d4a4SAndreas Gohr /** 5931039e80SAndreas Gohr * Clear login environment after login 6031039e80SAndreas Gohr * 6174b4d4a4SAndreas Gohr * @return void 6274b4d4a4SAndreas Gohr */ 6374b4d4a4SAndreas Gohr public function clearLoginData() 6474b4d4a4SAndreas Gohr { 6531039e80SAndreas Gohr if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth'])) { 6631039e80SAndreas Gohr unset($_SESSION[DOKU_COOKIE]['auth']['oauth']); 6774b4d4a4SAndreas Gohr } 6874b4d4a4SAndreas Gohr } 6974b4d4a4SAndreas Gohr 7074b4d4a4SAndreas Gohr /** 7174b4d4a4SAndreas Gohr * This basically duplicates what DokuWiki does when a user is logged in 7274b4d4a4SAndreas Gohr * 7374b4d4a4SAndreas Gohr * @param array $userdata 7474b4d4a4SAndreas Gohr * @param bool $resettime Set a new session time? False only when restoring from session 7574b4d4a4SAndreas Gohr * @return void 7674b4d4a4SAndreas Gohr * @throws Exception 7774b4d4a4SAndreas Gohr */ 7874b4d4a4SAndreas Gohr public function setUser($userdata, $resettime = true) 7974b4d4a4SAndreas Gohr { 8074b4d4a4SAndreas Gohr global $USERINFO; 8174b4d4a4SAndreas Gohr 8274b4d4a4SAndreas Gohr if ( 83*290e9b1fSAndreas Gohr !isset($userdata['user']) || 84*290e9b1fSAndreas Gohr !isset($userdata['name']) || 85*290e9b1fSAndreas Gohr !isset($userdata['mail']) || 86*290e9b1fSAndreas Gohr !isset($userdata['grps']) || 8774b4d4a4SAndreas Gohr !is_array($userdata['grps']) 8874b4d4a4SAndreas Gohr ) { 8974b4d4a4SAndreas Gohr throw new Exception('Missing user data, cannot save to session'); 9074b4d4a4SAndreas Gohr } 9174b4d4a4SAndreas Gohr 9274b4d4a4SAndreas Gohr $USERINFO = $userdata; 9374b4d4a4SAndreas Gohr $_SERVER['REMOTE_USER'] = $userdata['user']; 9474b4d4a4SAndreas Gohr 9574b4d4a4SAndreas Gohr $_SESSION[DOKU_COOKIE]['auth']['user'] = $userdata['user']; 961258c6c0SAndreas Gohr $_SESSION[DOKU_COOKIE]['auth']['pass'] = 'not-set'; // pass is neither needed nor wanted 9774b4d4a4SAndreas Gohr $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 9874b4d4a4SAndreas Gohr $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); 9974b4d4a4SAndreas Gohr if ($resettime) { 10074b4d4a4SAndreas Gohr $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); 10174b4d4a4SAndreas Gohr } 10274b4d4a4SAndreas Gohr } 10374b4d4a4SAndreas Gohr 10474b4d4a4SAndreas Gohr /** 10574b4d4a4SAndreas Gohr * The user data currently saved in the session if any 10674b4d4a4SAndreas Gohr * 10774b4d4a4SAndreas Gohr * @return false|array 10874b4d4a4SAndreas Gohr */ 10974b4d4a4SAndreas Gohr public function getUser() 11074b4d4a4SAndreas Gohr { 111*290e9b1fSAndreas Gohr return $_SESSION[DOKU_COOKIE]['auth']['info'] ?? false; 11274b4d4a4SAndreas Gohr } 11374b4d4a4SAndreas Gohr 11474b4d4a4SAndreas Gohr /** 11574b4d4a4SAndreas Gohr * Set oAuth info to cookie 11674b4d4a4SAndreas Gohr * 11774b4d4a4SAndreas Gohr * We use the same cookie as standard DokuWiki, but write different info. 11874b4d4a4SAndreas Gohr * 11974b4d4a4SAndreas Gohr * @param string $servicename 12028002081SAndreas Gohr * @param string $storageId 12174b4d4a4SAndreas Gohr * @return void 12274b4d4a4SAndreas Gohr */ 12328002081SAndreas Gohr public function setCookie($servicename, $storageId) 12474b4d4a4SAndreas Gohr { 12574b4d4a4SAndreas Gohr global $conf; 12674b4d4a4SAndreas Gohr $validityPeriodInSeconds = 60 * 60 * 24 * 365; 12728002081SAndreas Gohr $cookie = "$servicename|oauth|$storageId"; 12874b4d4a4SAndreas Gohr $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; 12974b4d4a4SAndreas Gohr $time = time() + $validityPeriodInSeconds; 130*290e9b1fSAndreas Gohr setcookie( 131*290e9b1fSAndreas Gohr DOKU_COOKIE, 132*290e9b1fSAndreas Gohr $cookie, 133*290e9b1fSAndreas Gohr [ 134*290e9b1fSAndreas Gohr 'expires' => $time, 135*290e9b1fSAndreas Gohr 'path' => $cookieDir, 136*290e9b1fSAndreas Gohr 'domain' => '', 137*290e9b1fSAndreas Gohr 'secure' => $conf['securecookie'] && is_ssl(), 138*290e9b1fSAndreas Gohr 'httponly' => true 139*290e9b1fSAndreas Gohr ] 140*290e9b1fSAndreas Gohr ); 14174b4d4a4SAndreas Gohr } 14274b4d4a4SAndreas Gohr 14374b4d4a4SAndreas Gohr /** 14474b4d4a4SAndreas Gohr * Get oAuth info from cookie 14574b4d4a4SAndreas Gohr * 14628002081SAndreas Gohr * @return array|false Either [servicename=>?, storageID=>?] or false if no oauth data in cookie 14774b4d4a4SAndreas Gohr */ 14874b4d4a4SAndreas Gohr public function getCookie() 14974b4d4a4SAndreas Gohr { 15074b4d4a4SAndreas Gohr if (!isset($_COOKIE[DOKU_COOKIE])) return false; 151*290e9b1fSAndreas Gohr [$servicename, $oauth, $storageId] = explode('|', $_COOKIE[DOKU_COOKIE]); 15274b4d4a4SAndreas Gohr if ($oauth !== 'oauth') return false; 15328002081SAndreas Gohr return ['servicename' => $servicename, 'storageId' => $storageId]; 15474b4d4a4SAndreas Gohr } 15574b4d4a4SAndreas Gohr 15674b4d4a4SAndreas Gohr /** 15774b4d4a4SAndreas Gohr * Is any auth data in the session currently trustworthy? 15874b4d4a4SAndreas Gohr * @return bool 15974b4d4a4SAndreas Gohr */ 16074b4d4a4SAndreas Gohr public function isValid() 16174b4d4a4SAndreas Gohr { 16274b4d4a4SAndreas Gohr global $conf; 16374b4d4a4SAndreas Gohr 16474b4d4a4SAndreas Gohr if (!isset($_SESSION[DOKU_COOKIE]['auth']['buid'])) return false; 16574b4d4a4SAndreas Gohr if (!isset($_SESSION[DOKU_COOKIE]['auth']['time'])) return false; 16674b4d4a4SAndreas Gohr if ($_SESSION[DOKU_COOKIE]['auth']['buid'] != auth_browseruid()) return false; 16774b4d4a4SAndreas Gohr if ($_SESSION[DOKU_COOKIE]['auth']['time'] < time() - $conf['auth_security_timeout']) return false; 16874b4d4a4SAndreas Gohr 16974b4d4a4SAndreas Gohr return true; 17074b4d4a4SAndreas Gohr } 17174b4d4a4SAndreas Gohr 17274b4d4a4SAndreas Gohr /** 17374b4d4a4SAndreas Gohr * Clear the session from auth related data 17474b4d4a4SAndreas Gohr * @return void 17574b4d4a4SAndreas Gohr */ 17674b4d4a4SAndreas Gohr public function clear() 17774b4d4a4SAndreas Gohr { 178e170f465SAndreas Gohr //FIXME clear cookie? 17974b4d4a4SAndreas Gohr $this->clearLoginData(); 18074b4d4a4SAndreas Gohr } 18174b4d4a4SAndreas Gohr} 182