|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // Implements logout for Shibboleth authenticated users according to: 00004 // - https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator 00005 // - https://spaces.internet2.edu/display/SHIB2/NativeSPNotify 00006 00007 require_once("../../config.php"); 00008 00009 require_once($CFG->dirroot."/auth/shibboleth/auth.php"); 00010 00011 00012 // Find out whether host supports https 00013 $protocol = 'http://'; 00014 if ( isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'){ 00015 $protocol = 'https://'; 00016 } 00017 00018 // Front channel logout 00019 if ( 00020 isset($_GET['return']) 00021 && isset($_GET['action']) 00022 && $_GET['action'] == 'logout' 00023 ){ 00024 00025 // Logout out user from application 00026 // E.g. destroy application session/cookie etc 00027 require_logout(); 00028 00029 // Finally, send user to the return URL 00030 redirect($_GET['return']); 00031 } 00032 00033 // Back channel logout 00034 elseif (!empty($HTTP_RAW_POST_DATA)) { 00035 00036 // Requires PHP 5 00037 00038 00039 // Set SOAP header 00040 $server = new SoapServer($protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl'); 00041 00042 00043 $server->addFunction("LogoutNotification"); 00044 $server->handle(); 00045 } 00046 00047 // Return WSDL 00048 else { 00049 00050 header('Content-Type: text/xml'); 00051 00052 echo <<<WSDL 00053 <?xml version ="1.0" encoding ="UTF-8" ?> 00054 <definitions name="LogoutNotification" 00055 targetNamespace="urn:mace:shibboleth:2.0:sp:notify" 00056 xmlns:notify="urn:mace:shibboleth:2.0:sp:notify" 00057 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 00058 xmlns="http://schemas.xmlsoap.org/wsdl/"> 00059 00060 <!-- 00061 This page either has to be called with the GET arguments 'action' and 'return' via 00062 a redirect from the Shibboleth Service Provider logout handler (front-channel 00063 logout) or via a SOAP request by a Shibboleth Service Provider (back-channel 00064 logout). 00065 Because neither of these two variants seems to be the case, the WSDL file for 00066 the web service is returned. 00067 00068 For more information see: 00069 - https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator 00070 - https://spaces.internet2.edu/display/SHIB2/NativeSPNotify 00071 --> 00072 00073 <types> 00074 <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify" 00075 xmlns="http://www.w3.org/2000/10/XMLSchema" 00076 xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"> 00077 00078 <simpleType name="string"> 00079 <restriction base="string"> 00080 <minLength value="1"/> 00081 </restriction> 00082 </simpleType> 00083 00084 <element name="OK" type="notify:OKType"/> 00085 <complexType name="OKType"> 00086 <sequence/> 00087 </complexType> 00088 00089 </schema> 00090 </types> 00091 00092 <message name="getLogoutNotificationRequest"> 00093 <part name="SessionID" type="notify:string" /> 00094 </message> 00095 00096 <message name="getLogoutNotificationResponse" > 00097 <part name="OK"/> 00098 </message> 00099 00100 <portType name="LogoutNotificationPortType"> 00101 <operation name="LogoutNotification"> 00102 <input message="getLogoutNotificationRequest"/> 00103 <output message="getLogoutNotificationResponse"/> 00104 </operation> 00105 </portType> 00106 00107 <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType"> 00108 <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 00109 <operation name="LogoutNotification"> 00110 <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/> 00111 </operation> 00112 </binding> 00113 00114 <service name="LogoutNotificationService"> 00115 <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding"> 00116 <soap:address location="{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/> 00117 </port> 00118 </service> 00119 </definitions> 00120 WSDL; 00121 exit; 00122 00123 } 00124 00125 /******************************************************************************/ 00126 00127 function LogoutNotification($SessionID){ 00128 00129 global $CFG, $SESSION, $DB; 00130 00131 // Delete session of user using $SessionID 00132 if(empty($CFG->dbsessions)) { 00133 00134 // File session 00135 $dir = $CFG->dataroot .'/sessions'; 00136 if (is_dir($dir)) { 00137 if ($dh = opendir($dir)) { 00138 // Read all session files 00139 while (($file = readdir($dh)) !== false) { 00140 // Check if it is a file 00141 if (is_file($dir.'/'.$file)){ 00142 $session_key = preg_replace('/sess_/', '', $file); 00143 00144 // Read session file data 00145 $data = file($dir.'/'.$file); 00146 if (isset($data[0])){ 00147 $user_session = unserializesession($data[0]); 00148 00149 // Check if we have found session that shall be deleted 00150 if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){ 00151 00152 // If there is a match, delete file 00153 if ($user_session['SESSION']->shibboleth_session_id == $SessionID){ 00154 // Delete session file 00155 if (!unlink($dir.'/'.$file)){ 00156 return new SoapFault('LogoutError', 'Could not delete Moodle session file.'); 00157 } 00158 } 00159 } 00160 } 00161 } 00162 } 00163 closedir($dh); 00164 } 00165 } 00166 } else { 00167 // DB Session 00168 //TODO: this needs to be rewritten to use new session stuff 00169 if (!empty($CFG->sessiontimeout)) { 00170 $ADODB_SESS_LIFE = $CFG->sessiontimeout; 00171 } 00172 00173 if ($user_session_data = $DB->get_records_sql('SELECT sesskey, sessdata FROM {sessions2} WHERE expiry > NOW()')) { 00174 foreach ($user_session_data as $session_data) { 00175 00176 // Get user session 00177 $user_session = adodb_unserialize( urldecode($session_data->sessdata) ); 00178 00179 if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){ 00180 00181 // If there is a match, delete file 00182 if ($user_session['SESSION']->shibboleth_session_id == $SessionID){ 00183 // Delete this session entry 00184 if (ADODB_Session::destroy($session_data->sesskey) !== true){ 00185 return new SoapFault('LogoutError', 'Could not delete Moodle session entry in database.'); 00186 } 00187 } 00188 } 00189 } 00190 } 00191 } 00192 00193 // If now SoapFault was thrown the function will return OK as the SP assumes 00194 00195 } 00196 00197 /*****************************************************************************/ 00198 00199 // Same function as in adodb, but cannot be used for file session for some reason... 00200 function unserializesession($serialized_string) { 00201 $variables = array(); 00202 $a = preg_split("/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 00203 $counta = count($a); 00204 for ($i = 0; $i < $counta; $i = $i+2) { 00205 $variables[$a[$i]] = unserialize($a[$i+1]); 00206 } 00207 return $variables; 00208 }