Different authentication for different classes using Restler - php

I'm trying to build a REST api(using Restler) which takes in username and password for login and generates a session key. Once sessionkey is generated, user will be able to pass this session key to access other classes in the api. Is it possible to get the name of the class that invokes __isAuthenticated function?
My Auth Class:
<?php
class Auth implements iAuthenticate
{
public static $sessionKey;
public static $currentUser;
public $tempsesskey;
function __isAuthenticated ()
{
if (isset($_GET['useremail']) && isset($_GET['userpass'])) {
$user = $_GET['useremail'];
$pass = $_GET['userpass'];
$user = mysql_real_escape_string($user);
$pass = mysql_real_escape_string($pass);
mysql_query(
"UPDATE `userdetail` SET lastlogin=NOW()
WHERE useremail='$user' AND userpass=md5('$pass')");
if (mysql_affected_rows() > 0) {
$result = mysql_query(
"SELECT sessionkey from usersession where TIMESTAMPDIFF(MINUTE,lastactivity,now()) < 20 and useremail='$user'");
while ($row = mysql_fetch_assoc($result)) {
$tempsesskey = $row['sessionkey'];
}
if (strlen($tempsesskey) > 0) {
mysql_query(
"UPDATE usersession set lastactivity=now() where sessionkey='$tempsesskey'");
} else {
$tempsesskey = generateKey(52);
mysql_query(
"UPDATE `usersession` set sessionkey='$tempsesskey',keyvalid='Y' where useremail='$user'");
}
self::$currentUser = $user;
self::$sessionKey = $tempsesskey;
return TRUE;
}
} else
if (isset($_GET['sessionkey'])) {
$sesskey = $_GET['sessionkey'];
$sesskey = mysql_real_escape_string($sesskey);
$result = mysql_query(
"SELECT sessionkey from usersession where sessionkey='$sesskey' and TIMESTAMPDIFF(MINUTE,lastactivity,now()) < 20");
if (mysql_affected_rows() > 0) {
while ($row = mysql_fetch_assoc($result)) {
$tempsesskey = $row['sessionkey'];
self::$sessionKey = $tempsesskey;
}
return TRUE;
}
}
}
}

There is a simple way of setting the property on the Authentication class by adding custom php doc comment /annotation which is explained in Authentication with ACL. You can use the same technique for your purpose as well

Related

PHP duplicate check - isUnique()

function isUnique($email){
$query = "select * from registerform where email='$email'";
global $db;
$result = $db->query($query);
if($result->num_rows > 0){
return false;
}
else return true;
}
function isUnique($username){
$query = "select * from registerform where username='$username'";
global $db;
$result = $db->query($query);
if($result->num_rows > 0){
return false;
}
else return true;
}
error code: Cannot redeclare a function previously declared, how do I make it check the duplicate for email and username?
if I remove 1 of the code it is completely fine.
You could also make a generique function such as
function isUnique($field, $value)
{
$query = "select * from registerform where $field='$value'";
global $db;
$result = $db->query($query);
return $result->num_rows > 0
}
You should also check how to sanitize inputs => https://xkcd.com/327/
You have to rename the function name, e.g.: isUniqueEmail and isUniqueUsername
You cannot have two functions with the exact same name.

Memory Leak or Connection not closed

I am having three files index.php, DB_Function, DB_Connect to connect through mysql server. But response is very slow and task is almost running according to the hosting server people.
index.php
if (isset($_POST['tag']) && $_POST['tag'] != '') {
// get tag
$tag = $_POST['tag'];
// include db handler
require_once 'DB_Functions.php';
$db = new DB_Functions();
// response Array
$response = array("tag" => $tag, "success" => 0, "error" => 0);
// check for tag type
if ($tag == 'login') {
// Request type is check Login
$email = $_POST['email'];
$password = $_POST['password'];
// check for user
$user = $db->getUserByEmailAndPassword($email, $password);
if ($user != false) {
// user found
// echo json with success = 1
$uservalue= $user["userid"];
$usercal = $db->getUserByuserid($uservalue);
if ($usercal != false) {
$response["usercal"]["userid"] = $usercal["userid"];
$response["usercal"]["newcalorie"] = $usercal["newcalorie"];
$response["usercal"]["oldcalorie"] = $usercal["oldcalorie"];
$response["usercal"]["flag"] = $usercal["flag"];
$response["usercal"]["fat"] = $usercal["fat"];
$response["usercal"]["carbohydrate"] = $usercal["carbohydrate"];
$response["usercal"]["protein"] = $usercal["protein"];
$response["usercal"]["startdate"] = $usercal["startdate"];
$response["usercal"]["enddate"] = $usercal["enddate"];
$response["usercal"]["createddate"] = $usercal["createddate"];
$response["usercal"]["updateddate"] = $usercal["updateddate"];
$response["usercal"]["createdby"] = $usercal["createdby"];
$response["usercal"]["updatedby"] = $usercal["updatedby"];
}
$response["success"] = 1;
$response["user"]["userid"] = $user["userid"];
$response["user"]["fname"] = $user["fname"];
$response["user"]["email"] = $user["email"];
$response["user"]["altemail"] = $user["altemail"];
$response["user"]["age"] = $user["age"];
$response["user"]["gender"] = $user["gender"];
$response["user"]["weight"] = $user["weight"];
$response["user"]["unit"] = $user["unit"];
$response["user"]["height"] = $user["height"];
$response["user"]["weightgoal"] = $user["weightgoal"];
$response["user"]["activitylevel"] = $user["activitylevel"];
$response["user"]["exerciselevel"] = $user["exerciselevel"];
$response["user"]["disease"] = $user["disease"];
$response["user"]["createddate"] = $user["createddate"];
$response["user"]["updateddate"] = $user["updateddate"];
$response["user"]["createdby"] = $user["createdby"];
$response["user"]["updatedby"] = $user["updatedby"];
echo json_encode($response);
} else {
// user not found
// echo json with error = 1
$response["error"] = 1;
$response["error_msg"] = "Incorrect email or password!";
echo json_encode($response);
}
}
else {
echo "Access Denied";
}
?>
DB_Function.php
<?php
class DB_Functions {
private $db;
//put your code here
// constructor
function __construct() {
require_once 'DB_Connect.php';
// connecting to database
$this->db = new DB_Connect();
$this->db->connect();
}
// destructor
function __destruct() {
}
/**
* Get user by email and password
*/
public function getUserByEmailAndPassword($email, $password) {
$result = mysql_query("SELECT * FROM userDetails WHERE email = '$email' AND password = '$password'") or die(mysql_error());
// check for result
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
$result = mysql_fetch_array($result);
return $result;
} else {
// user not found
return false;
}
}
/**
* Get user by email and password
*/
public function getUserByuserid($uservalue) {
$result = mysql_query("SELECT * FROM CalorieInfo WHERE userid= '$uservalue' ") or die(mysql_error());
// check for result
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
$result = mysql_fetch_array($result);
return $result;
} else {
$calresult = mysql_query("INSERT INTO CalorieInfo( userid,startdate, createddate, updateddate,createdby,updatedby) VALUES('$uservalue' ,NOW(), NOW(), NOW(),'$uservalue','$uservalue')");
if ($calresult) {
$id = mysql_insert_id();
$calresult = mysql_query("SELECT * FROM CalorieInfo WHERE id = $id");
return mysql_fetch_array($calresult);
}else{
// user not found
return false;
}
}
}
?>
DB_Connect.php
<?php
class DB_Connect {
// constructor
function __construct() {
//this->connect();
}
// destructor
function __destruct() {
//closing db
}
// Connecting to database
public function connect() {
require_once 'config.php';
// connecting to mysql
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die(mysql_error());
// selecting database
mysql_select_db(DB_DATABASE) or die(mysql_error());
// return database handler
return $con;
}
// Closing database connection
public function close() {
mysql_close();
}
}
?>
Is there anything more optimized that i should be aware of ?
Is something missing in my code. Hosting people says that tomcat and mysql is consuming more task.
Here are my recommendations
1.- Always close the connection after retrieving the data.
2.- If you are expecting just one row for a query like this
"SELECT * FROM userDetails WHERE email = '$email' AND password = '$password'
you should add LIMIT 1 at the end of the query for retrieving the only possible row
3.-Add indexes to the table
4.-Test your performance with mysqlslap

php class return array

I tried to get followers from MySQL usingy this class
class get_followers {
public $followers_arr = array();
public function __construct($user_id) {
$query = "select * from followsystem where following ='$user_id'";
$q = mysql_query($query) or die(mysql_error());
$count = mysql_num_rows($q);
if ($count > 0) {
while ($row = mysql_fetch_assoc($q)) {
array_push($this->followers_arr, $row['userid']);
}
}
return $this->followers_arr;
}
}
Then I initialize this class
$fol = new get_followers($userid);
$fol_arr = json_encode($fol);
echo $fol_arr;
Then I get
{"followers_arr":["1234","456"]}
but what i want want just to get this
["1234","456"]
How is that works?
I don't think you understand how constructors work. You can't return a value from a constructor because it's just used to instantiate the object. When you're doing $fol_arr = json_encode($fol); you're actually encoding the entire object, not it's return value.
If you really want to use a class to do this, you should add a method to the class and use that, like this:
class Followers {
public $followers_arr = array();
public $user_id = null;
public function __construct($user_id) {
$this->user_id = $user_id;
}
public function get()
{
$query = "select * from followsystem where following ='{$this->user_id}'";
$q = mysql_query($query) or die(mysql_error());
$count = mysql_num_rows($q);
if ($count > 0) {
while ($row = mysql_fetch_assoc($q)) {
array_push($this->followers_arr, $row['userid']);
}
}
return $this->followers_arr;
}
}
And use it like this:
$fol = new Followers($userid);
$fol_arr = json_encode($fol->get());
echo $fol_arr;
The solution to your problem is to do $fol_arr = json_encode($fol->followers_arr);
Nonetheless, making a class in this case is completely obsolete, since you only make it as a wrapper for a single function you want to execute (called get_followers) Instead of making a class, you could simply make the following:
function get_followers($user_id) {
$followers_arr = [];
$query = "select * from followsystem where following ='$user_id'";
$q = mysql_query($query) or die(mysql_error());
$count = mysql_num_rows($q);
if ($count > 0) {
while ($row = mysql_fetch_assoc($q)) {
array_push($followers_arr, $row['userid']);
}
}
return $followers_arr;
}
$fol = get_followers($userid);
$fol_arr = json_encode($fol);
echo $fol_arr;
There is no need to put it in a class unless the class serves the purpose of combining a few functions and variables to create a behaviour.

PHP: Run function and return values

I am trying to run a function that checks a db table for a username and an email. I call the function with two parameters ($user_username, $user_password). The function checks the database to see if those values exist. However, I cannot get the variables from the function to return properly. Here's what i have so far:
Function:
class registerClass{
public function checkUser($user_username, $user_email){
//connect to db via pdo...
$st_1 = $handler->prepare("SELECT * FROM tbl_users WHERE user_username = '$user_username'");
$st_1->execute();
if($st_1->rowCount() > 0){$user_exists = '1';}
$st_2 = $handler->prepare("SELECT * FROM tbl_users WHERE user_email = '$user_email'");
$st_2->execute();
if($st_2->rowCount() > 0){$email_exists = '1';}
}
}
Call to function:
$object = new registerClass();
$object->checkUser($user_username, $user_email);
if($user_exists >= '1'){$errors[] = "Username taken";}
if($email_exists >= '1'){$errors[] = "Email taken";}
For some reason the errors never get thrown. I'm not sure what I'm doing wrong here.
The variables you're setting are local to the function, they're not visible in the scope of the caller. Instead, the function should return the variables in an array:
class registerClass{
public function checkUser($user_username, $user_email){
$user_exists = $email_exists = false;
//connect to db via pdo...
$st_1 = $handler->prepare("SELECT * FROM tbl_users WHERE user_username = '$user_username'");
$st_1->execute();
if($st_1->rowCount() > 0){$user_exists = true;}
$st_2 = $handler->prepare("SELECT * FROM tbl_users WHERE user_email = '$user_email'");
$st_2->execute();
if($st_2->rowCount() > 0){$email_exists = true;}
return array($user_exists, $email_exists)
}
}
You can then use it like this:
list($user_exists, $email_exists) = $object->checkUser($user_username, $user_email);
if($user_exists){$errors[] = "Username taken";}
if($email_exists){$errors[] = "Email taken";}
I've also changed the values from strings with 0 and 1 to booleans false/true.
You should use return to return value by function and than in place where you call your function use for example list to get function return values.
Complete code:
<?php
class registerClass
{
public function checkUser($user_username, $user_email)
{
//connect to db via pdo...
$user_exists = 0;
$email_exists = 0;
$st_1 = $handler->prepare(
"SELECT * FROM tbl_users WHERE user_username = '$user_username'"
);
$st_1->execute();
if ($st_1->rowCount() > 0) {
$user_exists = '1';
}
$st_2 = $handler->prepare(
"SELECT * FROM tbl_users WHERE user_email = '$user_email'"
);
$st_2->execute();
if ($st_2->rowCount() > 0) {
$email_exists = '1';
}
return array($user_exists, $email_exists);
}
}
$object = new registerClass();
list($user_exists, $email_exists) = $object->checkUser(
$user_username,
$user_email
);
if ($user_exists >= '1') {
$errors[] = "Username taken";
}
if ($email_exists >= '1') {
$errors[] = "Email taken";
}
However normally you rather don't set value 1 in that case but boolean true so you should rather use this code:
class registerClass
{
public function checkUser($user_username, $user_email)
{
//connect to db via pdo...
$user_exists = false;
$email_exists = false;
$st_1 = $handler->prepare(
"SELECT * FROM tbl_users WHERE user_username = '$user_username'"
);
$st_1->execute();
if ($st_1->rowCount() > 0) {
$user_exists = true;
}
$st_2 = $handler->prepare(
"SELECT * FROM tbl_users WHERE user_email = '$user_email'"
);
$st_2->execute();
if ($st_2->rowCount() > 0) {
$email_exists = true;
}
return array($user_exists, $email_exists);
}
}
$object = new registerClass();
list($user_exists, $email_exists) = $object->checkUser(
$user_username,
$user_email
);
if ($user_exists) {
$errors[] = "Username taken";
}
if ($email_exists) {
$errors[] = "Email taken";
}
When you call a class method like: $object->checkUser($user_username, $user_email); or a function like : checkUser($user_username, $user_email); you must remember that php pass the params by copy, not by reference.
So by default what you pass (for example $user_name), it's not the same $user_name on function/method body. Seee http://php.net/manual/en/functions.arguments.php for more.
You can resolve your problem by using new method declaration this code:
public function checkUser(&$user_username, &$user_email){
//connect to db via pdo...
$st_1 = $handler->prepare("SELECT * FROM tbl_users WHERE user_username = '$user_username'");
$st_1->execute();
if($st_1->rowCount() > 0){$user_exists = '1';}
$st_2 = $handler->prepare("SELECT * FROM tbl_users WHERE user_email = '$user_email'");
$st_2->execute();
if($st_2->rowCount() > 0){$email_exists = '1';}
}
So to have have an argument to a function passed by reference, prepend an ampersand (&):checkUser(&$user_username, &$user_email)

Login using database sessions?

I have been trying to get my login script to work with database managed sessions.
This is my database session class:
class SessionManager {
var $life_time;
function SessionManager() {
// Read the maxlifetime setting from PHP
$this->life_time = 600; //10 minutes
// Register this object as the session handler
session_set_save_handler(array( &$this, "open" ),
array( &$this, "close" ),
array( &$this, "read" ),
array( &$this, "write"),
array( &$this, "destroy"),
array( &$this, "gc" )
);
}
function open( $save_path, $session_name ) {
global $sess_save_path;
$sess_save_path = $save_path;
// Don't need to do anything. Just return TRUE.
return true;
}
function close() {
return true;
}
function read( $id ) {
// Set empty result
$data = '';
// Fetch session data from the selected database
$time = time();
$newid = mysql_real_escape_string($id);
$sql = "SELECT
`session_data`
FROM
`sessions`
WHERE
`session_id` = '$newid'
AND
`session_expire` > $time";
$rs = mysql_query($sql);
$a = mysql_num_rows($rs);
if($a > 0) {
$row = mysql_fetch_assoc($rs);
$data = $row['session_data'];
}
return $data;
}
function write($id, $data) {
// Build query
$time = time() + $this->life_time;
$newid = mysql_real_escape_string($id);
$newdata = mysql_real_escape_string($data);
$sql = "INSERT INTO `sessions` (`session_id`, `session_data`,
`session_expire`, `session_agent`,
`session_ip`)
VALUES
(\"".$id."\", \"".$data."\",
\"".time()."\",\"".$_SERVER['HTTP_USER_AGENT']."\",
\"".$_SERVER['REMOTE_ADDR']."\")
ON DUPLICATE KEY UPDATE
`session_id` = \"".$id."\",
`session_data` = \"".$data."\",
`session_expire` = \"".time()."\"";
$rs = mysql_query($sql) or die(mysql_error());
return true;
}
function destroy($id) {
// Build query
$id = mysql_real_escape_string($id);
$sql = "DELETE FROM `sessions` WHERE `session_id`='$id'";
mysql_query($sql);
return true;
}
function gc(){
// Garbage Collection
// Build DELETE query. Delete all records who have passed the expiration time
$sql = 'DELETE FROM `sessions` WHERE `session_expire` < UNIX_TIMESTAMP();';
mysql_query($sql);
// Always return TRUE
return true;
}
}
This is a part of my login class:
function process_login(){
global $mysql_prefix;
$email = mysql_real_escape_string($_POST['email']);
$check = mysql_query("SELECT password,salt,id FROM ".$mysql_prefix."users WHERE email='$email'");
if(mysql_num_rows($check) > 0){
$info = mysql_fetch_assoc($check);
$private_key = $this->get_secret_key();
$password = hash('sha256', $info['salt'] . hash('sha256', $private_key.$_POST['password']));
if($password == $info['password']){
$_SESSION[$this->user_session]['id'] = $info['id'];
return true;
}else{
return false;
}
}else{
return false;
}
}
I have required the session class in my global.php file and called the class (or whatever it is called), but how do I actually go about and use this new database session system with my current login class?
I tried to use $ManageSessions->write(id, data) like this:
function process_login(){
global $mysql_prefix;
$email = mysql_real_escape_string($_POST['email']);
$check = mysql_query("SELECT password,salt,id FROM ".$mysql_prefix."users WHERE email='$email'");
if(mysql_num_rows($check) > 0){
$info = mysql_fetch_assoc($check);
$private_key = $this->get_secret_key();
$password = hash('sha256', $info['salt'] . hash('sha256', $private_key.$_POST['password']));
if($password == $info['password']){
$SessionManager->write(session_id(),$info['id']);
return true;
}else{
return false;
}
}else{
return false;
}
}
But it does not seem to work, and the data is overwritten the second the page is updated.
I must be missing something obvious, or just coding something wrong.
(I am aware of the security flaws in the script and I am in the process of redesigning it, so please don't say anything about security or like. Thanks :))
The class above substitutes php's session system with the one in the class. When you make a new instance of the class, its constructor (the function SessionManager() {) is called, setting the functions in the class to run instead of php's defaults. So now when you write something to the $_SESSION, it uses SessionManager's write functions, which adds it to the database.
So basically, just initialize that class on every page, and then use your sessions like you normally would. They'll all just show up in the database.

Categories