Sean’s Obsessions

  • Archives

08 Oct

Getting sick of elections

(Disclaimer: I’m a conservative)

I’m getting sick of the “[insert conservative thinking party] gave tax cuts to big evil corporations and is therefore not your friend”. I think it oversimplifies the issue.

Ignore the fact that it’s a tax cut, because that’s irrelevant. It could be a suitcase of money, it’s just that tax cuts are an easier way to give money from the government to another party. No cheques need to be written.

While I’m sure there are exceptions, the idea behind giving money to a company is to entice them to do something. To open an office where it’s otherwise not economically feasible. To not close down a particular site. To get them to work in some area that furthers a government’s policy.

So from that perspective, “XXX gave money to this big faceless corporation” is only telling half the story. It’s no different than saying “I took a car from the dealership” without saying “and paid for it”.

Secondly, it can be viewed as an investment. Those jobs generate payroll taxes, income taxes, and sales taxes. It gets people off of social assistance. Even if you subscribe to the “evil faceless corporations will evade income taxes” theory, there is always some trickledown.

Sure, some more transparency would be good. Maybe a deal was made that we’ll never hear about. Maybe the deal is documented in some place, but we only hear about the tax cut side of the equation.

I don’t normally get worked up about politics. What gets me going is the use of numbers to tell a story that’s just untrue.

29 Feb

Testing via screen scraping

Trying to figure out how to write a test based on screen scraping. Easiest example is to make sure that certain URIs redirect to the login screen.

Created an “automated” dir under app/tests/cases/, with a file called permissions.test.php:

<?php

class PermissionsTestCase extends CakeWebTestCase {

        var $mysite = "http://test.mysite.com";
        function setUp() {
        }

        function tearDown() {
        }

        function testMe() {

                $this->setMaximumRedirects(0);
                $result = $this->get($this->mysite . "/");
                $this->assertResponse(302);
                $this->assertHeader("Location", $this->mysite . "/users/login", "Homepage redirects to login");
        }
}
?>

The “setMaximumRedirects” is there because WebTestCase will, by default, follow 3 redirects. Here I tell it not to, then I get a page and check the status code and the header.

Lots of stuff you can test specific to a web page: http://simpletest.org/api/SimpleTest/WebTester/WebTestCase.html

29 Feb

How the hell do you test a controller?

Testing models is straightforward, see http://bakery.cakephp.org/articles/view/testing-models-with-cakephp-1-2-test-suite

Testing a controller though… Why is there nothing good out there that tells you how to test a controller, other than references to Felix’s work that doesn’t use simpletest?

That said, testing a controller should look something like

- Create controller object
- Call an action
- Poke at the controller to make sure it looks ok.

To test, I baked a controller and put in one action:

<?php
class PrintersController extends AppController {
        var $name = 'Printers';
        function foo() {
                $this->set("something", "some value");
                return 1;
        }
}
?>

I then modified the baked test case (tests/cases/controllers/printers_controller.test.php)

<?php

App::import('Controller', 'Printers');

class PrintersControllerTestCase extends CakeTestCase {
        var $TestObject = null;

        function setUp() {
                $this->TestObject = new PrintersController();
        }

        function tearDown() {
                unset($this->TestObject);
        }

        function testMe() {
                $result = $this->TestObject->foo();
                debug($this->TestObject);
        }
}
?>

After running the test, I could see the methods and variables in the controller. The stuff I could see testing in the controller is mostly the vars that get passed to the view, so after consulting the debugs I changed testMe() to

        function testMe() {
                $result = $this->TestObject->foo();
                $vars = $this->TestObject->viewVars;
                $this->assertEqual($vars["something"],
                     "some value");
                debug($this->TestObject);
        }

$vars is an array of the stuff that’s going to be sent to the view. Logically, if my model tests are correct and I have fixtures set up, the stuff that gets generated by the controller should be predictable and therefore testable.

I also noticed some other entries in the debug output, such as pagetitle. I’m sure there’s more, but this is a good start for now. Wh

25 Dec

I’ll be speaking at Sharkfest ‘08

I’m giving 2 talks on using Wireshark to expose VoIP problems at Sharkfest ‘08 (schedule). Details are sketchy, I think one of the talks is more of a hands on lab, the other is me talking. I’ve expanded on my techniques from the Linux Journal article I wrote on the topic.

Some other fascinating topics going on at the same conference. Hope to see you there.

24 Nov

Frameworks don’t suck

I’ve often had a dim view of web frameworks. At b5media we had more than one case where we’d send out some pretty basic development to be done, and we’d get it back, done in a framework that took more time to get running than it was worth. And, from a performance perspective, all that overhead has got to slow things down.

Now that I have a tiny bit more time on my hands I’ve started to try and write some code that I’ve been meaning to. As I sat down to it I started thinking of all the overhead I’d have to write — some authentication, some mapping of URLs to functions, database stuff, and then it hit me — this is what a framework does.

Given I had no deadline to meet, I decided to try out a framework. I’m not a Python guy, so Django was out. Rails sounded sexy, but the last thing I needed was to learn a new language, especially one that looks like it was written by someone on crack and that looked more like line noise than Perl.

I’d rather have picked on in Perl, but knowing that I’d probably be putting this on a shared host at some point, PHP was probably the best bet.

Symphony caused me no end of grief at b5, so it was out. I ready a bit about Zend but decided it wasn’t for me. Code Igniter seemed like too much of a moving target, which left CakePHP. Looking further into Cake it seemed like it was well laid out, had a large community with active development, and does a lot of things Rails does. What sold it for me was that it was one of the few frameworks that supported PHP4 which is on many shared hosts still.

Over the course of an evening I went through the first 3 CakePHP tutorials at IBM. Then I picked one of my projects and started slugging through it.

After a couple of weeks I learned the following:

MVC is really good for web apps. It took me a while to put the SQL generation in the hands of the framework, but most of my queries are simple anyway. Besides, I can always do $this->Model->Query(”SELECT blah..”).
Using a framework gets you up and running fast. Most of my programming is trying something, seeing how it looks, then trying something else. The framework lets me get to that point quickly, especially with scaffolding if I still haven’t finished a particular model/table.
It’s not slow at all. I haven’t got around to profiling it, but the response time is quick, and it’s not taking up much space in my opcode cache, no more than Smarty would have
Programming’s a lot more fun when you let the framework do all the crap work

14 Nov

Skinny controller, fat model

I understand how to work within the MVC (model, view, controller) system of development, but once I read skinny controller, fat model I realized what it’s all about. Even though it’s written for Ruby on Rails it’s easy enough to transport to your framework of choice.

I’ve heard the term “fat model” before, but really had no idea how to fatten up my model. Now I know.

05 Nov

Pushing a CakePHP app from dev to prod

After more work on a CakePHP app I wanted to host it somewhere. Because this is a fairly low volume app I went with a shared hosting provider.

One problem was that I needed two different database connections, one for my development site, and one when I push it to the server. It was fairly easy to set up two different connections in app/config/database.php:

var $default = array('driver' => 'mysql',
'connect' => 'mysql_connect',
'host' => 'localhost',
....
var $production = array('driver' => 'mysql',
'connect' => 'mysql_connect',
'host' => 'PRODUCTION_HOST',
.....

Then within cake/app_model.php I did a check within the constructor:


class AppModel extends Model{
function __construct($id = false, $table = null, $ds = null) {
if ($this->isProd()) {
$this->useDbConfig = 'production';
} else {
$this->useDbConfig = 'default';
}
parent::__construct();
}
function isProd() {
$server = $_SERVER["HTTP_HOST"];
if ($server == "DEVELOPMENT_SERVER") {
return false;
} else {
return true;
}
}
}

The next order of business was to script pushing code.


#!/bin/sh
#
# FTP information
FTPHOST=xxxx.com
FTPUSER="xxxx"
FTPPASS="xxxx"
# do we cd to a dir after logging in?
FTPDIR=.
# path to base of svn
SVNDIR="http://svnserver/svn/project"
TMPDIR=/tmp/$$
#
if [ "x$1" == "x" -o "$1" == "trunk" ]; then
SVNURL="${SVNDIR}/trunk/"
else
SVNURL="${SVNDIR}/tags/$1/"
fi
#
echo $SVNURL
mkdir -p $TMPDIR
#
(cd $TMPDIR && svn export $SVNURL code )
#
(cat - < cd $FTPDIR
lcd ${TMPDIR}/code
put .htaccess
mput -R *
chmod 777 app/tmp
mkdir app/tmp/cache
chmod 777 app/tmp/cache
mkdir app/tmp/logs
chmod 777 app/tmp/logs
mkdir app/tmp/sessions
chmod 777 app/tmp/sessions
SCRIPT
) | ncftp -u $FTPUSER -p $FTPPASS $FTPHOST
#
rm -rf $TMPDIR

This pulls the current code out of subversion (either trunk or a tag) and uploads it to the server. ncftp is pretty good at only uploading changed files.

In the end I used 1 and 1 (aff) and their $4/mo beginner plan that came with a free domain name. There was one problem with 500 errors with 1and1 that was fixed by changing the .htaccess files (no problems on the dev side either)

The only thing I need to change is to move the isProd() function somewhere that is accessible in the configuration class so that errorlevels are changed depending on the environment. This could also be taken care of in the svn branch.

04 Nov

A simple authentication system with CakePHP 1.2 and Auth Component

I’ve been learning the CakePHP framework recently, and came to need a simple user login system.

Judging by the documentation out there, ACLs are the way to do it. However after spending an hour trying to figure out all the contradicting articles out there I gave up. ACLs are very precise, all I need is a simple “Sean is logged in” type of thing.

More reading on the Bakery pointed me to the Auth component, which does exactly what I need. Again though, I found incomplete documentation, which combined with reading some of the code and trial and error, I figured it out. What I ended up with was a system that:

  1. By default requires users to log in with a username (email) and password
  2. Guests trying to access a protected resource get redirected to the login screen
  3. Controllers can determine which methods need protection and which don’t
  4. Supports basic groups - registered users are “users”, admins are “admins”. The controller figures out the rest based on that string
  5. It’s easily understood, and doesn’t require a lot of code in each controller

So to start I need a user model:

CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`email` varchar(255) NOT NULL,
`password` char(32) NOT NULL,
`role` varchar(20) NOT NULL default 'user',
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

The corresponding model code (user.php) is:


class User extends AppModel {
var $name = 'User';
var $validate = array(
'email' => VALID_NOT_EMPTY,
'password' => VALID_NOT_EMPTY
);
function beforeSave() {
if ($this->data['User']['password']) {
$this->data['User']['password'] = md5($this->data['User']['password']);
}
return true;
}
}

As a password is written into the database, it is automatically md5′ed.

Because I want authentication on every page (with exceptions… hang in there) it’s done at the cake/app_controller.php level in a beforeFilter hook:

class AppController extends Controller {
var $components = array("Auth");
function beforeFilter() {
// Handle the user auth filter
// This, along with no salt in the config file allows for straight
// md5 passwords to be used in the user model
Security::setHash("md5");
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'myprofile');
$this->Auth->logoutRedirect = '/';
$this->Auth->loginError = 'Invalid e-mail / password combination. Please try again';
$this->Auth->authorize = 'controller';
}

All the $this->Auth lines fill in the various behaviours, such as what the login page is. Setting “authorize” to “controller” means each controller must have an isAuthorized() function that returns true or false if the already authenticated user is authorized to do the action. The key was setting the hash to MD5, because the default is SHA1 and that wasn’t working with my model I made earlier. You also must edit your config file to remove the salt. This behaviour may be recent though, I see some reports that the Auth component uses plaintext passwords which is untrue in HEAD.

With this in place, all pages will require authentication. To fix that, in the controllers you want to be open, add a beforeFilter:


function beforeFilter() {
$this->Auth->allow("*");
parent::beforeFilter();
}

This will allow all actions in the controller to pass without authentication. allow() seems to take a list of actions that don’t need authentication, * means all. If only a few actions needed authentication, I’d do $this->Auth->allow(”view”, “foo”) to allow the view and foo actions to be open.

If you need to see the user that is logged in, use $this->Auth->user(), which returns the model. From there I can get the role/group, or whatever else I put in there. It doesn’t seem you can set() variables for the view in the beforeFilter, so if you want the view to have part of the User model you should set() it elsewhere.

For my login function, I stole it directly from this tutorial. (Actually most of what I did was based on that tutorial, my contribution is really the explanation of the MD5 stuff and the allow() action (the latter which I now see is in his tutorial, just buried down in another section))


if ($this->Auth->user()) {
if (!empty($this->data)) {
if (empty($this->data['User']['remember_me'])) {
$this->Cookie->del('User');
} else {
$cookie = array();
$cookie['email'] = $this->data['User']['email'];
$cookie['token'] = $this->data['User']['pasword'];
$this->Cookie->write('User', $cookie, true, '+2 weeks');
}
unset($this->data['User']['remember_me']);
}
$this->redirect($this->Auth->redirect());
}

The rest of the code is fairly simple, a register action to set up an account, and a logout function to call $this->Auth->logout.

08 Oct

b5media launches Spekked

b5media has launched an entertainment gateway
Our dev team worked around the clock (literally… you go Brian!) to get this ready for launch. I think it’s a great evolution of the channel concept. Rather than just having a bunch of blogs in a channel, we have this portal to help showcase the best posts, and the people behind it.

16 Sep

MythDora and jumpy livetv

After my previous post I ended up wiping my Myth box and installing Mythdora. Apparently there are some unresolved issues in F7’s kernel and the ivtv packaging.

Everything worked well except recording was funny. Watching livetv was jumpy… Every few seconds the audio and video would stutter. Watching a show on the MVP downstairs was interesting because it appeared that it was being played back at 110% speed, and people were talking like chipmonks.

This lead me to this link which suggested I get rid of the video4linux-kmdl modules and rebuild the saa7127 module from the kernel tree. That post referenced these instructions which were helpful, but not 100% complete.

First I googled for kernel-2.6.20-1.2962.fc6.src.rpm and found a site with the source RPM for the kernel I was running. I also needed to find the kernel-devel for this package (kernel-devel-2.6.20-1.2962.fc6.i686.rpm)


yum install rpm-build m4 make gnupg gcc redhat-rpm-config ncurses-devel
cd /usr/src/redhat/SPECS
rpmbuild -bp --target=i686 kernel-2.6.spec
cd /usr/src/redhat/BUILD/kernel-2.6.20/linux-2.6.20.i686/
cd include
ln -s asm-i386/ asm
cd ..
make scripts
make oldconfig
make menuconfig

Then I followed the instructions in the second link to configure the kernel, and build the module


make drivers/media/video
make M=drivers/media/video
cp drivers/media/video/saa7127.ko /lib/modules/2.6.20-1.2962.fc6/kernel/drivers/media/video/
depmod
reboot

The instructions worked well, the only hard part was getting the kernel build environment set up. The make was complaining that it couldn’t find some header files (asm/types.h), and it was that symlink that was needed.

© 2008 Sean’s Obsessions | Entries (RSS) and Comments (RSS)

Powered by Wordpress, design by Web4Sudoku, based on Pinkline byGPS Gazette