This repository has been archived on 2024-06-26. You can view files and clone it, but cannot push or open issues or pull requests.
sakura/libraries/Session.php

193 lines
5.1 KiB
PHP
Raw Normal View History

<?php
2016-02-03 22:22:56 +00:00
/**
* Holds the session handler.
2016-03-08 23:07:58 +00:00
*
2016-02-03 22:22:56 +00:00
* @package Sakura
*/
namespace Sakura;
/**
2016-02-02 21:04:15 +00:00
* User session handler.
2016-03-08 23:07:58 +00:00
*
* @package Sakura
2016-02-02 21:04:15 +00:00
* @author Julian van de Groep <me@flash.moe>
*/
class Session
{
2016-02-02 21:04:15 +00:00
/**
* The ID of the user this session is from.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $userId = 0;
2016-02-02 21:04:15 +00:00
/**
* The ID of the session.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var string
*/
public $sessionId = "";
2016-02-02 21:04:15 +00:00
/**
* Constructor.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @param int $userId The ID of the user.
* @param int $sessionId The active session ID.
*/
public function __construct($userId, $sessionId = null)
{
// Check if a PHP session was already started and if not start one
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
}
2016-03-31 20:03:25 +00:00
// Set the supposed session data
$this->userId = $userId;
$this->sessionId = $sessionId;
}
2016-02-02 21:04:15 +00:00
/**
* Destroy the active session.
*/
public function destroy()
{
// Invalidate the session key
2016-02-25 16:06:29 +00:00
DB::table('sessions')
->where('session_key', $this->sessionId)
->where('user_id', $this->userId)
->delete();
// Unset userId and sessionId
unset($this->userId);
unset($this->sessionId);
// Destroy the session
2016-03-31 20:03:25 +00:00
session_regenerate_id(true);
session_destroy();
}
2016-02-02 21:04:15 +00:00
/**
* Destroy all sessions from this user.
*/
2015-11-20 12:21:12 +00:00
public function destroyAll()
{
// Delete all database entries with this user in it
2016-02-25 16:06:29 +00:00
DB::table('sessions')
->where('user_id', $this->userId)
->delete();
2015-11-20 12:21:12 +00:00
// Destroy this session to finish it off
$this->destroy();
}
2016-02-02 21:04:15 +00:00
/**
* Create a new session.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @param boolean $permanent Is this a permanent session?
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @return string The session key.
*/
public function create($permanent)
{
// Generate session key
$session = hash('sha256', $this->userId . base64_encode('sakura' . mt_rand(0, 99999999)) . time());
// Insert the session into the database
2016-02-25 16:06:29 +00:00
DB::table('sessions')
->insert([
'user_id' => $this->userId,
2016-03-27 21:18:57 +00:00
'user_ip' => Net::pton(Net::ip()),
2016-02-25 16:06:29 +00:00
'user_agent' => Utils::cleanString(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'No user agent header.'),
'session_key' => $session,
'session_start' => time(),
'session_expire' => time() + 604800,
'session_remember' => $permanent ? '1' : '0',
]);
// Return the session key
return $session;
}
2016-02-02 21:04:15 +00:00
/**
* Validate the session.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @return int Success indicator; 0 = false, 1 = active, 2 = permanent.
*/
public function validate()
{
// Get session from database
2016-02-25 16:06:29 +00:00
$session = DB::table('sessions')
->where('user_id', $this->userId)
->where('session_key', $this->sessionId)
->get();
// Check if we actually got something in return
if (!$session) {
return 0;
}
// Check if the session expired
2016-02-25 16:06:29 +00:00
if ($session[0]->session_expire < time()) {
// ...and return false
return 0;
}
// IP Check
2016-02-18 23:28:44 +00:00
$ipCheck = false; // Forced disabled due to incompatibility with the Net class. -- Config::get('session_check');
// Origin checking
if ($ipCheck) {
// Split both IPs up
2016-02-25 16:06:29 +00:00
$sessionIP = explode('.', $session[0]->user_ip);
2016-03-27 21:18:57 +00:00
$userIP = explode('.', Net::ip());
// Take 1 off the ipCheck variable so it's equal to the array keys
$ipCheck = $ipCheck - 1;
// Check if the user's IP is similar to the session's registered IP
switch ($ipCheck) {
// 000.xxx.xxx.xxx
case 3:
if ($userIP[3] !== $sessionIP[3]) {
return 0;
}
// xxx.000.xxx.xxx
case 2:
case 3:
if ($userIP[2] !== $sessionIP[2]) {
return 0;
}
// xxx.xxx.000.xxx
case 1:
case 2:
case 3:
if ($userIP[1] !== $sessionIP[1]) {
return 0;
}
// xxx.xxx.xxx.000
case 0:
case 1:
case 2:
case 3:
if ($userIP[0] !== $sessionIP[0]) {
return 0;
}
}
}
// If the remember flag is set extend the session time
2016-02-25 16:06:29 +00:00
if ($session[0]->session_remember) {
DB::table('sessions')
->where('session_id', $session[0]->session_id)
->update(['session_expire' => time() + 604800]);
}
// Return 2 if the remember flag is set and return 1 if not
2016-02-25 16:06:29 +00:00
return $session[0]->session_remember ? 2 : 1;
}
}