Can't Delete cookie in user class with php - php

i think my problem is a little weird, ive wrote a little class to log in/out user, entire system is based in MVC pattern, and my libraries are custom and self written,
but the problem: when i log in the user with out the $remember flag, no problems, sessions are easily set and unset. but when i activate the $remember and i create a cookie, my logout function does not work, it deletes the session but not the cookie, so cookie remains in browser with complete data, and whenever i reload the page , my class logs me in again because there is a cookie with full authentication details, the problem is with a cookie, i cant send other headers like Location: blah blah from $this->logout; ive tried different ways to unset cookie, but no luck;
this is the class:
<?php
/**
* Pars----
* Classified --- Application
*
* #author Sallar Kaboli (me#sallar.ir)
* #copyright Copyright (C) 2009 - 2010 -----CO (dev#------.us)
* #package Pars---
* #version 1.0
*/
class ParsUser {
public $userID = false;
private $_p = null;
public $userData = null;
public function __construct() {
$this->_p = ParsRegistry::getInstance();
if( $this->_p->sess->isVarSet('parsUser') ) {
$this->loadUser($this->_p->sess->getVar('parsUser'));
}
if( isset($_COOKIE['parsUser']) and !$this->isLoggedIn() ) {
$userFromCookie = unserialize(base64_decode($_COOKIE['parsUser']));
$this->checkLogin($userFromCookie['username'], $userFromCookie['password'], true, false);
}
}
public function checkLogin($username, $password, $remember = true, $hash = true) {
if(!empty($username) and !empty($password)) {
$password = $hash ? $this->_p->valid->hash($password) : $password;
$qData = array('user' => $username, 'pass' => $password);
$query = 'SELECT * FROM people WHERE `username` = :user AND `password` = :pass';
$user = $this->_p->db->getRow($query, $qData);
if(is_object($user) AND !empty($user->id)) {
$this->userID = $user->id;
$this->userData = $user;
if( $hash ) {
$this->_p->db->execute('UPDATE people SET `last_login` = ? WHERE `id` = ?', array( time(), $this->userID ));
}
$this->loginTheUser($remember);
return true;
}
else {
return false;
}
}
else {
return false;
}
}
private function loginTheUser($remember = true) {
$this->_p->sess->setVar('parsUser', $this->userID);
if( $remember ){
$rememberPeriod = $this->_p->conf->c['cookie_remember_period'];
$cookie = array(
'username' => $this->userData->username,
'password' => $this->userData->password
);
$cookie = base64_encode(serialize($cookie));
setcookie('parsUser', $cookie, time() + $rememberPeriod/*, '/', $_SERVER['HTTP_HOST']*/);
}
return false;
}
private function loadUser($userID){
$user = $this->_p->db->getRow('SELECT * FROM people WHERE `id` = ?', $userID);
if( is_object($user) and ( $user->id == $userID ) ){
$this->userID = $user->id;
$this->userData = $user;
$this->_p->sess->setVar('parsUser', $this->userID);
return true;
}
else return false;
}
public function logout($redirectTo = false) {
setcookie('parsUser', '', mktime(12,0,0,1, 1, 1990));
unset($_COOKIE['parsUser']);
$this->_p->sess->sessionDrop();
$this->userData = null;
$this->userID = false;
if ( !empty($redirectTo) ){
$this->_p->core->redirect($redirectTo);
exit;
}
}
public function isLoggedIn() {
//return ( empty($this->userID) OR !$this->userID ) ? false : true;
if( $this->userID > 0 and $this->userID != false and !empty($this->userID) )
return true;
else return false;
}
public function checkAccess($level) {
if($level == 0) {
return true;
}
elseif($this->isLoggedIn()) {
if( $this->userData->level <= $level ) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
public function getUserData() {
$args = func_get_args();
if( empty($this->userID) )
throw new Exception('User is not loaded.');
if( is_array($args) and count($args) > 0){
foreach( $args as $arg ){
if( !isset($this->userData->$arg) )
throw new Exception('Unknown property: <b>' . $property . '</b>');
else
$props[$arg] = $this->userData->$arg;
}
if( count($args) == 1 )
return $props[$args[0]];
else
return $props;
}
else{
$props = $this->userData;
unset($props->password);
return $props;
}
}
}
sorry for my english.

try to set $path in both cases (create, remove cookie)

You could set the cookie with invalid data:
setcookie('parsUser', 'trash', time() - 3600);
If this doesn't delete the cookie, it should at least create an invalid login token.
I would also recommend against base64 encoding the username and password in the cookie. It's all but plaintext to an experienced attacker. You can easily integrate strong encryption into your application using mcrypt:
http://us2.php.net/mcrypt
If that's not an option, you can use a php-only implementation of xor encrypt with strong keys. There are also php-only implementations of blowfish and Rijndael on the internet. I'd provide links if I could, but my current reputation won't let me add more than one hyperlink.

Sorry for my strange question but why do you set a cookie in history (so it's gets deleted) and then unset a cookie that doesn't exist anymore?
Hmm looks strange if you look at the output of your image...
What is the system time of your server?
Because it said the cookie would expire in 1990.. Looks like your computer/server is way behind if that is still valid :P
By the way, maybe you can't edit the data, because you need to decode the base64 encryption first (because in your code when you set it, you use the base64 function)

Related

Variable giving me undefined index off 0

I'm currently building a social network. I got to the point where I need cookies and tokens (in the database) to make people logout and login in.
The problem is that for some reason one of my variables is not getting any data from the query I wrote...
Here's the code of the page:
Cookie_login.php
<?php declare(strict_types=1);
class Login
{
public static function isloggedIn(): ?int
{
if (isset($_COOKIE['SNID'])) {
$user = DB::query(
'SELECT user_id FROM tokens WHERE token=:token',
[':token' => sha1($_COOKIE['SNID'])]
);
if (empty($user) && isset($user[0]['user_id'])) {
$userid = $user[0]['user_id'];
}
if (isset($_COOKIE['SNID_'])) {
return $userid;
}
$cstrong = true;
$token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
DB_update::query_update(
'INSERT INTO tokens VALUES (\'\',:token,:user_id)',
[':token' => sha1($token), ':user_id' => $userid]
);
DB_update::query_update('DELETE FROM tokens WHERE token=:token', [':token' => sha1($_COOKIE['SNID'])]);
setcookie('SNID', $token, time() + 60 * 60 * 24 * 7, '/', null, true, true);
return $userid;
}
return null;
}
}
and the DB.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
class DB
{
private static function connect(): PDO
{
$pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
}
public static function query($query, $params = [])
{
$statement = self::connect()->prepare($query);
$statement->execute($params);
return $statement->fetchALL();
}
}
class DB_update
{
private static function connect(): PDO
{
$pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
}
public static function query_update($query_update, $paramss = [])
{
$statement = self::connect()->prepare($query_update);
$statement->execute($paramss);
return $statement->RowCount();
}
}
I used the fopen() and fwrite() to see what $userid is returning and it was returning 1... Already check the queries in SQL and they work just fine... So I don't know why the $userid variable is not saving the user_id from the table. I hope you guys can help me...
PS:DB_update is just a name to be different from DB_query
First, of all:
fwrite($fp, print_r($userid));
Function print_r has a second parameter, default sets to false but in your case, you have to explicity set to true:
fwrite($fp, print_r($userid, true));
Otherwise, you will always write to file 1 value.
And the second. It's good idea to use function fclose to close opened file pointer if it's no longer required.
This line generates your "undefined index off 0" error:
$userid = DB::query('SELECT user_id FROM tokens WHERE token=:token',
array(':token' =>sha1($_COOKIE['SNID'])))[0]['user_id'];
Specifically, the [0]['user_id'] bit that you've patched to the end of the query. You should only ever do that if you're sure the function called will always return an array with the necessary fields (not the case with DB queries!). When there is no match, your DB::query method probably returns NULL or false (and you can't have NULL[0] etc. much less NULL[0]['user_id'], thus the error).
You'll want to postpone the offset assignment, and first of all have a logic for situations where no match happens. First put the DB query result into a variable that you can evaluate as being the expected type of resource or not -- only then assign array offsets.
$user = DB::query('SELECT user_id FROM tokens WHERE token=:token',
array(':token' =>sha1($_COOKIE['SNID'])));
if (!empty($user) && isset($user[0]['user_id'])) {
$userid = $user[0]['user_id'];
}
else {
// whatever that you need to do here.
}
On your debugging trouble; your print_r logger is only logging 1 because:
print_r ( mixed $expression [, bool $return = FALSE ] ) : mixed
... "When the $return parameter is TRUE, this function will return a string.
Otherwise, the return value is TRUE."
If you want to both print and log into a file, then use an intermediate variable, along the lines of $pr = print_r($foo, true); echo $pr; fwrite($fp, $pr);. Hope that helps you get it sorted.
Ok, that's whole code with comments:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
class DB
{
private static function connect()
{
$pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8','root','');
$pdo -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
return $pdo;
}
public static function query($query,$params=array())
{
$statement = self::connect() ->prepare($query);
$statement ->execute($params);
$data = $statement -> fetchALL();
return $data;
}
}
class DB_update
{
private static function connect()
{
$pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8','root','');
$pdo -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
return $pdo;
}
public static function query_update($query_update,$paramss=array())
{
$statement = self::connect() ->prepare($query_update);
$statement ->execute($paramss);
$datas = $statement -> RowCount();
return $datas;
}
}
/**
* Table `tokens` schema:
* CREATE TABLE `tokens` (
* `token` varchar(255) NOT NULL,
* `user_id` int(11) NOT NULL,
* PRIMARY KEY (`token`)
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8
*/
class Login
{
public static function isloggedIn()
{
if (isset($_COOKIE['SNID'])) {
$userid = DB::query('SELECT user_id FROM tokens WHERE token=:token',array(':token' =>sha1($_COOKIE['SNID'])))[0]['user_id'];
$fp = fopen('problem.txt', 'w');
fwrite($fp, print_r($userid, true));
fclose($fp);
// I don't understand, what is this ? There is no place in your code, to set that cookie in that named key
// It always be false
if (isset($_COOKIE['SNID_']))
{
return $userid;
}
else {
$cstrong = TRUE;
$token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
DB_update::query_update('INSERT INTO tokens VALUES (:token,:user_id)',array(':token'=>sha1($token),':user_id'=>$userid));
DB_update::query_update('DELETE FROM tokens WHERE token=:token',array(':token'=>sha1($_COOKIE['SNID'])));
setcookie("SNID", $token, time() + 60 * 60 * 24 * 7, '/', NULL, TRUE, TRUE);
// I don't understand what is this below
setcookie("SNID:", '1', time() + 60 * 60 * 24 * 3, '/', NULL, TRUE, TRUE);
return $userid;
}
}
return false;
}
}
// Uncomment code below to log in
// $userIdToLogIn = 19; // You can change it to any other value
// $cstrong = true;
// $token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
// DB_update::query_update('INSERT INTO tokens VALUES (:token, :user_id)', array(':token' => sha1($token), ':user_id' => $userIdToLogIn));
// setcookie("SNID", $token, time() + 60 * 60 * 24 * 7, '/', NULL, TRUE, TRUE);
// ------------------------------
// Uncomment code below to log out
// setcookie("SNID", time() - 3600);
// -------------------------------
// And check
$userId = Login::isloggedIn();
if($userId) {
printf(
"User with id: %s is logger in with token: %s",
$userId,
DB::query('SELECT token FROM tokens WHERE user_id = :user_id', array(':user_id' => $userId))[0]['token']
);
} else {
echo "User is not logger in!";
}
And now:
Uncomment lines for comment: Uncomment code below to log in for first request. Script log in you.
Comment it back for second and nexts requests to check how it works.

Secure a class for a form hydratation : is this a good way?

I use PHP classes for managing users accounts and I wonder if what I'm doing is correct.
I directly use the $_POST['form'] for hydrate User objects.
But there is some field that I don't want user to modify (i.e. : Id_user, admin_level,...) so i use an argument in each setID or setAdmin_level (a boolean called $force) :
public function __construct(array $donnees = null, $forcer = false)
{
if($donnees){
$this->hydrate($donnees,$forcer);
}
}
public function hydrate(array $donnees, $forcer = false)
{
foreach($donnees as $champ => $valeur){
$method = 'set'.ucfirst($champ);
if(method_exists($this,$method))
{
if($forcer){
try {
$this->$method($this->securite($valeur), true);
}catch(Exception $e){
$this->$method($this->securite($valeur));
}
}else {
$this->$method($this->securite($valeur));
}
}
}
}
Here is an example of a "secured" setter :
public function setId_user($id_user, $forcer = false)
{
if(is_numeric($id_user)&&$forcer)
{
$this->_id_user = $id_user;
return true;
}else {
$this->addErreur('id_user','User ID incorrect');
return false;
}
}
So, in order to register a new user, I hydrate a new User object with the form POST :
$user = new User($_POST[form], false);
And I need to set the $force bool to true for creating a new User from an Id or if I want to set a field protected.
$userManager->getUserFromId(new User(['id_user' => 1], true));
Or
$userManager->getUserFromEmail(new User(['email' => "my_email#email.com"], true));
Is this a good way?

Custom PHP SessionHandler class Write issue

I'm creating my own custom SessionHandler to store my session information in a postgresql 9.3 database and I'm having a problem where the session data passed to the write() method isn't being written to the database, but the session name is??
Things that I know for a fact
My custom class is handling the sessions when session_start() is called - as tested with echoing output from the various methods and no session files are being created in /tmp
The $session_data arg in write() contains the proper serialized string as shown by echoing the contents in the write() method.
$session_name is being written to the database just fine and so is a BLANK serialized string a:0:{}.
Things I'm confused about:
Echoing the contents of $_SESSION['test_var1'] shows the correct value stored, even if read() is empty or returning no value??
If the session name is saved in the DB just fine, why isn't the session data?
Server Configuration
OS: Gentoo
Database: Postgresql 9.3
Web Server: NGINX 1.7.6
PHP 5.5.18 connected to NGINX via FPM
PHP ini session settings
session.save_handler = user
session.use_strict_mode = 1
session.use_cookies = 1
session.cookie_secure = 1
session.use_only_cookies = 1
session.name = _g
session.auto_start = 0
session.serialize_handler = php_serialize
class SessionManagement implements SessionHandlerInterface {
private $_id = '';
private $_link = null;
public function __construct() {
session_set_save_handler(
[$this, 'open'],
[$this, 'close'],
[$this, 'read'],
[$this, 'write'],
[$this, 'destroy'],
[$this, 'gc']
);
}
public function open($save_path, $session_id) {
echo 'open called<br/>';
$this->_id = $session_id;
$this->_link = new PDO('pgsql:host=' . $_SERVER['DB_HOST'] . ';dbname=' . $_SERVER['DB_DB'],
$_SERVER['DB_USER'],
$_SERVER['DB_PASS']);
}
public function close() {
echo 'close called<br/>';
}
public function destroy($session_id) {
echo 'destroying '.$session_id, '<br/>';
}
public function gc($maxlifetime) {
echo 'GC called<br/>';
}
public function read($session_name) {
$name = $this->_id.'_'.$session_name;
$sql = 'SELECT session_data FROM sessions WHERE session_name = :name';
if ($rel = $this->_link->prepare($sql)) {
if ($rel->execute([':name' => $name])) {
return $rel->fetch(PDO::FETCH_ASSOC)['session_data'];
} else {
return false;
}
} else {
return false;
}
return '';
}
public function write($session_name, $session_data) {
echo 'Session data: '.$session_data.'<br/>';
$name = $this->_id . '_' . $session_name;
$data = $session_data;
$sql = "SELECT 1 FROM sessions WHERE session_name = :name";
if ($rel = $this->_link->prepare($sql)) {
if ($rel->execute([':name' => $name])) {
if ($rel->rowCount()) {
echo 'Updating...<br/>';
$sql = 'UPDATE sessions SET session_data = :data WHERE session_name = :name';
if ($rel = $this->_link->prepare($sql)) {
if ($rel->execute([':name' => $name, ':data' => $data])) {
echo 'Update success...<br/>';
} else {
echo 'Update failed...<br/>';
var_dump($rel->errorInfo());
}
}
} else {
echo 'Inserting...<br/>';
$sql = 'INSERT INTO sessions (session_name, session_data) ';
$sql .= 'VALUES(:name, :data)';
if ($rel = $this->_link->prepare($sql)) {
if ($rel->execute([':name' => $name, ':data' => $data])) {
echo 'Insert success...<br/>';
} else {
echo 'Insert failed...<br/>';
var_dump($rel->errorInfo());
}
}
}
}
}
}
}
Test code:
new SessionManagement();
session_start();
$_SESSION['test_var1'] = 'some test data';
session_write_close(); // Making sure writing is finished
echo $_SESSION['test_var1'];
Output via test page
open called
Session data: a:1:{s:9:"test_var1";s:14:"some test data";}
Inserting...
Insert success...
close called
some test data
Relevant database fields
session_name: _g_h8m64bsb7a72dpj56vgojn6f4k3ncdf97leihcqfupg2qtvpbo20
session_data: a:0:{}
I'm not sure if this is a database issue or a PHP issue. I've been messing with this for a few days now and decided it was time to ask the community. Hopefully someone has some insight as to what the problem is.
I think you must initialize PDO object outside of the Open function handler and the class itself
try to access to your PDO Object with a Global value or through a static variable.
This is my implementation with MYSQL for my project :
class Core_DB_SessionHandler implements SessionHandlerInterface
{
protected $options = array(); // Options de la session
protected static $db = NULL; // Acceder a la BDD
public function __construct($options, $pdo) {
$this->options = $options;
self::$db = $pdo;
}
public function open($savePath, $sessionName) {
$now = time();
$req = self::$db->prepare("DELETE FROM tbl_sessions WHERE expire < '{1}' ");
$req->execute(array($now));
return TRUE;
}
public function close() {
$this->gc(ini_get('session.gc_maxlifetime'));
}
public function read($id) {
$now = time();
$stmt = self::$db->query("SELECT data FROM tbl_sessions WHERE sid = '$id AND expire < '$now'");
$result = $stmt->fetchColumn();
return $result;
}
public function write($id, $data) {
if (array_key_exists('TIMEOUT', $_SESSION)) {
$newExp = $_SESSION['TIMEOUT'];
}
else {
$newExp = time() + $this->options['time_limiter'];
}
try {
$req = self::$db->prepare('INSERT INTO tbl_sessions (sid, data, expire) VALUES (:sid, :data, :expire)
ON DUPLICATE KEY UPDATE data = :data, expire = :expire');
$vals = array('sid' => $id, 'data' => $data, 'expire' => $newExp);
$req->execute($vals);
return TRUE;
}
catch (PDOException $e) {
throw new Core_Exception(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e);
}
}
public function destroy($id) {
$stmt = self::$db->prepare("DELETE FROM tbl_sessions WHERE sid = '{1}'");
$stmt->execute(array($id));
//return ($stmt->rowCount() === 1) ? true : false;
return TRUE;
}
public function gc($maxlifetime) {
$now = time();
$req = self::$db->prepare("DELETE FROM tbl_sessions WHERE expire < '{1}' ");
$req->execute(array($now));
return TRUE;
}
}
and i initialize handler like this :
$handler = new Core_DB_SessionHandler($MyOptions, $MyPDO);
if (PHP5) {
if (!session_set_save_handler($handler, TRUE)) {
throw new Core_Exception('Erreur lors de l\'init des sessions !');
}
}
nb : In your Table structure don't use autoincrement for ID
Well, I've solved my problem, but it's hard to say if this fix was actually the problem in the first place.
In the read method, I changed the follow:
return $rel->fetch(PDO::FETCH_ASSOC)['session_data'];
to
$data $rel->fetch(PDO::FETCH_ASSOC)['session_data'];
return $data;
After this the session was writing $session_data to the database without any problem. That's all well and dandy, but it doesn't explain why it didn't work in the first place. I mainly say this because upon switching the statement back everything continued to work. As in, I can't reproduce the issue now. So it's hard for me to even say that this was the problem in the first place.
Hopefully this helps someone. I've been unable to find more information about it, but it something does show up I'll be sure to add it here.

Check if a User is Logged On In a PHP Login System

I'm relatively new to PHP and have been making a PHP login system. It works fine and all, but I'm wondering if there's a cleaner and more efficient way to check if a user is logged in. At the current moment my code looks like this:
session_start();
if(isset($_SESSION['username']))
{
Echo "*Whole bunch of HTML*";
}
else{
header("location:index.php");
end();
}
I want to make it to where the if statement checks if the user is logged in and nothing more, rather than having the if statement check if the user is logged in then displaying the page within in the if statement. Is this possible?
You are doing things ok. But here is what I do for my code:
function checklogin() {
if (!$this->isLoggedIn())
return false;
else
return true;
}
function isLoggedIn() {
if (isset($_SESSION['user_id']) && isset($_SESSION['user_email'])) {
if( !$this->isTimeOut() )
return false;
$where = array(
'id' => $_SESSION['user_id'],
'email' => $_SESSION['user_email']
);
//this is database class method
$value['data'] = $dataBaseClass->login_access($where);
if ($value['data'] != FALSE && $_SESSION['user_id'] == $value['data']->id && $_SESSION['user_email'] == $value['data']->email) {
return true;
}
/*
username or userlevel not exist or s_ecryption session invalid
User not logged in.
*/
else
return false;
}
/**
* cookie check for user login || you can escape this
*/
else if (isset($_COOKIE['cookie_key']) && $_COOKIE['cookie_key'] != '') {
$cookie_key = $_COOKIE['cookie_key'];
$where = array(
'cookie_key' => $cookie_key
);
$user_data = $databaseClass->login_access($where);
if (!empty($user_data)) {
$_SESSION['user_id'] = $user_data->id;
$_SESSION['user_email'] = $user_data->email;
return true;
}
} else {
return false;
}
}
Make a library/functions file, write above code, include that file in class files you need and call the function.
Hope this helps.

Mediawiki authenication replacement showing "Login Required" instead of signing user into wiki

I'm fairly to MediaWiki and needed a way to automatically log users in after they authenticated to a central server (which creates a session and cookie for applications to use).
I wrote a custom authentication extension based off of the LDAP Authentication extension and a few others. The extension simply needs to read some session data to create or update a user and then log them in automatically. All the authentication is handled externally. A user would not be able to even access the wiki website without logging in externally.
This extension was placed into production which replaced the old standard MediaWiki authentication system. I also merged user accounts to prepare for the change. By default, a user must be logged in to view, edit, or otherwise do anything in the wiki.
My problem is that I found if a user had previously used the built-in MediaWiki authentication system and returned to the wiki, my extension would attempt to auto-login the user, however, they would see a "Login Required" page instead of the page they requested like they were an anonymous user. If the user then refreshed the page, they would be able to navigate, edit, etc.
From what I can tell, this issue resolves itself after the UserID cookie is reset or created fresh (but has been known to strangely come up sometimes). To replicate, if there is an older User ID in the "USERID" cookie, the user is shown the "Login Required" page which is a poor user experience. Another way of showing this page is by removing the user account from the database and refreshing the wiki page. As a result, the user will again see the "Login Required" page.
Does anyone know how I can use debugging to find out why MediaWiki thinks the user is not signed in when the cookies are set properly and all it takes is a page refresh?
Here is my extension (simplified a little for this post):
<?php
$wgExtensionCredits['parserhook'][] = array (
'name' => 'MyExtension',
'author' => '',
);
if (!class_exists('AuthPlugin')) {
require_once ( 'AuthPlugin.php' );
}
class MyExtensionPlugin extends AuthPlugin {
function userExists($username) {
return true;
}
function authenticate($username, $password) {
$id = $_SESSION['id'];
if($username = $id) {
return true;
} else {
return false;
}
}
function updateUser(& $user) {
$name = $user->getName();
$user->load();
$user->mPassword = '';
$user->mNewpassword = '';
$user->mNewpassTime = null;
$user->setRealName($_SESSION['name']);
$user->setEmail($_SESSION['email']);
$user->mEmailAuthenticated = wfTimestampNow();
$user->saveSettings();
return true;
}
function modifyUITemplate(& $template) {
$template->set('useemail', false);
$template->set('remember', false);
$template->set('create', false);
$template->set('domain', false);
$template->set('usedomain', false);
}
function autoCreate() {
return true;
}
function disallowPrefsEditByUser() {
return array (
'wpRealName' => true,
'wpUserEmail' => true,
'wpNick' => true
);
}
function allowPasswordChange() {
return false;
}
function setPassword( $user, $password ) {
return false;
}
function strict() {
return true;
}
function initUser( & $user ) {
}
function updateExternalDB( $user ) {
return false;
}
function canCreateAccounts() {
return false;
}
function addUser( $user, $password ) {
return false;
}
function getCanonicalName( $username ) {
return $username;
}
}
function SetupAuthMyExtension() {
global $wgHooks;
global $wgAuth;
$wgHooks['UserLoadFromSession'][] = 'Auth_MyExtension_autologin_hook';
$wgHooks['UserLogoutComplete'][] = 'Auth_MyExtension_UserLogoutComplete';
$wgHooks['PersonalUrls'][] = 'Auth_MyExtension_personalURL_hook';
$wgAuth = new MyExtensionPlugin();
}
function Auth_MyExtension_autologin_hook($user, &$return_user ) {
global $wgUser;
global $wgAuth;
global $wgContLang;
wfSetupSession();
// Give us a user, see if we're around
$tmpuser = new User() ;
$rc = $tmpuser->newFromSession();
$rc = $tmpuser->load();
if( $rc && $rc->isLoggedIn() ) {
if ( $rc->authenticate($rc->getName(), '') ) {
return true;
} else {
$rc->logout();
}
}
$id = trim($_SESSION['id']);
$name = ucfirst(trim($_SESSION['name']));
if (empty($dsid)) {
$result = false; // Deny access
return true;
}
$user = User::newFromName($dsid);
if (0 == $user->getID() ) {
// we have a new user to add...
$user->setName( $id);
$user->addToDatabase();
$user->setToken();
$user->saveSettings();
$ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
$ssUpdate->doUpdate();
} else {
$user->saveToCache();
}
// update email, real name, etc.
$wgAuth->updateUser( $user );
$result = true;
// Go ahead and log 'em in
$user->setToken();
$user->saveSettings();
$user->setupSession();
$user->setCookies();
return true;
}
function Auth_MyExtension_personalURL_hook(& $personal_urls, & $title) {
global $wgUser;
unset( $personal_urls['mytalk'] );
unset($personal_urls['Userlogin']);
$personal_urls['userpage']['text'] = $wgUser->getRealName();
foreach (array('login', 'anonlogin') as $k) {
if (array_key_exists($k, $personal_urls)) {
unset($personal_urls[$k]);
}
}
return true;
}
function Auth_MyExtension_UserLogoutComplete(&$user, &$inject_html, $old_name) {
setcookie( $GLOBALS['wgCookiePrefix'] . '_session', '', time() - 3600, $GLOBALS['wgCookiePath']);
setcookie( $GLOBALS['wgCookiePrefix'] . 'UserName', '', time() - 3600, $GLOBALS['wgCookiePath']);
setcookie( $GLOBALS['wgCookiePrefix'] . 'UserID', '', time() - 3600, $GLOBALS['wgCookiePath']);
setcookie( $GLOBALS['wgCookiePrefix'] . 'Token', '', time() - 3600, $GLOBALS['wgCookiePath']);
return true;
}
?>
Here is part of my LocalSettings.php file:
#############################
# Disallow Anonymous Access
#############################
$wgGroupPermissions['*']['read'] = false;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['createpage'] = false;
$wgGroupPermissions['*']['createtalk'] = false;
$wgGroupPermissions['*']['createaccount'] = false;
$wgShowIPinHeader = false; # For non-logged in users
#############################
# Extension: MyExtension
#############################
require_once("$IP/extensions/MyExtension.php");
$wgAutoLogin = true;
SetupAuthMyExtension();
$wgDisableCookieCheck = true;
I found out the reason why this problem was occuring. When a user had previously signed into the wiki an old cookie with the old user id was set. Mediawiki attempted to read this cookie and found that it did not match the database so for security purposes, a "login required" page was shown to the user.
To get passed this issue, users can simply refresh the page, clear their cookies prior to login, or the admin can allow guest access to read pages.
Alternatively, a change to the core file set can be made temporarily to bypass the check.

Categories