[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/auth/shibboleth/ -> logout.php (source)

   1  <?php
   2  
   3  // Implements logout for Shibboleth authenticated users according to:
   4  // - https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator
   5  // - https://spaces.internet2.edu/display/SHIB2/NativeSPNotify
   6  
   7  require_once("../../config.php");
   8  
   9  require_once($CFG->dirroot."/auth/shibboleth/auth.php");
  10  
  11  
  12  // Find out whether host supports https
  13  $protocol = 'http://';
  14  if (is_https()) {
  15      $protocol = 'https://';
  16  }
  17  
  18  // Front channel logout
  19  if (
  20          isset($_GET['return'])
  21          && isset($_GET['action'])
  22          && $_GET['action'] == 'logout'
  23     ){
  24  
  25      // Logout out user from application
  26      // E.g. destroy application session/cookie etc
  27      require_logout();
  28  
  29      // Finally, send user to the return URL
  30      redirect($_GET['return']);
  31  }
  32  
  33  // Back channel logout
  34  elseif (!empty($HTTP_RAW_POST_DATA)) {
  35  
  36      // Requires PHP 5
  37  
  38  
  39      // Set SOAP header
  40      $server = new SoapServer($protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl');
  41  
  42  
  43      $server->addFunction("LogoutNotification");
  44      $server->handle();
  45  }
  46  
  47  // Return WSDL
  48  else {
  49  
  50      header('Content-Type: text/xml');
  51  
  52      echo <<<WSDL
  53  <?xml version ="1.0" encoding ="UTF-8" ?>
  54  <definitions name="LogoutNotification"
  55    targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
  56    xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"
  57    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  58    xmlns="http://schemas.xmlsoap.org/wsdl/">
  59  
  60  <!--
  61  This page either has to be called with the GET arguments 'action' and 'return' via
  62  a redirect from the Shibboleth Service Provider logout handler (front-channel
  63  logout) or via a SOAP request by a Shibboleth Service Provider (back-channel
  64  logout).
  65  Because neither of these two variants seems to be the case, the WSDL file for
  66  the web service is returned.
  67  
  68  For more information see:
  69  - https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator
  70  - https://spaces.internet2.edu/display/SHIB2/NativeSPNotify
  71  -->
  72  
  73      <types>
  74         <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
  75             xmlns="http://www.w3.org/2000/10/XMLSchema"
  76             xmlns:notify="urn:mace:shibboleth:2.0:sp:notify">
  77  
  78              <simpleType name="string">
  79                  <restriction base="string">
  80                      <minLength value="1"/>
  81                  </restriction>
  82              </simpleType>
  83  
  84              <element name="OK" type="notify:OKType"/>
  85              <complexType name="OKType">
  86                  <sequence/>
  87              </complexType>
  88  
  89          </schema>
  90      </types>
  91  
  92      <message name="getLogoutNotificationRequest">
  93          <part name="SessionID" type="notify:string" />
  94      </message>
  95  
  96      <message name="getLogoutNotificationResponse" >
  97          <part name="OK"/>
  98      </message>
  99  
 100      <portType name="LogoutNotificationPortType">
 101          <operation name="LogoutNotification">
 102              <input message="getLogoutNotificationRequest"/>
 103              <output message="getLogoutNotificationResponse"/>
 104          </operation>
 105      </portType>
 106  
 107      <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType">
 108          <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
 109          <operation name="LogoutNotification">
 110              <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/>
 111          </operation>
 112      </binding>
 113  
 114      <service name="LogoutNotificationService">
 115            <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding">
 116              <soap:address location="{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/>
 117            </port>
 118      </service>
 119  </definitions>
 120  WSDL;
 121      exit;
 122  
 123  }
 124  
 125  /******************************************************************************/
 126  
 127  function LogoutNotification($SessionID){
 128  
 129      global $CFG, $SESSION, $DB;
 130  
 131      // Delete session of user using $SessionID
 132      if(empty($CFG->dbsessions)) {
 133  
 134          // File session
 135          $dir = $CFG->dataroot .'/sessions';
 136          if (is_dir($dir)) {
 137              if ($dh = opendir($dir)) {
 138                  // Read all session files
 139                  while (($file = readdir($dh)) !== false) {
 140                      // Check if it is a file
 141                      if (is_file($dir.'/'.$file)){
 142                          $session_key = preg_replace('/sess_/', '', $file);
 143  
 144                          // Read session file data
 145                          $data = file($dir.'/'.$file);
 146                          if (isset($data[0])){
 147                              $user_session = unserializesession($data[0]);
 148  
 149                              // Check if we have found session that shall be deleted
 150                              if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){
 151  
 152                                  // If there is a match, delete file
 153                                  if ($user_session['SESSION']->shibboleth_session_id == $SessionID){
 154                                      // Delete session file
 155                                      if (!unlink($dir.'/'.$file)){
 156                                          return new SoapFault('LogoutError', 'Could not delete Moodle session file.');
 157                                      }
 158                                  }
 159                              }
 160                          }
 161                      }
 162                  }
 163                  closedir($dh);
 164              }
 165          }
 166      } else {
 167          // DB Session
 168          //TODO: this needs to be rewritten to use new session stuff
 169          if (!empty($CFG->sessiontimeout)) {
 170              $ADODB_SESS_LIFE   = $CFG->sessiontimeout;
 171          }
 172  
 173              if ($user_session_data = $DB->get_records_sql('SELECT sesskey, sessdata FROM {sessions2} WHERE expiry > NOW()')) {
 174              foreach ($user_session_data as $session_data) {
 175  
 176                  // Get user session
 177                  $user_session = adodb_unserialize( urldecode($session_data->sessdata) );
 178  
 179                  if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){
 180  
 181                      // If there is a match, delete file
 182                      if ($user_session['SESSION']->shibboleth_session_id == $SessionID){
 183                          // Delete this session entry
 184                          if (ADODB_Session::destroy($session_data->sesskey) !== true){
 185                              return new SoapFault('LogoutError', 'Could not delete Moodle session entry in database.');
 186                          }
 187                      }
 188                  }
 189              }
 190          }
 191      }
 192  
 193      // If now SoapFault was thrown the function will return OK as the SP assumes
 194  
 195  }
 196  
 197  /*****************************************************************************/
 198  
 199  // Same function as in adodb, but cannot be used for file session for some reason...
 200  function unserializesession($serialized_string) {
 201      $variables = array();
 202      $a = preg_split("/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
 203      $counta = count($a);
 204      for ($i = 0; $i < $counta; $i = $i+2) {
 205              $variables[$a[$i]] = unserialize($a[$i+1]);
 206      }
 207      return $variables;
 208  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1