logo

Implementing Bitwise Permissions

Add comment

Reader Freddy requested a tutorial about implementing bitwise permissions in real application. This tutorial will cover that. It’s very simple tutorial and I tried to make it as simple as possible.

Folder Structure Top

Folder structure is very simple. We only have 3 files db.php, user.php and index.php. db.php will have database connection, user.php will have simple class that will help us working with users and index.php will be our main file.

Database Structure Top

We’ll need database to. We’ll have 3 tables. bw_users, bw_actions and bw_groups.

bw_users Top

This table is for our users. It has 3 fields, id, name and group. id is primary key, name is users name and group if foreign key for group that links to bw_groups table (id filed).

CREATE TABLE IF NOT EXISTS `bw_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uname` varchar(25) COLLATE utf8_bin NOT NULL,
  `group` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `group` (`group`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=5 ;

bw_actions Top

This table will have all available actions. We’ll have 3 fields, id, name and priv. id is primary key, name is name of the action and we’ll use it to choose action from table that is requested from user and priv is used to determine what privilege is required to execute that action.

CREATE TABLE IF NOT EXISTS `bw_actions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) COLLATE utf8_bin NOT NULL,
  `priv` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;

bw_groups Top

This table will have all groups. We’ll have 3 fields, id, name and priv. id is primary key, name is name of the group and priv is privilege that certain group has.

CREATE TABLE IF NOT EXISTS `bw_groups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) COLLATE utf8_bin NOT NULL,
  `priv` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=6 ;

Now we just need to link bw_users to bw_groups.

ALTER TABLE `bw_users`
  ADD CONSTRAINT `bw_users_ibfk_1` FOREIGN KEY (`group`) REFERENCES `bw_groups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Table Data Top

I did not create any interface that we will use for creating actions, grups and users but using my tutorial on bitwise permissions i created them manually. Each action has it’s own unique privilege that has to be some number in base 2 (1, 2, 4, 16…) and why you can read on a link above. Groups have some bits set or unset from those actions depending on groups requirements. For example guest will only have permission to read but not to edit, publish or delete.

INSERT INTO `bw_actions` (`id`, `name`, `priv`) VALUES
(1, 'view', 1),
(2, 'edit', 2),
(5, 'publish', 4),
(6, 'delete', 8);

INSERT INTO `bw_groups` (`id`, `name`, `priv`) VALUES
(1, 'guest', 1),
(3, 'editor', 3),
(4, 'publisher', 5),
(5, 'administrator', 15);

INSERT INTO `bw_users` (`id`, `uname`, `group`) VALUES
(1, 'user1', 1),
(2, 'user2', 3),
(3, 'user3', 4),
(4, 'user4', 5);

db.php Top

This file is elementary PHP and I’ll not explain it.

$con = mysql_connect('localhost', 'root', '');
mysql_select_db('tutoriali', $con);

user.php Top

Now we will create our user class. First we’ll have two variables, $_priv and $_group. What they are for you can tell from their names. Then we’ll have some “useless” constructor.

class user
{

    private $_priv;

    private $_group;

    public function __construct()
    { }

}

Next we’ll have two methods for setting values and two for restoring them (setters and getters). Nothing special. Note that in setPriv we cast passed variable to integer. Why? Reason is very simple. When we get it from database it’s a string but we need integer. We can’t even have float type. That’s because ‘1′, 1 and 1.0 are not the same thing. ‘1′ is binary coded as 0..0110001 and as integer that is 49 (49 is 1 in ASCII table) and that is not 1 that we need. 1.0 is one but has different way of coding than integers because they have wider range of numbers they can display.

public function getGroup()
{
    return $this->_group;
}

public function setGroup($group)
{
    $this->_group = $group;
}

public function getPriv()
{
    return $this->_priv;
}

public function setPriv($priv)
{
    $this->_priv = (int) $priv;
}

Now we have only one more method and that will check if user can do something. Not that here we cast **$action to integer again and use ‘&’ to check if user can or can not execute that action.

public function can($action)
{
    return (int) $action & $this->getPriv();
}

Main Page Top

Now that we have our class we just need to put this all together. First we’ll include our files in index.php and create two arrays that will have all available users and actions. Next we check if parameters from $_GET are set and valid. After that we have a list of all available users and actions to make our testing easier. After that we just pull our data from database, pass required elements to user class and then we echo message about users permission (can or can not execute action).

require_once './db.php';
require_once './user.php';

$actions = array('view', 'edit', 'publish', 'delete');
$users = array('user1', 'user2', 'user3', 'user4');

$action = (isset($_GET['action']) && in_array($_GET['action'], $actions)) ? $_GET['action'] : 'view';
$user = (isset($_GET['user']) && in_array($_GET['user'], $users)) ? $_GET['user'] : 'user1';

?>
<table>
    <thead>
        <tr>

            < ?php foreach($actions as $tmpAction) : ?>
            <th>< ?php echo $tmpAction; ?></th>
            < ?php endforeach; ?>
        </tr>
    </thead>

    <tbody>
        < ?php foreach($users as $tmpUser) : ?>
        <tr>
            < ?php foreach($actions as $tmpAction) : ?>
            <td><a href="index.php?user=<?php echo $tmpUser; ?>&action=< ?php echo $tmpAction; ?>">< ?php echo $tmpUser; ?></a></td>

            < ?php endforeach; ?>
        </tr>
        < ?php endforeach; ?>
    </tbody>
</table>
< ?php

$sql = 'SELECT `bw_groups`.`priv`, `bw_groups`.`name` '
. 'FROM `bw_users` '
. 'JOIN `bw_groups` '
. 'ON `bw_users`.`group` = `bw_groups`.`id` '
. "WHERE `bw_users`.`uname` = '%s' "

. 'LIMIT 1';

$result = mysql_query(sprintf($sql, $user), $con);

if (!$result)
    die('Error.');

$temp = mysql_fetch_object($result);

$userClass = new user();
$userClass->setGroup($temp->name);
$userClass->setPriv($temp->priv);

$sql = 'SELECT `priv` '
. 'FROM `bw_actions` '
. "WHERE `name` = '%s'";

$result = mysql_query(sprintf($sql, $action), $con);

if (!$result)
    die('Error.');

$temp = mysql_fetch_object($result);

printf(
    'User %s in group %s %s %s.',
    $user,
    $userClass->getGroup(),
    $userClass->can($temp->priv) ? 'can' : "can't",
    $action
);

Conclusion Top

This is just simple way that show you how you can use bitwise permissions in your application. You can view demo here or download source code here.

Related Posts
  • 18.08.2009 — Permissions Using Bitwise (2)
    This will be a quick tutorial on how to use bitwise operators in PHP to create permissions control. …
  • 23.12.2009 — Learning Resources (0)
    Reader Satish requested a list of tutorials where he could learn about PHP, MySQL and jQuery. Since …
  • 16.07.2009 — Advanced PHP User Login (8)
    If you ever had a bank account you are familiar with TAN-s (Transaction Authentication Number). What…
  • 24.06.2009 — PHP Antispam (1)
    Today web programmers have big problems with spam comments. There are a lot of tutorials about captc…
  • 02.01.2010 — Enable E-mail In PHP – Win (0)
    This will be a quick tutorial that will show you how to enable e-mail function in PHP on Windows….
  • 22.10.2009 — jQuery Basic Tutorial (0)
    User named Enrho requested a tutorial that will explain some basics in jQuery. This will be a very s…
  • 16.10.2009 — PHP DomDocument Tutorial (5)
    This will be a quick tutorial that will show you how to use PHP’s DOMDocument to parse your XML so y…

logo

Leave a Reply


 *


 *


logo
logo
Powered by Wordpress | Designed by Elegant Themes | CopyRight ©2010 php4every1.com