1<?php 2 3namespace dokuwiki\plugin\oauth; 4 5/** 6 * Singleton to manage all oAuth related session and cookie data 7 */ 8class Session 9{ 10 /** @var Session */ 11 protected static $instance = null; 12 13 /** 14 * hidden constructor 15 */ 16 protected function __construct() 17 { 18 } 19 20 /** 21 * Get Singleton Instance 22 * 23 * @return Session 24 */ 25 public static function getInstance() 26 { 27 if (self::$instance === null) { 28 self::$instance = new Session(); 29 } 30 return self::$instance; 31 } 32 33 /** 34 * Set a service and guid for a login in progress 35 * 36 * @param string $servicename 37 * @param string $guid 38 * @return void 39 */ 40 public function setLoginData($servicename, $guid) 41 { 42 $_SESSION[DOKU_COOKIE]['auth']['oauth']['service'] = $servicename; 43 $_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'] = $guid; 44 } 45 46 /** 47 * Get currently used login service 48 * 49 * @return false|array Either [servicename=>*,guid=>*] or false 50 */ 51 public function getLoginData() 52 { 53 if ( 54 isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['service']) and 55 isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['guid']) 56 57 ) { 58 return [ 59 'servicename' => $_SESSION[DOKU_COOKIE]['auth']['oauth']['service'], 60 'guid' => $_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'], 61 ]; 62 } 63 return false; 64 } 65 66 /** 67 * Remove login service from session 68 * @return void 69 */ 70 public function clearLoginData() 71 { 72 if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['service'])) { 73 unset($_SESSION[DOKU_COOKIE]['auth']['oauth']['service']); 74 } 75 if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'])) { 76 unset($_SESSION[DOKU_COOKIE]['auth']['oauth']['guid']); 77 } 78 } 79 80 /** 81 * This basically duplicates what DokuWiki does when a user is logged in 82 * 83 * @param array $userdata 84 * @param bool $resettime Set a new session time? False only when restoring from session 85 * @return void 86 * @throws Exception 87 */ 88 public function setUser($userdata, $resettime = true) 89 { 90 global $USERINFO; 91 92 if ( 93 !isset($userdata['user']) or 94 !isset($userdata['name']) or 95 !isset($userdata['mail']) or 96 !isset($userdata['grps']) or 97 !is_array($userdata['grps']) 98 ) { 99 throw new Exception('Missing user data, cannot save to session'); 100 } 101 102 $USERINFO = $userdata; 103 $_SERVER['REMOTE_USER'] = $userdata['user']; 104 105 $_SESSION[DOKU_COOKIE]['auth']['user'] = $userdata['user']; 106 $_SESSION[DOKU_COOKIE]['auth']['pass'] = $userdata['pass']; 107 $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 108 $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); 109 if ($resettime) { 110 $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); 111 } 112 } 113 114 /** 115 * The user data currently saved in the session if any 116 * 117 * @return false|array 118 */ 119 public function getUser() 120 { 121 if (isset($_SESSION[DOKU_COOKIE]['auth']['info'])) { 122 return $_SESSION[DOKU_COOKIE]['auth']['info']; 123 } 124 return false; 125 } 126 127 /** 128 * Set oAuth info to cookie 129 * 130 * We use the same cookie as standard DokuWiki, but write different info. 131 * 132 * @param string $servicename 133 * @param string $guid 134 * @return void 135 */ 136 public function setCookie($servicename, $guid) 137 { 138 global $conf; 139 $validityPeriodInSeconds = 60 * 60 * 24 * 365; 140 $cookie = "$servicename|oauth|$guid"; 141 $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; 142 $time = time() + $validityPeriodInSeconds; 143 setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true); 144 } 145 146 /** 147 * Get oAuth info from cookie 148 * 149 * @return array|false Either [servicename=>?, guid=>?] or false if no oauth data in cookie 150 */ 151 public function getCookie() 152 { 153 if (!isset($_COOKIE[DOKU_COOKIE])) return false; 154 list($servicename, $oauth, $guid) = explode('|', $_COOKIE[DOKU_COOKIE]); 155 if ($oauth !== 'oauth') return false; 156 return ['servicename' => $servicename, 'guid' => $guid]; 157 } 158 159 /** 160 * Is any auth data in the session currently trustworthy? 161 * @return bool 162 */ 163 public function isValid() 164 { 165 global $conf; 166 167 if (!isset($_SESSION[DOKU_COOKIE]['auth']['buid'])) return false; 168 if (!isset($_SESSION[DOKU_COOKIE]['auth']['time'])) return false; 169 if ($_SESSION[DOKU_COOKIE]['auth']['buid'] != auth_browseruid()) return false; 170 if ($_SESSION[DOKU_COOKIE]['auth']['time'] < time() - $conf['auth_security_timeout']) return false; 171 172 return true; 173 } 174 175 /** 176 * Clear the session from auth related data 177 * @return void 178 */ 179 public function clear() 180 { 181 //FIXME clear cookie? 182 $this->clearLoginData(); 183 184 } 185} 186