Access Control in PHP and my new OSS Project


Recently at work I have been working on a project that has made me have to think about project flexibility in a whole new way. The project involves a service we are creating which companies will be able to purchase and label as their own. We plan on accomplishing this by making use of the Smarty Templating Engine and some server-side magic so that we only have one code base for infinite iterations of the service.

For the most part all of the underlying logic is identical, but Access Control has to be configurable on an individual company basis. Our company has three access levels which map basically to “Basic”, “Pro”, and “Premium”, but Company A may only have “Basic” and “Pro” while Company C may have “Basic”, “Pro”, “Premium”, and “Super-Epic-AwesomeTown”. To complicate matters further, the access levels are not strictly hierarchical. A user who registers on a site may have purchased the “Basic” package and the “Premium” package while opting not to purchase “Pro” or “Super-Epic-AwesomeTown”.

After researching PHP Access Control libraries for a while, I discovered nothing that seemed to meet my needs in an easy to use and flexible way. So, like any good nerd I decided to write and Open-Source my own.

Introducing PHP-Bouncer

PHP-Bouncer uses the idea of roles to manage permissions, so in the above examples “Basic”, “Pro”, “Premium”, and “Super-Epic-AwesomeTown” would map to roles each of which would give access to specific sets of pages. Each role also has the option to override a page from any other roles, so if “Pro” gives you access to a page called “Buy Premium”, Premium may override that page and send you to “Premium Home”. Roles are defined Like this:

$bouncer = new Bouncer();
// Add a role     Name,      Array of pages role provides
$bouncer->addRole("Public", array("index.php", "about.php"));
// Add a role          Name,              Array of pages role provides
$bouncer->addRole("Registered User", array("myaccount.php", "editaccount.php", "viewusers.php"));
// Add a role          Name,   Array of pages role provides       List of pages that are overridden by other pages
$bouncer->addRole("Admin", array("stats.php", "manageusers.php"), array("viewusers.php" => "manageusers.php"));

With our roles defined, we can now create some users and give them roles (NOTE: The User class in this example extends the BouncerUser class, which provides basic role management functionality and is totally optional):

// Here we add some users. The user class here extends the BouncerUser class, so it can still do whatever you
// would normally create a user class to do..
$user1 = new User();
$user2 = new User();
$user3 = new User();

$user1->addRole("Public");
$user2->addRole("Registered User");
$user3->addRole("Admin");

And now, we take our users and our roles and check to see if they would have access to certain pages:

$bouncer->verifyAccess($user1->getRoles(), "index.php"); // True!
$bouncer->verifyAccess($user1->getRoles(), "viewusers.php"); // False! User 1 does not have access to this page.

$bouncer->verifyAccess($user2->getRoles(), "index.php"); // True!
$bouncer->verifyAccess($user2->getRoles(), "viewusers.php"); // True!

$bouncer->verifyAccess($user3->getRoles(), "index.php"); // True!
$bouncer->verifyAccess($user3->getRoles(), "viewusers.php"); // False! As an Admin, viewusers.php has been replaced
// with manageusers.php

This provides a good demo of how PHP-Bouncer works, but a better real-world example might be to include the following code in an include file on every page of your site:

$bouncer = new Bouncer();
$bouncer->addRole("Public", array("/index.php", "/test/test.php"));
$bouncer->addRole("Private", array("/smartyTest.php"));
$bouncer->addRole("Admin", array("/admin.php"), array("/smartyTest.php"=>"/admin.php"));
$bouncer->addRole("Observer", array("/observer.php"));
$publicOnly = array("Public");
$privateOnly = array("Private");
$observerOnly = array("Observer");
$adminOnly = array("Admin");
$allAccess = array("Public", "Private", "Admin", "Observer");
if(!$bouncer->verifyAccess($adminOnly, $_SERVER["PHP_SELF"])){
    echo "Permission denied for page ".$_SERVER["PHP_SELF"];
    exit;
}

PHP-Bouncer is (at the time of this writing) only about 3 days old, and far from perfect/complete, so feel free to check out the Google Code page for additional documentation and to download bouncer!

Advertisements

Science, it still works!


Today I stumbled upon the following article. I encourage you to read the article, but for brevity I will sum it up. Basically, when creating a for loop in most C-based languages, there are two basic incrementation operators: Pre-increment (++i) and Post-increment (i++), with Post-increment being by far more common. From a functional standpoint, in C# they are equivalent within a loop and always produce the same output. The premise of the article is that while Post-incrementing is recommended by most computer science professors, due to it’s implementation in the ECMA standards it is actually slower than Pre-incrementation.

I tend to be a skeptic, so when I read the article I thought the author must have been mistaken. After all, I assumed that computer science is a field where something as common as the for loop would be well documented and understood by the academics. In order to test the author’s claim I decided to write some code to test how long it took each operator to iterate 1 billion times incrementing a variable on each iteration. Here is the code:

using System;

namespace PostIncrementTest {
    class Program {
        static void Main(string[] args) {
            const long reps = 1000000000;
            for (int k = 0; k < 10; k++) {
                long temp = 0;
                // Define start time
                DateTime firstLoopStart = DateTime.Now;
                // Do a Post-Increment Loop
                for (long i = 0; i < reps; i++) {
                    temp++;
                }
                // Define end time
                DateTime firstLoopEnd = DateTime.Now;
                temp = 0;
                // Define start time
                DateTime secondLoopStart = DateTime.Now;
                // Do a Pre-Increment Loop
                for (long i = 0; i < reps; ++i) {
                    ++temp;
                }
                // Define end time
                DateTime secondLoopEnd = DateTime.Now;
                TimeSpan firstLoopTime = firstLoopEnd - firstLoopStart;
                TimeSpan secondLoopTime = secondLoopEnd - secondLoopStart;
                Console.WriteLine("The post-increment loop took {0} seconds", firstLoopTime.TotalSeconds);
                Console.WriteLine("The pre-increment loop took {0} seconds", secondLoopTime.TotalSeconds);
            }
            // Show that the operators produce the same output
            for(int i = 0; i < 10; i++)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
            for (int i = 0; i < 10; i++) {
                Console.Write(i + " ");
            }
            Console.ReadLine();
        }
    }
}

And the results:

Results of the test, pre-increment is very slightly faster

While there is a measurable difference between the two operators, it is so minute that over the course of 1 billion iterations it only amounted to .02 seconds difference on average on my machine. In a loop used in an every day program, this would most likely make no measurable difference. Although the difference was minute, I may still start using the Pre-increment operator since it is such a small change.

Interesting Read If You Have the Time


Today I was reading about managing hierarchical data using MySQL when I stumbled upon an excellent and extremely informative article. There’s nothing I can add to the article that isn’t better articulated there, so head on over and check it out!

Making HTTP POST Requests in PHP


Recently at my job I have had several situations in which I needed to pass fairly large amounts of data to a particular page on a website for processing, and in which submitting a form isn’t a feasible option. Typically in this situation one would attempt to append the data to the url using GET parameters, but sometimes your data is too large or too sensitive to pass through the URL. Unfortunately, PHP does not provide an easy way to make post requests natively. Luckily for us, there is cURL. cURL allows us to communicate across multiple protocols to a variety of different server types. With cURL, we are able to make HTTP POST requests:

function post_request($url, $data) {
	$output = array();
	foreach ($data as $key => $value) {
		if(is_object($value) || is_array($value)){
			$data[$key] = serialize($value);
		}
	}
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	$result = curl_exec($ch);
	if ($result) {
		$output['status'] = "ok";
		$output['content'] = $result;
	} else {
		$output['status'] = "failure";
		$output['error'] = curl_error($ch);
	}
	curl_close($ch);
	return $output;

}

The above function accepts two parameters, the URL to make the request to, and an associative array containing the keys and values you would like to submit with your POST request. The function returns an associative array containing two values: status, which will either be equal to “ok” or “failure” depending on the success or failure of the POST request; and either ‘content’ or ‘error’ depending on success or failure. In the case of a successful POST request, ‘content’ will contain the full output from the page you have posted to (In other words, you may need to be prepared for an entire html document). Otherwise, ‘error’ will contain the details of the error as returned by cURL.

Taking Control of Your PHP Sessions: Using Database Sessions


Introduction

Recently while working on a project for work, I encountered an interesting issue. I needed to develop a way to add and remove permissions from a User in a system we are building (which will be made open source as a service to the internet community once development is complete), but I needed the ability to push out these permission changes even if a user is currently logged in to the system.

As far as I know PHP does not provide a way to edit User sessions other than the $_SESSION array, which only applies to the current User’s session. After some research, I discovered that it is possible to change PHP’s default session storage method. This can be very useful if you are using a CDN to share server load between multiple servers while still allowing data persistence through the session. Another useful benefit of storing your sessions in the Database is the ability to alter User sessions (for any user) on the fly.

There are a few things to note about editing User Sessions on the fly:

  • If you aren’t careful you can inadvertently edit the wrong session, leading to security issues
  • The way session data is stored in the database is through a single serialized data field. This means that before editing a session variable you must either parse and change only the value you wish to change, or unserialize the entire session data string, edit the individual values, and then re-serialize the data for insert.
  • I have never tried the above method, and therefore cannot provide any code to accomplish this task. If this changes, I will edit this post with the relevant code
  • If you are only storing basic login type data in the session (which would be pulled from the Database), killing a User’s session and allowing them to log back in is the safest way to ensure that any changes to the session will populate correctly

Setting up the Database

The SQL in this tutorial is written to work with MySQL, so if you’re using something else just bear in mind that your syntax may need to be tweaked, especially in the DDL.

Create the Table:

CREATE TABLE SESSION (
id VARCHAR(32) NOT NULL COMMENT 'Stores the Session ID',
access INT(10) UNSIGNED NOT NULL,
data TEXT,
PRIMARY KEY (`id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;

Create a few PHP classes

This first class I built handles the Database connection, and is in two parts: Config.inc.php (for configuring the database variables) and MySQLDatabase.class.php:

Config.inc.php

<?php
define("conf_hostname", "localhost");
define("conf_username", "user");
define("conf_password", "password");
define("conf_schema", "database_to_use");
?>

MySQLDatabase.class.php

<?php
include("Config.inc.php");
class MySQLDatabase{
	private $db;
	private $hostname;
	private $username;
	private $password;
	private $schema;
	
	function __construct() {
		if(func_num_args() == 0){
			$this->hostname = conf_hostname;
			$this->username = conf_username;
			$this->password = conf_password;
			$this->schema = conf_schema;
		}
		else{
			$params = func_get_args();
			$this->hostname = $params[0];
			$this->username = $params[1];
			$this->password = $params[2];
			$this->schema = $params[3];
		}
	}
	
	private function open(){
		$this->db = mysql_connect($this->hostname, $this->username, $this->password) or die ('Error connecting to mysql');
		mysql_select_db($this->schema, $this->db);
	}
	
	public function executeQuery($query){
		$this->open();
		$results = mysql_query($query, $this->db) or die ("Error in query: $query. ".mysql_error());
		return $results;
	}
	
	public function close(){
		mysql_close($this->db);
	}
	
}
?>

Next we need to create a class to handle some session related events:

DatabaseSessionHandler.class.php

<?php
include_once ("MySQLDatabase.class.php");
/**
 *
 */
class DatabaseSessionHandler {
	private $db;

	public function _open($save_path, $session_name) {
		$this -> db = new MySQLDatabase();
		return true;
	}

	public function _close() {
		$this -> db -> close();
	}

	function _read($id) {

		$id = mysql_real_escape_string($id);

		$query = "SELECT data
				FROM SESSION
				WHERE id = '$id'";

		if ($result = $this -> db -> executeQuery($query)) {
			if (mysql_num_rows($result)) {
				$record = mysql_fetch_assoc($result);
				return $record['data'];
			}
		}

		return '';
	}

	function _write($id, $data) {
		$access = time();

		$id = mysql_real_escape_string($id);
		$access = mysql_real_escape_string($access);
		$data = mysql_real_escape_string($data);

		$query = "REPLACE
				INTO SESSION
				VALUES ('$id', '$access', '$data')";

		return $this -> db -> executeQuery($query);
	}

	function _destroy($id) {

		$id = mysql_real_escape_string($id);

		$query = "DELETE
				FROM SESSION
				WHERE id = '$id'";

		return $this -> db -> executeQuery($query);
	}

	function _clean($max) {
		$old = time() - $max;
		$old = mysql_real_escape_string($old);

		$query = "DELETE
				FROM SESSION
				WHERE access < '$old'";

		return $this -> db -> executeQuery($query);
	}
	
	public function killUserSession($username){
		$query = "delete from SESSION where data like('%userID|s:%\"". mysql_real_escape_string($username) ."%\";first_name|s:%')";
		$this->db->executeQuery($query);
	}

}
?>

Replacing PHP’s Session with our Database Session

Now all we have left to do is actually utilize our new session handling. This is actually a relatively painless process. In my application the session is started in the header include file for each page. In this case, all I had to do was change:

<?php
     session_start();
?>

to:

<?php
$sess = new DatabaseSessionHandler();
session_set_save_handler(array(&$sess, '_open'),
                         array(&$sess, '_close'),
                         array(&$sess, '_read'),
                         array(&$sess, '_write'),
                         array(&$sess, '_destroy'),
                         array(&$sess, '_clean'));
session_start();
?>

From here on out, the session can be handled in code exactly like a PHP session, but now you also have the ability to edit User sessions on the fly!

Ubuntu: Automatically Disable Touchpad when External Mouse Connected


Introduction:

If you’re like me, you hate using your touchpad when you could be using an external mouse. If you’re like me you also have a habit of disabling your touchpad when using a mouse, and forgetting to re-enable it until after you unplug your mouse. If you’re like me, this tutorial is exactly what you need.

What you need to get started:

You will need to make sure that you have xinput and halevt installed. You almost certainly already have xinput, but the following command will make sure you have what you need:

sudo aptitude install xinput halevt

I also recommend that you create a folder for scripts (if you haven’t already), and add it to your $PATH. I created a “bin” folder in my home directory for this. Create the folder with:

mkdir ~/bin

and add it to your path by issuing the following commands:

echo "PATH=\$PATH:~/bin" >> ~/.bashrc
echo "export PATH" >> ~/.bashrc

Configure the script:

First we need to create and configure the script which will actually toggle the touchpad:

cd ~/bin
touch toggleTouchpad
gedit toggleTouchpad

The script should now be open in gedit (feel free to replace gedit with your favorite text editor). Paste the following into the script:

# toggleTouchpad by Brendon Dugan
# Toggles a touchpad on or off depending on it's current state or CLI argument
#
# To configure, run the command 'xinput list' in terminal and identify your touch pad.
# Using the output of the above command, change the touchpadString variable to a substring
# of your touchpad's description that is unique to that device.
#
# To run, simply type 'toggleTouchpad' to toggle your touchpad on or off, or
# 'toggleTouchpad on' to explicitly turn your touchpad on, or
# 'toggleTouchpad off' to explicitly turn it off.
#
# Enjoy!

# A function for logging
safemk () {
if [ ! -d $1 ];
  then mkdir $1;
  chmod +rw $1;
fi
}
logdir=/home/$USER/.toggleTouchpad
touchpadString="TouchPad"
touchpadID=$(xinput list | grep "$touchpadString" | awk -F " " '{print $6}' | awk -F "=" '{print $2}')
touchpadEnabled=$(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}')
sleeptime=1

# Create the logging directory
safemk $logdir
touch $logdir/errorLog.txt

# Check for arguments on the command line
if test $# -eq 1
then
	# Change the argument to lowercase
	arg1=$(echo $1 | tr [:upper:] [:lower:])
	cliArg=1
else
	# There is no argument.
	cliArg=0
fi

if [ $cliArg -eq 1 ]
then
	# If there's an argument, check to see whether it is on, off, or junk
	if [ $arg1 = 'on' ]
	then
		# The argument was 'on', so turn the touchpad on
		xinput --set-prop $touchpadID "Device Enabled" 1
		if [ $(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}') -eq 0 ]
		then
			echo "Something went wrong\n" >> $logdir/errorLog.txt
		fi
	elif [ $arg1 = 'off' ]
	then
		# Sleep for a short time to fix a bug that re-enabled the touchpad immediately after disabling it
		sleep $sleeptime
		# The argument was 'off', so turn the touchpad off
		xinput --set-prop $touchpadID "Device Enabled" 0
		if [ $(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}') -eq 1 ]
		then
			echo "Something went wrong, perhaps \$sleeptime needs to be greater than $sleeptime ?\n" >> $logdir/errorLog.txt
		fi
	else
		# The argument was junk, so log the error and go on
		echo "Invalid argument \""$arg1"\" was supplied\n" >> $logdir/errorLog.txt
	fi
else
	# There was no argument, so just toggle the touchpad to the opposite
	# of the state it has now.
	if [ $touchpadEnabled -eq 1 ]
	then
		xinput --set-prop $touchpadID "Device Enabled" 0
	else
		xinput --set-prop $touchpadID "Device Enabled" 1
	fi
fi

Now make the script executable by running:

 chmod +x ~/bin/toggleTouchpad

Ok, we’re almost configured. We need to make sure that your touchpad will be affected by the script. Run the following command to get a list of all current input devices:

xinput -list

It should have an output something like this:

brendon@brendon-lappy-linux:~$ xinput -list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ Logitech Logitech BT Mini-Receiver      	id=15	[slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad              	id=12	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Video Bus                               	id=7	[slave  keyboard (3)]
    ↳ Power Button                            	id=8	[slave  keyboard (3)]
    ↳ Sleep Button                            	id=9	[slave  keyboard (3)]
    ↳ Laptop_Integrated_Webcam_2M             	id=10	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=11	[slave  keyboard (3)]
    ↳ Dell WMI hotkeys                        	id=13	[slave  keyboard (3)]
    ↳ Logitech Logitech BT Mini-Receiver      	id=14	[slave  keyboard (3)]
brendon@brendon-lappy-linux:~$

If your touchpad has the word “TouchPad” (case sensitive) in it, the script is ready to go. If it doesn’t, edit the variable “touchpadString” in the script to match your touchpad… but remember everything is case sensitive. For now, your script is configured. Next step is testing.

Test the script:

Make sure your touchpad is working, and then open a new terminal window. We are going to do four tests. Before and after each test, try your touchpad.

Test 1:

toggleTouchpad

Did your touchpad stop working? Good!

Test 2:

toggleTouchpad

Did your touchpad start working again? Good!

Test 3:

toggleTouchpad off

Wait at least one second…
Did your touchpad stop working? Good!

Test 4:

toggleTouchpad on

Wait at least one second…
Did your touchpad start working again? Good!

Making the magic happen automatically:

We’re almost there! Now we need to set the script to run automatically when your mouse is plugged in. Making sure your mouse is unplugged, run the following command:

halevt -i >>~/connectedDevices.txt

While the command is running, plug in your mouse, and then unplug it. Now press Ctrl +c to kill the process. Open ~/connectedDevices.txt, and you should see something that looks like:

New Device: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial
New Device: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial_if0
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0_logicaldev_input
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0_logicaldev_input
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0_logicaldev_input
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0_logicaldev_input
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial_if0
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial

All of those devices are your mouse. Since each of those events will trigger every time you plug in your mouse, we only need to handle one of them. Pick one that ends in seemingly random numbers, and copy and paste everything after the “:” into a text file. We will be using it in a moment. Now, let’s create our halevt config file:

touch ~/.halevt.xml && gedit ~/.halevt.xml

Paste the following into the file:

<?xml version="1.0" encoding="UTF-8"?>
<halevt:Configuration version="0.1" xmlns:halevt="http://www.environnement.ens.fr/perso/dumas/halevt.html">
	<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023">
		<halevt:Insertion exec="toggleTouchpad off"/>
		<halevt:Removal exec="toggleTouchpad on"/>
	</halevt:Device>
</halevt:Configuration>

We are almost done! Remember the bit I had you paste into another file?? We are going to use that to identify your device. In the config file, change the line that says:

<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023">

to say :

<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/the_rest_of_what_you_copied_into_the_file">

Theoretically, we’re done!

Test the Magic:

From terminal run:

sudo killall halevt
halevt -c ~/.halevt.xml

Now, connect your mouse. If all is going well, about ~1.5 seconds after you plug in your mouse your touchpad should stop working. Now, disconnect your mouse. Your touchpad should start working again.

Making it permanent:

If all went well in the tests, you will want to make this happen automatically forever. Go to “System->Preferences->Startup Applications”, and add a new startup program. Name it something you will remember, and for the command put “halevt -c ~/.halevt.xml”. You’re done!!

Special Thanks:

While writing this script I received a great deal of help from the user Arndt at Ubuntuforums, so you should go leave him lots of love and thanks.

Quickly Toggle Your Touchpad in Linux


For me it is often frustrating trying to use my laptop’s touchpad to do anything that requires even the slightest bit of accuracy, so I use an external mouse whenever possible. Unfortunately, the placement of the touchpad means that I will invariably end up touching it with my palms while I type. Today I finally had enough and decided to take matters into my own hands. The following script will allow you to either toggle your touchpad based upon it’s current setting, or to explicitly turn your touchpad on or off (perhaps as an event to be fired when you plug in or unplug an external mouse). Without further ado:

# toggleTouchpad by Brendon Dugan
# Toggles a touchpad on or off depending on it's current state or CLI argument
#
# To configure, run the command 'xinput list' in terminal and identify your touch pad.
# Using the output of the above command, change the touchpadString variable to a substring
# of your touchpad's description that is unique to that device.
#
# To run, simply type 'toggleTouchpad' to toggle your touchpad on or off, or
# 'toggleTouchpad on' to explicitly turn your touchpad on, or
# 'toggleTouchpad off' to explicitly turn it off.
#
# Enjoy!
touchpadString="TouchPad"
touchpadID=$(xinput list | grep "$touchpadString" | awk -F " " '{print $6}' | awk -F "=" '{print $2}')
touchpadEnabled=$(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}')

# Check for arguments on the command line
if test $# -eq 1
then
	# Change the argument to lowercase
	arg1=$(echo $1 | tr [:upper:] [:lower:])
	cliArg=1
else
	# There is no argument.
	cliArg=0
fi

if [ $cliArg -eq 1 ]
then
	# If there's an argument, check to see whether it is on, off, or junk
	if [ $arg1 = 'on' ]
	then
		# The argument was 'on', so turn the touchpad on
		xinput --set-prop $touchpadID "Device Enabled" 1
	elif [ $arg1 = 'off' ]
	then
		# The argument was 'off', so turn the touchpad off
		xinput --set-prop $touchpadID "Device Enabled" 0
	else
		# The argument was junk, so do nothing
		sleep 1
	fi
else
	# There was no argument, so just toggle the touchpad to the opposite
	# of the state it has now.
	if [ $touchpadEnabled -eq 1 ]
	then
		xinput --set-prop $touchpadID "Device Enabled" 0
	else
		xinput --set-prop $touchpadID "Device Enabled" 1
	fi
fi

Project Euler Problem 3


For project Euler problem 3 we work on a few basic principles that we will use for several upcoming problems (yay reusable code!), factorization and determining whether a number is prime. Here is the problem:

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

One way one could complete this problem would be to find all factors of the given number, and loop through checking if they are prime, returning only the largest one. To start out, let’s find all factors of a number.

import math
def findAllFactors(number):
    factors = list()
    for i in xrange(1, long(math.sqrt(number))):
        if number%i == 0:
            factors.append(i)  
    return factors

Here, we are simply looping through the numbers between 1 and the square root of the number, looking for numbers that divide evenly into our original number. Numbers that divide evenly are factors, so we add them to a list which we return afterward. Alternately, we could create a generator to return all factors:

import math
def findAllFactors(number):
    for i in xrange(1, long(math.sqrt(number))):
        if number%i == 0:
            yield i 

Next, we loop through each factor, checking to see if it is prime using the following code:

def isPrime(n):
    n = abs(long(n))
    if n < 2:
        return False
    if n == 2: 
        return True
    if not n & 1: 
        return False
    for x in range(3, long(n**0.5)+1, 2):
        if n % x == 0:
            return False
    return True

If we have a prime factor, let’s toss it in a list for now:

if __name__ == "__main__":
    factors = findAllFactors(600851475143L)
    primeFactors = list()
    for f in factors:
        if isPrime(f):
            primeFactors.append(f)

or if you are using the generator:

if __name__ == "__main__":
    primeFactors = list()
    for f in findAllFactors(600851475143L):
        if isPrime(f):
            primeFactors.append(f)

Now we simply grab the largest number in the list by sorting it and grabbbing the last item!

    primeFactors.sort()
    print "The Correct answer is: %d" % (primeFactors[-1])

Learn to Program with Python pt. 1


Programming can be a fun hobby and a well paying career for those who learn to do it well, as well as a great way to keep stimulating your brain to keep you sharp and alert. Learning to program on your own can be difficult for some people however. Many programming tutorials have one of the following issues:

  • Talking above your head: Many programming tutorials assume a great deal of knowledge beforehand, and are therefore not suitable for brand-new programmers
  • Being half-heartedly written: Many tutorials start out well, but as the tutorial drags on the author loses interest, and the writing and content suffer dramatically
  • Generally sucking: That pretty much sums it up

I have decided to take my own crack at a programming tutorial, and I will attempt to avoid the previously mentioned pitfalls. There are a few details I would like to cover before we get started. The first is my choice of language. I have chosen to use Python for this tutorial for several reasons, the first and foremost being that I really enjoy programming in Python. I also think Python is great about getting out of your way and letting you program without having to micro-manage details such as Data Types (most of the time) and memory allocation (don’t worry if you don’t know what this means). The next detail I would like to cover is the timeline for this tutorial. I plan on writing this tutorial as multiple blog posts over the next several months, with many unrelated posts in between. If it has been a while, feel free to drop me a comment nagging me for the next issue.

Enough introduction, let’s get started with Programming and Python. To get started, we need to make sure we have Python installed on our system. If you are running Linux, chances are Python is pre-installed. For Windows and Mac users, I recommend ActivePython. ActivePython will install Python to your system, as well as a very basic Python editor (although any text editor will do). Open up your editor of choice and type the following:

print "Goodbye Cruel World"

Now save this as emoProgram.py . This is your first program. Kinda lame isn’t it? Don’t worry, you’ll be writing slightly less lame programs in no time. In fact, the only reason I had you do this is so I could teach you to run your program once you have written it. If you are using PythonWin editor (the editor that came with ActivePython) press Ctrl+R and a box will pop up asking you which file you want to run, and it should have emoProgram.py selected. Press OK, and it will run. If you have chosen to use a different editor (or even if you just like the command line), open up a command prompt and navigate to the folder where you saved your script and type:
python emoProgram.py
and you will see “Goodbye Cruel World” print to your terminal.

In an attempt to make each section as short as possible, I will be stopping here for now and picking up again in a few days with variables, operators, and data types.

My first “real” Python Program pt. 2


In the first post about my first real Python program, I talked about how I parsed out stories based upon a tag-based markup system, prompted the user for values for all of the tags, and then returned the story with all user input in place. Today I will be talking about how I created a system to allow users to write their own stories and have them automatically detected and parsed, as well as allowing users to save their created stories.
(more…)