MDL-25637 Fixed whitespace
[moodle.git] / auth / shibboleth / logout.php
CommitLineData
5117d598 1<?php
2db6ec19 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
7require_once("../../config.php");
8
9require_once($CFG->dirroot."/auth/shibboleth/auth.php");
10
11
ad9f023c 12// Find out whether host supports https
13$protocol = 'http://';
14if ( isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'){
80c12897 15 $protocol = 'https://';
5117d598 16}
ad9f023c 17
2db6ec19 18// Front channel logout
19if (
5117d598 20 isset($_GET['return'])
ad9f023c 21 && isset($_GET['action'])
22 && $_GET['action'] == 'logout'
2db6ec19 23 ){
5117d598 24
ad9f023c 25 // Logout out user from application
26 // E.g. destroy application session/cookie etc
27 require_logout();
5117d598 28
ad9f023c 29 // Finally, send user to the return URL
30 redirect($_GET['return']);
2db6ec19 31}
32
33// Back channel logout
34elseif (!empty($HTTP_RAW_POST_DATA)) {
5117d598 35
ad9f023c 36 // Requires PHP 5
5117d598
PS
37
38
ad9f023c 39 // Set SOAP header
40 $server = new SoapServer($protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl');
5117d598
PS
41
42
ad9f023c 43 $server->addFunction("LogoutNotification");
44 $server->handle();
5117d598 45}
2db6ec19 46
47// Return WSDL
48else {
5117d598 49
ad9f023c 50 header('Content-Type: text/xml');
5117d598 51
ad9f023c 52 echo <<<WSDL
2db6ec19 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<!--
61This page either has to be called with the GET arguments 'action' and 'return' via
5117d598
PS
62a redirect from the Shibboleth Service Provider logout handler (front-channel
63logout) or via a SOAP request by a Shibboleth Service Provider (back-channel
2db6ec19 64logout).
5117d598 65Because neither of these two variants seems to be the case, the WSDL file for
2db6ec19 66the web service is returned.
67
68For more information see:
69- https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator
70- https://spaces.internet2.edu/display/SHIB2/NativeSPNotify
71-->
72
ad9f023c 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">
5117d598 77
ad9f023c 78 <simpleType name="string">
79 <restriction base="string">
80 <minLength value="1"/>
81 </restriction>
82 </simpleType>
5117d598 83
ad9f023c 84 <element name="OK" type="notify:OKType"/>
85 <complexType name="OKType">
86 <sequence/>
87 </complexType>
5117d598 88
ad9f023c 89 </schema>
90 </types>
5117d598 91
ad9f023c 92 <message name="getLogoutNotificationRequest">
93 <part name="SessionID" type="notify:string" />
94 </message>
5117d598 95
ad9f023c 96 <message name="getLogoutNotificationResponse" >
97 <part name="OK"/>
98 </message>
5117d598 99
ad9f023c 100 <portType name="LogoutNotificationPortType">
101 <operation name="LogoutNotification">
102 <input message="getLogoutNotificationRequest"/>
103 <output message="getLogoutNotificationResponse"/>
104 </operation>
105 </portType>
5117d598 106
ad9f023c 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>
5117d598 113
ad9f023c 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>
2db6ec19 119</definitions>
120WSDL;
ad9f023c 121 exit;
2db6ec19 122
123}
124
125/******************************************************************************/
126
127function LogoutNotification($SessionID){
5117d598 128
ffdd703a 129 global $CFG, $SESSION, $DB;
5117d598 130
ad9f023c 131 // Delete session of user using $SessionID
132 if(empty($CFG->dbsessions)) {
5117d598 133
ad9f023c 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)){
c78a948e 142 $session_key = preg_replace('/sess_/', '', $file);
5117d598 143
ad9f023c 144 // Read session file data
145 $data = file($dir.'/'.$file);
146 if (isset($data[0])){
147 $user_session = unserializesession($data[0]);
5117d598
PS
148
149 // Check if we have found session that shall be deleted
ad9f023c 150 if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){
5117d598 151
ad9f023c 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
cc220229 168 //TODO: this needs to be rewritten to use new session stuff
ad9f023c 169 if (!empty($CFG->sessiontimeout)) {
170 $ADODB_SESS_LIFE = $CFG->sessiontimeout;
171 }
5117d598 172
ffdd703a 173 if ($user_session_data = $DB->get_records_sql('SELECT sesskey, sessdata FROM {sessions2} WHERE expiry > NOW()')) {
ad9f023c 174 foreach ($user_session_data as $session_data) {
5117d598 175
ad9f023c 176 // Get user session
177 $user_session = adodb_unserialize( urldecode($session_data->sessdata) );
5117d598 178
ad9f023c 179 if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){
5117d598 180
ad9f023c 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 }
5117d598 192
ad9f023c 193 // If now SoapFault was thrown the function will return OK as the SP assumes
5117d598 194
2db6ec19 195}
196
197/*****************************************************************************/
198
199// Same function as in adodb, but cannot be used for file session for some reason...
b692e4aa
AB
200function 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);
80c12897 204 for ($i = 0; $i < $counta; $i = $i+2) {
b692e4aa 205 $variables[$a[$i]] = unserialize($a[$i+1]);
ad9f023c 206 }
80c12897 207 return $variables;
2db6ec19 208}