MDL-61351 auth_shibboleth: move new functions to separate class
authorMark Nelson <markn@moodle.com>
Mon, 9 Jul 2018 08:51:33 +0000 (16:51 +0800)
committerMark Nelson <markn@moodle.com>
Tue, 17 Jul 2018 08:45:20 +0000 (16:45 +0800)
This reduces the amount of code to an already confusing logout.php
file and prevents conflicts if someone else happens to be using
the same function name in a file.

auth/shibboleth/classes/helper.php [new file with mode: 0644]
auth/shibboleth/logout.php
auth/shibboleth/upgrade.txt

diff --git a/auth/shibboleth/classes/helper.php b/auth/shibboleth/classes/helper.php
new file mode 100644 (file)
index 0000000..c1d5705
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Contains a helper class for the Shibboleth authentication plugin.
+ *
+ * @package    auth_shibboleth
+ * @copyright  2018 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace auth_shibboleth;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The helper class for the Shibboleth authentication plugin.
+ *
+ * @package    auth_shibboleth
+ * @copyright  2018 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class helper {
+
+    /**
+     * Delete session of user using file sessions.
+     *
+     * @param string $spsessionid SP-provided Shibboleth Session ID
+     * @return \SoapFault or void if everything was fine
+     */
+    public static function logout_file_session($spsessionid) {
+        global $CFG;
+
+        if (!empty($CFG->session_file_save_path)) {
+            $dir = $CFG->session_file_save_path;
+        } else {
+            $dir = $CFG->dataroot . '/sessions';
+        }
+
+        if (is_dir($dir)) {
+            if ($dh = opendir($dir)) {
+                // Read all session files.
+                while (($file = readdir($dh)) !== false) {
+                    // Check if it is a file.
+                    if (is_file($dir.'/'.$file)) {
+                        // Read session file data.
+                        $data = file($dir.'/'.$file);
+                        if (isset($data[0])) {
+                            $usersession = self::unserializesession($data[0]);
+                            // Check if we have found session that shall be deleted.
+                            if (isset($usersession['SESSION']) && isset($usersession['SESSION']->shibboleth_session_id)) {
+                                // If there is a match, delete file.
+                                if ($usersession['SESSION']->shibboleth_session_id == $spsessionid) {
+                                    // Delete session file.
+                                    if (!unlink($dir.'/'.$file)) {
+                                        return new SoapFault('LogoutError', 'Could not delete Moodle session file.');
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                closedir($dh);
+            }
+        }
+    }
+
+    /**
+     * Delete session of user using DB sessions.
+     *
+     * @param string $spsessionid SP-provided Shibboleth Session ID
+     */
+    public static function logout_db_session($spsessionid) {
+        global $CFG, $DB;
+
+        $sessions = $DB->get_records_sql(
+            'SELECT userid, sessdata FROM {sessions} WHERE timemodified > ?',
+            array(time() - $CFG->sessiontimeout)
+        );
+
+        foreach ($sessions as $session) {
+            // Get user session from DB.
+            if (session_decode(base64_decode($session->sessdata))) {
+                if (isset($_SESSION['SESSION']) && isset($_SESSION['SESSION']->shibboleth_session_id)) {
+                    // If there is a match, kill the session.
+                    if ($_SESSION['SESSION']->shibboleth_session_id == trim($spsessionid)) {
+                        // Delete this user's sessions.
+                        \core\session\manager::kill_user_sessions($session->userid);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Unserialize a session string.
+     *
+     * @param string $serializedstring
+     * @return array
+     */
+    private static function unserializesession($serializedstring) {
+        $variables = array();
+        $a = preg_split("/(\w+)\|/", $serializedstring, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
+        $counta = count($a);
+        for ($i = 0; $i < $counta; $i = $i + 2) {
+            $variables[$a[$i]] = unserialize($a[$i + 1]);
+        }
+        return $variables;
+    }
+}
index ae57977..c9fa33d 100644 (file)
@@ -135,94 +135,19 @@ function LogoutNotification($spsessionid) {
     if (!empty($CFG->session_handler_class)) {
         $sessionclass = $CFG->session_handler_class;
         if (preg_match('/database/i', $sessionclass) === 1) {
-            return logoutdbsession($spsessionid);
+            return \auth_shibboleth\helper::logout_db_session($spsessionid);
         } else if (preg_match('/file/i', $sessionclass) === 1) {
-            return logoutfilesession($spsessionid);
+            return \auth_shibboleth\helper::logout_file_session($spsessionid);
         } else {
             throw new moodle_exception("Shibboleth logout not implemented for '$sessionclass'");
         }
     } else {
         // Session handler class is not specified, check dbsessions instead.
         if (!empty($CFG->dbsessions)) {
-            return logoutdbsession($spsessionid);
+            return \auth_shibboleth\helper::logout_db_session($spsessionid);
         }
         // Assume file sessions if dbsessions isn't used.
-        return logoutfilesession($spsessionid);
+        return \auth_shibboleth\helper::logout_file_session($spsessionid);
     }
     // If no SoapFault was thrown, the function will return OK as the SP assumes.
 }
-
-// Delete session of user using $spsessionid.
-function logoutfilesession($spsessionid) {
-    global $CFG;
-
-    if (!empty($CFG->session_file_save_path)) {
-        $dir = $CFG->session_file_save_path;
-    } else {
-        $dir = $CFG->dataroot . '/sessions';
-    }
-
-    if (is_dir($dir)) {
-        if ($dh = opendir($dir)) {
-            // Read all session files.
-            while (($file = readdir($dh)) !== false) {
-                // Check if it is a file.
-                if (is_file($dir.'/'.$file)) {
-
-                    // Read session file data.
-                    $data = file($dir.'/'.$file);
-                    if (isset($data[0])) {
-                        $usersession = unserializesession($data[0]);
-
-                        // Check if we have found session that shall be deleted.
-                        if (isset($usersession['SESSION']) && isset($usersession['SESSION']->shibboleth_session_id)) {
-
-                            // If there is a match, delete file.
-                            if ($usersession['SESSION']->shibboleth_session_id == $spsessionid) {
-                                // Delete session file.
-                                if (!unlink($dir.'/'.$file)) {
-                                    return new SoapFault('LogoutError', 'Could not delete Moodle session file.');
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            closedir($dh);
-        }
-    }
-}
-
-function logoutdbsession($spsessionid) {
-    global $CFG, $DB;
-    $sessions = $DB->get_records_sql(
-        'SELECT userid, sessdata FROM {sessions} WHERE timemodified > ?',
-        array(time() - $CFG->sessiontimeout)
-    );
-    foreach ($sessions as $session) {
-        // Get user session from DB.
-        if (session_decode(base64_decode($session->sessdata))) {
-            if (isset($_SESSION['SESSION']) && isset($_SESSION['SESSION']->shibboleth_session_id)) {
-                // If there is a match, kill the session.
-                if ($_SESSION['SESSION']->shibboleth_session_id == trim($spsessionid)) {
-                    // Delete this user's sessions.
-                    \core\session\manager::kill_user_sessions($session->userid);
-                }
-            }
-        }
-    }
-}
-
-/*****************************************************************************/
-
-// Same function as in adodb, but cannot be used for file session for some reason...
-function unserializesession($serialized_string) {
-    $variables = array();
-    $a = preg_split("/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
-    $counta = count($a);
-    for ($i = 0; $i < $counta; $i = $i+2) {
-            $variables[$a[$i]] = unserialize($a[$i+1]);
-    }
-    return $variables;
-}
-
index dbd7b4b..9083025 100644 (file)
@@ -1,6 +1,11 @@
 This files describes API changes in /auth/shibboleth/*,
 information provided here is intended especially for developers.
 
+=== 3.5.2 ===
+
+* Moved the public function unserializesession in auth/shibboleth/logout.php to auth/shibboleth/classes/helper.php and
+  made it private. This function should not have been used outside of this file.
+
 === 3.3 ===
 
 * The config.html file was migrated to use the admin settings API.