Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

DZone's Guide to

# Access Control with Bit Masks

· Web Dev Zone ·
Free Resource

Comment (1)

Save
{{ articles[0].views | formatCount}} Views

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

Today I want to tell you about the organization of access rights for users (on your site) using bit masks. Perhaps you already know it, probably not, but anyway I want to give you this information. Why bit masks? – easy, because this is a fast and easy way to recognize a user’s possible actions. In our system, I have identified six possible actions (it will keep 6 bits, where each bit is one of the possible actions). The actions are: Read, Create, Edit Own, Delete Own, Edit Any and Delete Any (moderator’s / admin’s actions). This method can be applied to everything – blogs, news articles, photos and more. Ok, lets start.

Here is a little theory about Bitwise Operators:

Example Name Result
\$a & \$b And Bits that are set in both \$a and \$b are set.
\$a | \$b Or (inclusive or) Bits that are set in either \$a or \$b are set.
\$a ^ \$b Xor (exclusive or) Bits that are set in \$a or \$b but not both are set.
~ \$a Not Bits that are set in \$a are not set, and vice versa.
\$a << \$b Shift left Shift the bits of \$a \$b steps to the left (each step means “multiply by two”)
\$a >> \$b Shift right Shift the bits of \$a \$b steps to the right (each step means “divide by two”)

### Step 1. HTML

Our demo uses 3 html template files:

#### main_page.html

```<!DOCTYPE html>
<html lang="en" >
<body>
<a href="http://www.script-tutorials.com/access-control-with-bit-masks/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
<div class="container">
{form}
</div>
</body>
</html>```

This is a very easy layout, isn’t it?. Next template file:

```<div class="column">
<h3>Access control demonstration</h3>
</div>
<div class="column">
</form>
</div>```

Another one easy template for the login form. Next template file:

#### logout_form.html

```<div class="column">
<h3>Hello {name}</h3>
<div>{possibilities}</div>
</div>
<div class="column">
<a href="index.php?logout">Log Out</a>
</div>```

This is a template where we will display the user's possibilities and link to the logout.

### Step 2. CSS

#### css/main.css

This file contains several styles of our page layout, no need to publish it today.

### Step 3. PHP

Now, let's review our main functionality:

#### index.php

```<?php

// define bit mask for access rights
define('CAN_READ', 1 << 0);   // 000001
define('CAN_CREATE', 1 << 1); // 000010
define('CAN_EDIT_OWN', 1 << 2);   // 000100
define('CAN_DELETE_OWN', 1 << 3); // 001000
define('CAN_EDIT_ANY', 1 << 4);   // 010000
define('CAN_DELETE_ANY', 1 << 5); // 100000

// login system init and generation code
\$oSimpleAccessSystem = new SimpleAccessSystem();

// class SimpleAccessSystem
class SimpleAccessSystem {

// variables
var \$aMembers; // Existed members array

// constructor
function SimpleAccessSystem() {
session_start();

// different sets of permissions
\$sWriterPerm = CAN_READ | CAN_CREATE | CAN_EDIT_OWN | CAN_DELETE_OWN;
\$sModeratorPerm = CAN_READ | CAN_EDIT_ANY | CAN_DELETE_ANY;
\$sAdminPerm = CAN_READ | CAN_CREATE | CAN_EDIT_OWN | CAN_DELETE_OWN | CAN_EDIT_ANY | CAN_DELETE_ANY;

/* hash = sha1(md5('password') . 'testing'); */
\$this->aMembers = array(
'User' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => \$sUserPerm),
'Writer' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => \$sWriterPerm),
'Moderator' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => \$sModeratorPerm),
);
}

if (isset(\$_GET['logout'])) { // logout processing
if (isset(\$_SESSION['member_name']) && isset(\$_SESSION['member_pass']))
\$this->performLogout();
}

exit;
} else { // wrong login
ob_start(); // get template of Login form
}
} else { // in case if we already logged (on refresh page):
if (isset(\$_SESSION['member_name']) && \$_SESSION['member_name'] && \$_SESSION['member_pass']) {
\$sRule = \$this->aMembers[\$_SESSION['member_name']]['rule'];
\$sPermissions = '';
\$sPermissions .= \$this->isCanCreate(\$sRule);
\$sPermissions .= \$this->isCanEdit(\$sRule);
\$sPermissions .= \$this->isCanEditAny(\$sRule);
\$sPermissions .= \$this->isCanDelete(\$sRule);
\$sPermissions .= \$this->isCanDeleteAny(\$sRule);

ob_start(); // get template of Logout form
require_once('logout_form.html');
\$sLogoutForm = ob_get_clean();
\$sLogoutForm = str_replace('{name}', \$_SESSION['member_name'], \$sLogoutForm);
\$sLogoutForm = str_replace('{possibilities}', \$sPermissions, \$sLogoutForm);
return \$sLogoutForm;
}
}

// otherwise - draw login form
ob_start();
}
}

// check functions
}
function isCanCreate(\$sRule) {
return (\$sRule & CAN_CREATE) ? 'You can Create<br />' : '';
}
function isCanEdit(\$sRule) {
return (\$sRule & CAN_EDIT_OWN) ? 'You can Edit<br />' : '';
}
function isCanEditAny(\$sRule) {
return (\$sRule & CAN_EDIT_ANY) ? 'You can Edit anything<br />' : '';
}
function isCanDelete(\$sRule) {
return (\$sRule & CAN_DELETE_OWN) ? 'You can Delete<br />' : '';
}
function isCanDeleteAny(\$sRule) {
return (\$sRule & CAN_DELETE_ANY) ? 'You can Delete anything<br />' : '';
}

\$this->performLogout();

\$sSalt = \$this->aMembers[\$sName]['salt'];
\$sPass = sha1(md5(\$sPass) . \$sSalt);

\$_SESSION['member_name'] = \$sName;
\$_SESSION['member_pass'] = \$sPass;
}

// perform logout
function performLogout() {
unset(\$_SESSION['member_name']);
unset(\$_SESSION['member_pass']);
}

function checkLogin(\$sName, \$sPass, \$isHash = true) {
if (isset(\$this->aMembers[\$sName])) {
if (! \$isHash) {
\$sSalt = \$this->aMembers[\$sName]['salt'];
\$sPass = sha1(md5(\$sPass) . \$sSalt);
}
return (\$sPass == \$this->aMembers[\$sName]['hash']);
}
return false;
}
}
```

First, we define the constants for access rights (bit mask). Further, when we enumerate users on the system – we grant them different sets of rights (using the logical operator | or). Keep in mind that I am not forcing you to keep users in the same array, in your case, your users can easily be in the database. And, in this case, you can grant them their right in the database itself. Further, I have added extra check functions, so that we can understand if the user can perform a certain action.

In such functions we use the logical operator & (and). Most of these checks use a single bit check. If you want to do multiple check, for example – let's create a function to check if the member can read and create. Then this function will looks like this:

```function isCanReadCreate(\$sRule) {
return (\$sRule & (CAN_READ | CAN_CREATE));
}
```

This function will return True or False.

### Conclusion

I hope that it was interesting for you to remember how bitwise and logical operands work. If you have any good ideas you would like to share, be sure to write us as well. Good luck!

What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

Topics:

Comment (1)

Save
{{ articles[0].views | formatCount}} Views

Opinions expressed by DZone contributors are their own.