Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/auth/shibboleth/logout.php
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Enumerations