| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * GNU social's implementation of SessionHandler | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * StatusNet - the distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2009, StatusNet, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program 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 Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (!defined('GNUSOCIAL')) { | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Superclass representing the associated interfaces of session handling. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author GNU social | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class InternalSessionHandler implements SessionHandlerInterface | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * A helper function to print a session-related message to the debug log if | 
					
						
							|  |  |  |      * the site session debug configuration option is enabled. | 
					
						
							|  |  |  |      * @param $msg | 
					
						
							|  |  |  |      * @return void | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function logdeb($msg) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (common_config('sessions', 'debug')) { | 
					
						
							|  |  |  |             common_debug("Session: " . $msg); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Dummy option for saving to file needed for full PHP adherence. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param $save_path | 
					
						
							|  |  |  |      * @param $session_name | 
					
						
							|  |  |  |      * @return bool true | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function open($save_path, $session_name) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Dummy option for saving to file needed for full PHP adherence. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return bool true | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function close() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Fetch the session data for the session with the given $id. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param $id | 
					
						
							|  |  |  |      * @return string Returns an encoded string of the read data. If nothing was read, it must return an empty string. Note this value is returned internally to PHP for processing. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function read($id) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |         self::logdeb("Fetching session '$id'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $session = Session::getKV('id', $id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($session)) { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |             self::logdeb("Couldn't find '$id'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |             return ''; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             self::logdeb("Found '$id', returning " . | 
					
						
							|  |  |  |                          strlen($session->session_data) . | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |                          " chars of data."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |             return (string)$session->session_data; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Write the session data for session with given $id as $session_data. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param $id | 
					
						
							|  |  |  |      * @param $session_data | 
					
						
							|  |  |  |      * @return bool Returns TRUE on success or FALSE on failure. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function write($id, $session_data) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |         self::logdeb("Writing session '$id'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $session = Session::getKV('id', $id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($session)) { | 
					
						
							|  |  |  |             self::logdeb("'$id' doesn't yet exist; inserting."); | 
					
						
							|  |  |  |             $session = new Session(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $session->id = $id; | 
					
						
							|  |  |  |             $session->session_data = $session_data; | 
					
						
							|  |  |  |             $session->created = common_sql_now(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $result = $session->insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!$result) { | 
					
						
							|  |  |  |                 common_log_db_error($session, 'INSERT', __FILE__); | 
					
						
							|  |  |  |                 self::logdeb("Failed to insert '$id'."); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 self::logdeb("Successfully inserted '$id' (result = $result)."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return (bool) $result; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             self::logdeb("'$id' already exists; updating."); | 
					
						
							|  |  |  |             if (strcmp($session->session_data, $session_data) == 0) { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |                 self::logdeb("Not writing session '$id' - unchanged."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |                 return true; | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |                 self::logdeb("Session '$id' data changed - updating."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |                 // Only update the required field
 | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |                 $orig = clone($session); | 
					
						
							|  |  |  |                 $session->session_data = $session_data; | 
					
						
							|  |  |  |                 $result = $session->update($orig); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (!$result) { | 
					
						
							|  |  |  |                     common_log_db_error($session, 'UPDATE', __FILE__); | 
					
						
							|  |  |  |                     self::logdeb("Failed to update '$id'."); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     self::logdeb("Successfully updated '$id' (result = $result)."); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return (bool) $result; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Find sessions that have persisted beyond $maxlifetime and delete them. | 
					
						
							|  |  |  |      * This will be limited by config['sessions']['gc_limit'] - it won't delete | 
					
						
							|  |  |  |      * more than the number of sessions specified there at a single pass. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param $maxlifetime | 
					
						
							|  |  |  |      * @return bool Returns TRUE on success or FALSE on failure. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function gc($maxlifetime) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |         self::logdeb("Garbage Collector has now started with maxlifetime = '$maxlifetime'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $epoch = common_sql_date(time() - $maxlifetime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $ids = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $session = new Session(); | 
					
						
							|  |  |  |         $session->whereAdd('modified < "' . $epoch . '"'); | 
					
						
							|  |  |  |         $session->selectAdd(); | 
					
						
							|  |  |  |         $session->selectAdd('id'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $limit = common_config('sessions', 'gc_limit'); | 
					
						
							|  |  |  |         if ($limit > 0) { | 
					
						
							|  |  |  |             // On large sites, too many sessions to expire
 | 
					
						
							|  |  |  |             // at once will just result in failure.
 | 
					
						
							|  |  |  |             $session->limit($limit); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $session->find(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         while ($session->fetch()) { | 
					
						
							|  |  |  |             $ids[] = $session->id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $session->free(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |         self::logdeb("Garbage Collector found " . count($ids) . " ids to delete."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($ids as $id) { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |             self::logdeb("Garbage Collector will now delete session '$id'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |             self::destroy($id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Deletes session with given id $id. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param $id | 
					
						
							|  |  |  |      * @return bool Returns TRUE on success or FALSE on failure. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function destroy($id) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |         self::logdeb("Destroying session '$id'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $session = Session::getKV('id', $id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($session)) { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |             self::logdeb("Can't find '$id' to destroy."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $result = $session->delete(); | 
					
						
							|  |  |  |             if (!$result) { | 
					
						
							|  |  |  |                 common_log_db_error($session, 'DELETE', __FILE__); | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |                 self::logdeb("Failed to destroy '$id'."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2019-05-22 23:39:34 +01:00
										 |  |  |                 self::logdeb("Successfully destroyed '$id' (result = $result)."); | 
					
						
							| 
									
										
										
										
											2019-05-14 22:57:45 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             return (bool) $result; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |