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 the environment needed to verify a login in progress 35 * 36 * @param string $servicename the name of the service used 37 * @param string $id pageID to return to after login 38 * @return void 39 */ 40 public function setLoginData($servicename, $id) 41 { 42 $_SESSION[DOKU_COOKIE]['auth']['oauth'] = [ 43 'servicename' => $servicename, 44 'id' => $id, 45 ]; 46 } 47 48 /** 49 * Get the current login environment 50 * 51 * @return false|array Either [servicename=>*, id=>*] or false 52 */ 53 public function getLoginData() 54 { 55 if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth'])) { 56 return $_SESSION[DOKU_COOKIE]['auth']['oauth']; 57 } 58 return false; 59 } 60 61 /** 62 * Clear login environment after login 63 * 64 * @return void 65 */ 66 public function clearLoginData() 67 { 68 if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth'])) { 69 unset($_SESSION[DOKU_COOKIE]['auth']['oauth']); 70 } 71 } 72 73 /** 74 * This basically duplicates what DokuWiki does when a user is logged in 75 * 76 * @param array $userdata 77 * @param bool $resettime Set a new session time? False only when restoring from session 78 * @return void 79 * @throws Exception 80 */ 81 public function setUser($userdata, $resettime = true) 82 { 83 global $USERINFO; 84 85 if ( 86 !isset($userdata['user']) or 87 !isset($userdata['name']) or 88 !isset($userdata['mail']) or 89 !isset($userdata['grps']) or 90 !is_array($userdata['grps']) 91 ) { 92 throw new Exception('Missing user data, cannot save to session'); 93 } 94 95 $USERINFO = $userdata; 96 $_SERVER['REMOTE_USER'] = $userdata['user']; 97 98 $_SESSION[DOKU_COOKIE]['auth']['user'] = $userdata['user']; 99 $_SESSION[DOKU_COOKIE]['auth']['pass'] = 'not-set'; // pass is neither needed nor wanted 100 $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 101 $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); 102 if ($resettime) { 103 $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); 104 } 105 } 106 107 /** 108 * The user data currently saved in the session if any 109 * 110 * @return false|array 111 */ 112 public function getUser() 113 { 114 if (isset($_SESSION[DOKU_COOKIE]['auth']['info'])) { 115 return $_SESSION[DOKU_COOKIE]['auth']['info']; 116 } 117 return false; 118 } 119 120 /** 121 * Set oAuth info to cookie 122 * 123 * We use the same cookie as standard DokuWiki, but write different info. 124 * 125 * @param string $servicename 126 * @param string $storageId 127 * @return void 128 */ 129 public function setCookie($servicename, $storageId) 130 { 131 global $conf; 132 $validityPeriodInSeconds = 60 * 60 * 24 * 365; 133 $cookie = "$servicename|oauth|$storageId"; 134 $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; 135 $time = time() + $validityPeriodInSeconds; 136 setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true); 137 } 138 139 /** 140 * Get oAuth info from cookie 141 * 142 * @return array|false Either [servicename=>?, storageID=>?] or false if no oauth data in cookie 143 */ 144 public function getCookie() 145 { 146 if (!isset($_COOKIE[DOKU_COOKIE])) return false; 147 list($servicename, $oauth, $storageId) = explode('|', $_COOKIE[DOKU_COOKIE]); 148 if ($oauth !== 'oauth') return false; 149 return ['servicename' => $servicename, 'storageId' => $storageId]; 150 } 151 152 /** 153 * Is any auth data in the session currently trustworthy? 154 * @return bool 155 */ 156 public function isValid() 157 { 158 global $conf; 159 160 if (!isset($_SESSION[DOKU_COOKIE]['auth']['buid'])) return false; 161 if (!isset($_SESSION[DOKU_COOKIE]['auth']['time'])) return false; 162 if ($_SESSION[DOKU_COOKIE]['auth']['buid'] != auth_browseruid()) return false; 163 if ($_SESSION[DOKU_COOKIE]['auth']['time'] < time() - $conf['auth_security_timeout']) return false; 164 165 return true; 166 } 167 168 /** 169 * Clear the session from auth related data 170 * @return void 171 */ 172 public function clear() 173 { 174 //FIXME clear cookie? 175 $this->clearLoginData(); 176 177 } 178} 179