]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-17942 more session refactoring
authorskodak <skodak>
Sun, 18 Jan 2009 18:00:44 +0000 (18:00 +0000)
committerskodak <skodak>
Sun, 18 Jan 2009 18:00:44 +0000 (18:00 +0000)
admin/auth.php
admin/cron.php
admin/user.php
admin/user/user_bulk_delete.php
lib/authlib.php
lib/sessionlib.php
user/editadvanced.php

index caed90baebd608369289bd7a836d8cd500841972..7115ff04cf38ddd078f7daf751aae9642d2cc06c 100644 (file)
@@ -52,7 +52,7 @@ switch ($action) {
         if ($auth == $CFG->registerauth) {
             set_config('registerauth', '');
         }
-        session_get_instance()->gc(); // remove stale sessions
+        session_gc(); // remove stale sessions
         break;
 
     case 'enable':
@@ -62,7 +62,7 @@ switch ($action) {
             $authsenabled = array_unique($authsenabled);
             set_config('auth', implode(',', $authsenabled));
         }
-        session_get_instance()->gc(); // remove stale sessions
+        session_gc(); // remove stale sessions
         break;
 
     case 'down':
index 661cccf9ec87a7d7d24a8bd7682f2e08ca06da91..fa15f56b21b37197cc531cc1bf50b605551b3e7d 100644 (file)
@@ -87,7 +87,7 @@
 /// Session gc
 
     mtrace("Cleaning up stale sessions");
-    session_get_instance()->gc();
+    session_gc();
 
 /// Run all cron jobs for each module
 
index 0ef6cf246f99436b3a4ad040e9885bc214c61524..1ff160de215356231ce5a6328fcb3642d6da888e 100644 (file)
@@ -80,7 +80,7 @@
             } else {
                 notify(get_string('deletednot', '', fullname($user, true)));
             }
-            session_get_instance()->gc(); // remove stale sessions
+            session_gc(); // remove stale sessions
         }
     } else if ($acl and confirm_sesskey()) {
         if (!has_capability('moodle/user:delete', $sitecontext)) {
index 5df513572cf6f2d7df03a53256e725347c0a2075..8278f8307e522505a0b584597ae61d772bb8ada0 100755 (executable)
@@ -35,7 +35,7 @@ if ($confirm and confirm_sesskey()) {
         }
         $rs->close;
     }
-    session_get_instance()->gc(); // remove stale sessions
+    session_gc(); // remove stale sessions
     redirect($return, get_string('changessaved'));
 
 } else {
index 164dc3b4687fd6969d9515a105a62127f9ab9fd6..1e143884d92fab35f725f39102db6e9cf73d47ca 100644 (file)
@@ -343,7 +343,16 @@ class auth_plugin_base {
         //override if needed
     }
 
-    function ignore_timeout_hook($userid, $userauth, $sid, $timecreated, $timemodified) {
+    /**
+     * Hook called before timing out of database session.
+     * This is usueful for SSO and MNET.
+     * @param object $user
+     * @param string $sid session id
+     * @param int $timecreated start of session
+     * @param int $timemodified user last seen
+     * @return bool true means do not timeout session yet
+     */
+    function ignore_timeout_hook($user, $sid, $timecreated, $timemodified) {
         return false;
     }
 
index 71d2dcf33ad047a629f66405e8795c27975a6822..fad7cab382f8b67b9bf679c79c7ef8ea26864cec 100644 (file)
@@ -10,8 +10,12 @@ function session_get_instance() {
     static $session = null;
 
     if (is_null($session)) {
+        if (empty($CFG->sessiontimeout)) {
+            $CFG->sessiontimeout = 7200;
+        }
+
         if (defined('SESSION_CUSTOM')) {
-            // this is a hook for custom session handling, webservices, etc.
+            // this is a hook for webservices, key based login, etc.
             if (defined('SESSION_CUSTOM_FILE')) {
                 require_once($CFG->dirroot.SESSION_CUSTOM_FILE);
             }
@@ -38,26 +42,12 @@ interface moodle_session {
      */
     public function terminate_current();
 
-    /**
-     * Terminates all sessions, auth hooks are not executed.
-     * Useful in ugrade scripts.
-     */
-    public function terminate_all();
-
     /**
      * No more changes in session expected.
      * Unblocks the sesions, other scripts may start executing in parallel.
      * @return void
      */
     public function write_close();
-
-    /**
-     * Session garbage collection
-     * - verify timeout for all users
-     * - kill sessions of all deleted users
-     * - kill sessions of users with disabled plugins or 'nologin' plugin
-     */
-    public function gc();
 }
 
 /**
@@ -304,9 +294,6 @@ class legacy_file_session extends session_stub {
             ini_set('session.gc_probability', 1);
         }
 
-        if (empty($CFG->sessiontimeout)) {
-            $CFG->sessiontimeout = 7200;
-        }
         ini_set('session.gc_maxlifetime', $CFG->sessiontimeout);
 
         if (!file_exists($CFG->dataroot .'/sessions')) {
@@ -317,25 +304,6 @@ class legacy_file_session extends session_stub {
         }
         ini_set('session.save_path', $CFG->dataroot .'/sessions');
     }
-
-    /**
-     * Terminates all sessions, auth hooks are not executed.
-     * Useful in ugrade scripts.
-     */
-    public function terminate_all() {
-        // TODO
-    }
-
-    /**
-     * Session garbage collection
-     * - verify timeout for all users
-     * - kill sessions of all deleted users
-     * - kill sessions of users with disabled plugins or 'nologin' plugin
-     */
-    public function gc() {
-        // difficult/slow
-    }
-
 }
 
 /**
@@ -357,9 +325,6 @@ class database_session extends session_stub {
         // gc only from CRON - individual user timeouts now checked during each access
         ini_set('session.gc_probability', 0);
 
-        if (empty($CFG->sessiontimeout)) {
-            $CFG->sessiontimeout = 7200;
-        }
         ini_set('session.gc_maxlifetime', $CFG->sessiontimeout);
 
         $result = session_set_save_handler(array($this, 'handler_open'),
@@ -373,72 +338,6 @@ class database_session extends session_stub {
         }
     }
 
-    /**
-     * Terminates all sessions, auth hooks are not executed.
-     * Useful in ugrade scripts.
-     */
-    public function terminate_all() {
-        try {
-            // do not show any warnings - might be during upgrade/installation
-            $this->database->delete_records('sessions');
-        } catch (dml_exception $ignored) {
-        }
-    }
-
-    /**
-     * Session garbage collection
-     * - verify timeout for all users
-     * - kill sessions of all deleted users
-     * - kill sessions of users with disabled plugins or 'nologin' plugin
-     */
-    public function gc() {
-        global $CFG;
-        $maxlifetime = $CFG->sessiontimeout;
-
-        if (empty($CFG->rolesactive)) {
-            return;
-        }
-
-        try {
-            /// kill all sessions of deleted users
-            $this->database->delete_records_select('sessions', "userid IN (SELECT id FROM {user} WHERE deleted <> 0)");
-
-            /// kill sessions of users with disabled plugins
-            $auth_sequence = get_enabled_auth_plugins(true);
-            $auth_sequence = array_flip($auth_sequence);
-            unset($auth_sequence['nologin']); // no login allowed
-            $auth_sequence = array_flip($auth_sequence);
-            $notplugins = null;
-            list($notplugins, $params) = $this->database->get_in_or_equal($auth_sequence, SQL_PARAMS_QM, '', false);
-            $this->database->delete_records_select('sessions', "userid IN (SELECT id FROM {user} WHERE auth $notplugins)", $params);
-
-            /// now get a list of time-out candidates
-            $sql = "SELECT s.*, u.auth, u.username
-                      FROM {sessions} s
-                      JOIN {user} u ON u.id = s.userid
-                     WHERE s.timemodified + ? < ?";
-            $params = array($maxlifetime, time());
-
-            $authplugins = array();
-            foreach($auth_sequence as $authname) {
-                $authplugins[$authname] = get_auth_plugin($authname);
-            }
-            $records = $this->database->get_records_sql($sql, $params);
-            foreach ($records as $record) {
-                if (!empty($record->userid) and $record->username !== 'guest') { // skips not logged in and guests
-                    foreach ($authplugins as $authplugin) {
-                        if ($authplugin->ignore_timeout_hook($record->userid, $records->auth, $record->sid, $record->timecreated, $record->timemodified)) {
-                            continue;
-                        }
-                    }
-                }
-                $this->database->delete_records('sessions', array('id'=>$record->id));
-            }
-        } catch (dml_exception $ex) {
-            error_log('Error gc-ing sessions');
-        }
-    }
-
     public function handler_open($save_path, $session_name) {
         return true;
     }
@@ -489,7 +388,7 @@ class database_session extends session_stub {
                         $authsequence = get_enabled_auth_plugins(); // auths, in sequence
                         foreach($authsequence as $authname) {
                             $authplugin = get_auth_plugin($authname);
-                            if ($authplugin->ignore_timeout_hook($user->id, $user->auth, $record->sid, $record->timecreated, $record->timemodified)) {
+                            if ($authplugin->ignore_timeout_hook($user, $record->sid, $record->timecreated, $record->timemodified)) {
                                 $ignoretimeout = true;
                                 break;
                             }
@@ -593,7 +492,117 @@ class database_session extends session_stub {
         $this->gc();
         return true;
     }
+}
+
+/**
+ * Terminates all sessions, auth hooks are not executed.
+ * Useful in ugrade scripts.
+ */
+function session_kill_all() {
+    global $CFG, $DB;
+
+    try {
+        // do not show any warnings - might be during upgrade/installation
+        $DB->delete_records('sessions');
+    } catch (dml_exception $ignored) {
+    }
 
+    $sessiondir = "$CFG->dataroot/sessions/";
+    if (is_dir($sessiondir)) {
+        // TODO: delete all files, watch out some might be locked
+    }
+}
+
+/**
+ * Terminates one sessions, auth hooks are not executed.
+ *
+ * @param string $sid session id
+ */
+function session_kill($sid) {
+    global $CFG, $DB;
+
+    try {
+        // do not show any warnings - might be during upgrade/installation
+        $$DB->delete_records('sessions', array('sid'=>$sid));
+    } catch (dml_exception $ignored) {
+    }
+
+    $sessionfile = clean_param("$CFG->dataroot/sessions/$sid", PARAM_FILE);
+    if (file_exists($sessionfile)) {
+        // TODO: delete file, watch out might be locked
+    }
+}
+
+/**
+ * Terminates all sessions of one user, auth hooks are not executed.
+ * NOTE: This can not work for file based sessions!
+ *
+ * @param int $userid user id
+ */
+function session_kill_user($userid) {
+    global $CFG, $DB;
+
+    try {
+        // do not show any warnings - might be during upgrade/installation
+        $$DB->delete_records('sessions', array('userid'=>$userid));
+    } catch (dml_exception $ignored) {
+    }
+}
+
+/**
+ * Session garbage collection
+ * - verify timeout for all users
+ * - kill sessions of all deleted users
+ * - kill sessions of users with disabled plugins or 'nologin' plugin
+ *
+ * NOTE: this can not work when legacy file sessions used!
+ */
+function session_gc() {
+    global $CFG, $DB;
+
+    $maxlifetime = $CFG->sessiontimeout;
+
+    if (empty($CFG->rolesactive)) {
+        return;
+    }
+
+    try {
+        /// kill all sessions of deleted users
+        $DB->delete_records_select('sessions', "userid IN (SELECT id FROM {user} WHERE deleted <> 0)");
+
+        /// kill sessions of users with disabled plugins
+        $auth_sequence = get_enabled_auth_plugins(true);
+        $auth_sequence = array_flip($auth_sequence);
+        unset($auth_sequence['nologin']); // no login allowed
+        $auth_sequence = array_flip($auth_sequence);
+        $notplugins = null;
+        list($notplugins, $params) = $DB->get_in_or_equal($auth_sequence, SQL_PARAMS_QM, '', false);
+        $DB->delete_records_select('sessions', "userid IN (SELECT id FROM {user} WHERE auth $notplugins)", $params);
+
+        /// now get a list of time-out candidates
+        $sql = "SELECT u.*, s.sid, s.timecreated AS s_timecreated, s.timemodified AS s_timemodified
+                  FROM {user} u
+                  JOIN {sessions} s ON s.userid = u.id
+                 WHERE s.timemodified + ? < ? AND u.username <> 'guest'";
+        $params = array($maxlifetime, time());
+
+        $authplugins = array();
+        foreach($auth_sequence as $authname) {
+            $authplugins[$authname] = get_auth_plugin($authname);
+        }
+        $rs = $DB->get_recordset_sql($sql, $params);
+        foreach ($rs as $user) {
+            foreach ($authplugins as $authplugin) {
+                if ($authplugin->ignore_timeout_hook($user, $user->sid, $user->s_timecreated, $user->s_timemodified)) {
+                    continue;
+                }
+            }
+            $DB->delete_records('sessions', array('sid'=>$user->sid));
+        }
+        $rs->close();
+    } catch (dml_exception $ex) {
+        error_log('Error gc-ing sessions');
+    }
 }
 
 /**
@@ -689,6 +698,7 @@ function get_moodle_cookie() {
     }
 }
 
+
 /**
  * Setup $USER object - called during login, loginas, etc.
  * Preloads capabilities and checks enrolment plugins
index 81c45ffce28a64f834adfce239d795337d744367..f765a65d7e0c651ece0d30960d9f1baf1dcf1286 100644 (file)
                 redirect("$CFG->wwwroot/user/view.php?id=$USER->id&course=$course->id");
             }            
         } else {
-            session_get_instance()->gc(); // remove stale sessions
+            session_gc(); // remove stale sessions
             redirect("$CFG->wwwroot/$CFG->admin/user.php");
         }
         //never reached