User permissions custom cms - php

looking for some advice on my current setup and if there is a better approach (this is my first attempt at building an app like this) but I am at a point where I need user roles, only two so user and admin.
I have a users table and a groups table and also a join table which takes the ID from the users table and the Id from the groups table and I can allocate which group the user belongs too.
I am wanting to set a way to do a couple of things, prevent 'users' accessing the admin area by typing in the url /admin/index.php and also show a link on the index page if they are an admin and not see it it if they are a normal user.
Here is my code to demonstrate that I can show the users role title but struggling at this point:
<?php
$user = $_SESSION['user'];
try{
$results = $dbh->query("SELECT *
FROM groups
INNER JOIN user_group_link_table
ON groups.id = user_group_link_table.group_id
WHERE user_group_link_table.user_id = $user");
}catch(Exception $e) {
echo $e->getMessage();
die();
}
$group = $results->fetchAll(PDO::FETCH_ASSOC);
foreach($group as $groups){
echo
$groups["name"]
// show a link to admins that user do not see?
;}
?>
I am wondering if my approach is totally wrong?
UPDATE
<?
include('session.php');
if (!isset($_SESSION['user'])) {
header("Location: index.php");
}
if(!ini_get('date.timezone'))
{
date_default_timezone_set('GMT');
}
// This could be an include file for all admin pages
$isAdmin = false;
foreach($group as $groups){
if($groups['name'] === 'admin'){
$isAdmin = true;
break;
}
}
if(!$isAdmin){
header('Location: index.php'); // or some other arbitrary location
die();
}
?>
And I get this error:
Notice: Undefined variable: group in /Applications/MAMP/htdocs/dashboardr v3.2.3/admin/header.php on line 12
Warning: Invalid argument supplied for foreach() in /Applications/MAMP/htdocs/dashboardr v3.2.3/admin/header.php on line 12

I am wanting to set a way to do a couple of things, prevent 'users' accessing the admin area by typing in the url /admin/index.php and also show a link on the index page if they are an admin and not see it it if they are a normal user.
I'll give you a solution that'll work in your current setup; It's not the way to go, but i'll get the job done for now. If you're worried about the user being in a specific role, you're better off specifying that role in your query rather than iterating through all their potential roles.
// This could be an include file for all admin pages
$isAdmin = false;
foreach($group as $groups){
if($groups['name'] === 'admin'){
$isAdmin = true;
break;
}
}
if(!$isAdmin){
header('Location: index.php'); // or some other arbitrary location
die;
}
You'll want to place this at the top of the page, before you spit out any kind of HTML.

Related

Not able to create proper session's for User management application in php

I have created a user management application in PHP, Where Super Admin has a rights/permissions to grant and revoke permissions to the Users.
I have created Session for all the users including the Super Admin.
Below code for the same:
$_SESSION['User_login'] = $single_value['user_name'];//USER NAME
$_SESSION['permission'] = $single_value['permission']; // Granted permissions
$_SESSION['role_code'] = $single_value['role_id'];// ROLE CODE
The working is fine but I'm facing the problem in the below condition.
Super Admin has a right to create users with Create_user.php file and USER Test has a right to access the only download_file.php
When User Test Logins to the download_file.php file he is able to do all the tasks mentioned in that file but if Test user enters the Create_user.php in URL then he is able to view that file which belongs to Super Admin without any problem.
So I'm confused here how to stop this process when 1 user does not have the rights/permissions to open a particular file, the user should be directed to the home page or any error something.
You'll need some kind of conditional check at the beginning of your Create_user.php file which check what permissions the user requesting that page has. Something like this:
if ($_SESSION['permission'] != 'Admin') { // or however you name your permissions
header('Location: /download_file.php'); // redirect non-admin users
}
// ... admin stuff follows
This can be achieved with the help of in_array() function.
Creating a sperate table for all the menu with the page name and checking the currently rendered page with the given/granted permissions to the logged in user.
menu table:
Below code for checking the permissions.
CHECK.PHP
function check($filename)
{
include_once('config.php');
$sql = "SELECT name from menu where page_name = '".$filename."' ";
#echo $sql;
$result = $conn->query($sql);
if($result->num_rows > 0 )
{
while($row = $result->fetch_assoc())
{
if(!in_array($row['name'],explode(",",$_SESSION['permission'])))
{
header('location:logout.php');
}
#echo "data = ".$row['name']; echo "<br> My permission = ".$_SESSION['permission'];
}//EOF WHILE
}//EOF IF
else
{
echo "0 result";
}
}//EOF CHECK();
calling this function where you want to check permissions
Create_user.php
<?php include_once 'check.php';
check(basename($_SERVER['PHP_SELF'])); #passing the name of current file.
?>
<!DOCTYPE html>
<!-- Rest of the code -->
<html>

Different redirect for member and admin

Hope all is well!
I am trying to code my login.php so that it redirects to consumerView.php for a member and admin.php for employee/admin. I have written the following php code but I keep getting redirected to consumerView.php even though the role of the login info is for an employee. Could someone provide any insight to get this working please?
The SQL query works, I tested it in phpmyadmin.
Disclaimer: I am new to php.
// SELECT query
$query1 = "SELECT u.id, u.email, u.pass password, r.name role
FROM users u INNER JOIN role r ON r.id = u.ro_fk
WHERE email = ? AND u.pass = ? ;";
if(r.name == 'member'){
header("Location: consumerView.php");}
else
{header("Location: admin.php");}
die();
} else {
//If the username/password doesn't matche a user in our database
// Display an error message and the login form
echo "Failed to login";
}
} else {
echo "failed to prepare the SQL";
}
}
?>
You have got result in $myrow.
$myrow = $result->fetch_assoc();
//Create a session variable that holds the user's id
$_SESSION['id'] = $myrow['id'];
//Redirect the browser to the profile editing page and kill this page.
if($myrow['name'] == 'member'){ // <- You need to change this line to check user is member or not.
header("Location: consumerView.php");
}
else{
header("Location: admin.php");
}
Replace
if(r.name == 'member')
with
if($myrow['name'] == 'member')
Ok, just to be precise I will elaborate my comment here:
You have
if (r.name == 'member') {
header("Location: consumerView.php");
}
First of all, you dont have variable r assigned anywhere. Even if you did, it should be $r in php. Then, you are accesing it's property but in php it is done by -> not by dot. So you should obtain your user from $result, and then do something like (or however it will be stored, var_dump your $result to be sure how is it stored)
if ($user->name === 'member') {
header("Location: consumerView.php");
}
Or you can access it from $myrow = $result->fetch_assoc() if you want, but then you need to access it like array so probably it would be something like $myrow['name'];

adding a column in mysql so that depending on which user logs in they go to a specific page

below is the authorisation script (from login). I want to send a user to a specific page depending on (new column called company to be added to database table) a user and their company.
Current script, even if someone can point me in the direction I would appreciate it:
<title>authorise</title>
<?php
session_start();
$un = $_POST['username'];
$pw = $_POST['password'];
if ($pw != ''){
$_SESSION['user'] = $un;
echo "Incorrect username / password";
}
try
{
$dbh = new PDO("mysql:host=localhost;dbname=login_site","root","black$23");
}
catch (PDOException $e){
echo $e->getMessage();
}
$query = "SELECT * FROM users WHERE LOWER(username)=:username";
$stmt=$dbh->prepare($query);
$stmt->bindValue(':username',strtolower ($_POST['username']));
$stmt->execute();
if ($stmt->rowCount() == 1)
{
$row=$stmt->fetch(PDO::FETCH_ASSOC);
require('blowfish.php');
require('bcrypt.class.php');
$bcrypt = new Bcrypt(4);
if($bcrypt->verify($_POST['password'],$row['password']))
{
echo"logged in!!";
header("Location: hollyfort/123.php");
}
}
?>
I think you need a table with the userID and a page id (or perhaps w/ the companyID and a pageID), so you can determine the page to be returned by the user or company. Maybe you even want both tables, e.g. if you want all employees of a company to get a certain site, but the CEO should get to a special site where he can see all his employees' activities.
you then first check, if an entry for that user exists (if it does, you return the page). if not, check if an entry for the company exists. if you cannot find an entry, you probably want to return a default page
all is ok - I setup company variables to check against the database column and it works :)

ACL implementation for databases

I'm trying to implement an ACL in my database. I have a database which looks like:
SYS_USERS { id, name, .. }
AUTH { au_id, au_name, .. }
USER_GROUPS { sys_users_id, auth_id } // bridge table
And say AUTH data looks like:
au_id au_name ...
1 admin ...
2 staff ...
... ... ...
My question is, how can I structure my query from php such that upon login, depending on your authentication level, you are presented different pages?
At the moment I have this, which seems a little off:
<?php
// code which verifies session variables etc here
$mysql_hostname = 'localhost';
$mysql_username = '...';
$mysql_password = '...';
$mysql_dbname = '...';
try {
/* Set up new DB object */
$db = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_dbname", $mysql_username, $mysql_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* authenticate user access level */
// username = 'blah' for question clarity
$query = $db->prepare('SELECT au_name FROM auth WHERE au_id = (SELECT auth_id FROM user_groups WHERE sys_users_id = (SELECT id FROM sys_users WHERE username="blah"))');
// do something with results..
} catch(Exception $exception) {
$message = 'We are unable to process your request. Please try again later';
}
?>
So I guess my questions are:
Is the SELECT query adequate? Or should I use an INNER JOIN to achieve the same results? (Does it matter?)
Upon success of the query, how do I show the page depending on the level? For example, if it returned admin do I write a function such that
if ($result == 'admin') {
// show admin.php
} elseif ($result == 'staff') {
// show staff.php
} else { ... }
But this seems rather 'hard coded', i.e. if we were to extend the system for more AUTH roles, we would need to then add in more IF/ELSEIF statements to the above.
Anyone able to lead me in the right direction?
Thanks.
EDIT
So I was thinking of a new way to do this. I could add two more database tables:
PAGES { id, page_name .. }
AUTH_PAGES { au_id, pages_id, .. } // bridge between auth and pages
Which then in pages I could store page_name which would hold the authentication level required to view that page?
For example: a page called admin_page.php could only be accessed by administrators. Therefore this row in pages looks like:
id page_name
1 admin_page.php
2 members_page.php
and auth_pages:
au_id pages_id
1 1
1 2
Which is to say the auth row admin (au_name) has access to admin_page.php and members_page.php. Then all I would need to do in my PHP would be to cross reference the page name with the id from pages table with auth_pages table using echo basename($_SERVER['PHP_SELF']);.
Does that make any practical sense?
Since you mentioned its going to be simple so this is what I can suggest you.
At the time of login get the user id and then run a query with the id user as
select
a.au_name,a.au_id
from USER_GROUPS ag
inner join SYS_USERS su on su.id = ag.sys_users_id
inner join AUTH a on a.au_id = ag.auth_id
where ag.sys_users_id = {id of the user retrieved after the login validation}
Now Execute the above query and get the au_name and store it in a session variable as
$_SESSION['au_name'] = {auth name from the above query} ;
Create a function as below and execute it after the login.
get_page_access($au_id){
run a query to get all the pages for the auth id you got from previous query
store them in an array and finally to a session variable as
$_SESSION['page_access'] = $array ;
$array will hold all the pages you retrive
}
Now do the redirect based on the $_SESSION['au_name'] firstime after the login.
Now what if user hotlink an URL i.e. a non-admin user try to access a page. So for that create a file called check_access.php and add include it to all the pages other than the login page.
In this page you get the URL using PHP and get the filename from the URL, then check if that filename exists on the array $_SESSION['page_access'] and if yes user is allowed to view the page else show message.
Make sure you do session_start() before the include .
This will be fairly simple in nature

Determining Account Type from table and Registering Session

Basically what i am trying to do here is to read from the table in my database using the customers login details, then retrieve the record that matches this information. In this table there is a column called "AccountType", this differentiates the average user from a manager, if this column is 1, they are a average user. If this column is 2, they are a manager.
Now im having issues implementing this in my code, below is the snippet of my process script for the login:
<?php
***session_start()
$query = mysql_query("SELECT * FROM accounts WHERE username='$username' and password='$password'", $db) or die ("Query failed with error: ".mysql_error());
$count=#mysql_num_rows($query);
if(***$count == 1)
{
***$user_row = mysql_fetch_array($result)
$userid = $user_row["userid"];
$_SESSION['userid'] = $userid;
$customername = $user_row["customername"];
$_SESSION['customername'] = $customername;
$AccountType = $user_row["accounttype"];
if ($AccountType == 2)
{
$_SESSION['manager'] = $AccountType;
}
Depending on this, when my check login script which every page includes, it will display specific links on the navigation depending what there account type is, if they are user they will have access to normal links, but if they are a manager they have access to admin functions, below is the code snippet for this also:
***session_start();
if (***isset($_SESSION['userid']))
{
$employeeid = $_SESSION['userid'];
$firstname = $_SESSION['customername'];
if (***isset($_SESSION['manager']))
{
$User_Options .='Manager links go here';
}
else
{
$Links .='Normal Links go here';
}
}
Thats just a basic truncated version, but that gives the basis of what im trying to accomplish. I am guessing down to using the while loop its overwriting the session, which i understand, however there will only be one record for the information i am searching. It works to some extent, however even if the AccountType is 1, it displays the options for 2.
Can anyone assist me further in solving this issue? Thankyou!
Use something like this on the login form:
$_SESSION['manager'] = false;
if ($AccountType == 2) {
$_SESSION['manager'] = true;
}
then later:
if ($_SESSION['manager']) {
// display manager-only options
} else {
// display user-only options
}
// Display options for everyone here

Categories