Wednesday, November 5, 2008

Adding body events to a single catalyst page

I wanted to include some javascript on a single page which was identical to the rest of the site, except it had 'onLoad()' and 'onResize()' events in the page body.

To do this, I created a new ./lib/MyApp/View/, which was identical to ./lib/MyApp/View/ except it pointed to a different wrapper: 'site/jsPageWrapper'.

My 'site/jsPage' was identical to 'site/wrapper' except it called the WRAPPER 'site/jsPageHTML'

In turn, 'site/jsPageHTML' was identical to 'site/html' but with the relevant event handlers on the body tags.

In my controller, I needed to forward to my new view: $c->forward('MyApp::View::NewView').

and that was that.

Sunday, October 5, 2008

Thanks to mst and edenc on irc, I managed to reuse a configuration for connect_info among a number of models. And then I wrote it up for the wiki:

Thursday, October 2, 2008

Template toolkit rendering a hash

I wanted to render a which I generated within my app; it is a calendar basically:
$calendar{$year}{$month}{$day} = daynumber; which I add stash as:
$c->stash->{calendar} = $calendar;

the code I used to get this working is as follows:

[% FOREACH year IN calendar.keys -%]
[% FOREACH month IN calendar.$year -%]
[% SET m = month.key %]
[% FOREACH day IN calendar.$year.$m -%]
[% SET d = day.key %]
values =
[% year %],
[% month.key %],
[% day.key %],
day number = [% calendar.$year.$m.$d %]

[% END %]
[% END %]
[% END %]

Wednesday, September 3, 2008

another day another incantation

I want to use namespaces within my PostgreSQL database (schema in PostgreSQL world). However, they are not currently supported within the Catalyst scripts which will automatically build catalyst::schema automatically.

So the solution is to call Schema::Loader 'manually' with this incantation:

perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("AddressBook::Addresses", { debug => 1, db_schema => "addressStuff" }, [ "dbi:Pg:host=localhost;dbname=testdb", "testuser", "123" ])'

so there you have it: thanks to the irc crew for sorting this out... and they pointed out that cross schema querying will require some jiggery pokery when I get to that...

Friday, August 22, 2008

LDAP, catalyst, roles and groups

After a day or so of effort, I've got LDAP authorization working for groups/roles. I'm posting my config files here, since they worked for me and someone else may stumble across them and find them useful:

my ldif file is as follows:

objectclass: top
objectclass: organization

dn: cn=admin,
objectClass: simpleSecurityObject
objectclass: organizationalRole
cn: admin
description: LDAP Administrator
userPassword: 123

dn: ou=groups,
objectClass: organizationalUnit
ou: groups
description: generic groups branch

dn: ou=people,
ou: people
description: All people in organisation
objectclass: organizationalunit

dn: cn=researchers,ou=groups,
objectClass: groupofnames
cn: researchers
member: uid=richard,ou=people,

dn: uid=lionel,ou=people,
objectClass: top
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Lionel Porcheron
sn: Porcheron
userPassword: password
mail: l@a.b
title: Just a person
initials: LP
ou: people

dn: uid=richard,ou=people,
objectClass: top
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Richard Richard
sn: Richard
userPassword: password
mail: r@a.b
title: Researcher and person
initials: R
ou: people
ou: researchers

This LDIF file creates a group: researchers and a couple of people: richard and lionel. Richard is added to the group of researchers.

# Config for Store::LDAP
default_realm: ldap
class: Password
password_field: password
password_type: self_check
class: LDAP
ldap_server: localhost
timeout: 10
binddn: anonymous
bindpw: dontcare
start_tls: 0
verify: none
user_filter: (&(objectClass=organizationalPerson)(uid=%s))
user_scope: sub
user_field: uid
use_roles: 1
role_basedn: ou=groups,
role_filter: (member=%s)
role_scope: one
role_field: cn
role_value: dn
deref: always

This is my config file for catalyst.

sub list : Local {
my ($self, $c) = @_;
$c->assert_user_roles( qw/researchers/ ); # only researchers and view a list.
my $people : Stashed = $c->model('AddressDB::People');
$c->stash->{template} = 'person/list.tt2';

and this is a chunk of text from my controller.

Hope this is helpful - and saves you some time.

ldap thoughts

I have spent the last day or so trying to get my head around LDAP/Catalyst role authorization. For this project, authentication, authorization and auditing are important considerations.

LDAP seems like a suitable choice for the first two, there is someone else who is worrying about provenance and auditing - all I have to do is make sure the hooks are in place.

My struggle with LDAP and Catalyst was metaphorically like building of the channel tunnel: working from two foreign lands and meeting in the middle. The benefit of this process is that I have a much better understanding of LDAP, and ultimatly, the system works.

LDAP is powerful and it is not obvious that this is the right tool for this deployment.

  • It is mature, stable and well documented.
  • It is scalable and can be integrated into existing infrastructure.
  • Many tools support it.
  • It is complicated to administer.
LDAP will allow this project to relate to exsting web applications which have been deployed already. There is a considerable problem with 'account' creep. Each new application requires the same users to create a new account: username/password - and this is a pain. LDAP provides a foundation apon which this can be centralised and ultimatly - single-sign-on can be implemented.

The mature, stable and widly deployed nature of LDAP means that the administration can be centralised.

Friday, August 15, 2008

centralised configuration

I should be obvious, but today's lesson for me is to centralise configuration at all cost.

And Catalyst should make this easy; and it does.

Next week I should have some machines in the data centre to start building the system on.

Thursday, August 14, 2008

LDAP + catalyst.

LDAP in Catalyst is as easy as it should be... however, just because I'm using Catalyst, dosen't mean I'm doing it right.

On average thought, I think Catalyst will keep things modular so that someone will be able to pick up the work once I've left.

This brings me onto the point of this work: prepare for departure.

Nothing much else to report.

Wednesday, August 13, 2008

LDAP, there must be an upside

LDAP is a fairly natural choice for a organisation who will be distributed over a number of sites and have users with differing roles.

So I thought I'd have a play with it to get a feel for how it would work for us.

That play took a while (two days) but I'm beginning to get a feel for it. While I normally like the command line for alot of sys-admin stuff, I really wanted a graphical browser to surf around entries and make changes.

It took half a day to track down and configure jxplorer, but this did what I wanted and my search ended there. Other candidates which I tried out included:
  • directory_administrator old school X11 interface, does not currently work with OpenLDAP 2.2 or newer - which was a problem for me.
  • lat which was a prone to crashing at my hand: I think due to my incompetence.
  • luma which I couldn't get configured - probably for the same reason I had problems with lat.
after all this tinkering with LDAP, i'm starting to see the benifits though: using tools which support it. The first of these will likely be an ftp server.

The upside: One directory of users with roles, all the services use this directory. Centralised and manageable.

Thursday, August 7, 2008

enhancement to the code

Well, I wondered if this should be part of the catalyst book errerta, but in the end I decided that the code in the book worked, so it wasn't in error.

I have been working through the book using Pg instead of SQLite. The big difference with Pg is that a user/pass are needed. I've navigated a few hurdles on the way, and this afternoon I found another one.

When including a script within your catalyst app, it is The Book has an excellent example which properly integrates your script with the existing config files.

If you construct a DSN in the following way, you can also use the user/pass conbination from your config file!

my @dsn = @{$config->{'Model::AddressDB'}->{connect_info}};

my $HOME = dir($Bin, '..');
$dsn[0] =~ s/__HOME__/$HOME/;

my $schema = AddressBook::Schema::AddressDB->connect(@dsn)
or die "Failed to connect to database at $dsn[0]";

config files

I'm using a config file as I work through the tutorial. This is an obvious thing to do and I completely agree with it. However, when I introduce this structure, I don't really want it to 'over-ride' existing values - I want to delete all the values which are now to be stored only in the config file.

I had to play around a bit. My model previously contained database connection information. When I introduce the config file, the values were taken from the file. However, when I deleted all of the relevant section from the Model, it broke the app. I needed to leave in a minimal stub:

schema_class => 'AddressBook::Schema::AddressDB');

Friday, August 1, 2008

day two, hurdle navigated

Well this is my second day working through the JROCK Catalyst book.

It has been a little frustrating - but this has reinforced some of the paradigms behind MVC and Catalyst so it can be thought of as useful.

Todays TIP: find_or_new does not return and empty model if it fails. The new it returns has the primary key which it failed to find. This could be 'undef' or 'null', and this object is not suitable for a subsequent: update_or_insert. Instead, do a find, if that fails, create a new object.

Thursday, July 31, 2008

Catalyst, day one

I've previously played with Ruby on Rails. My experience was ok with that. However, I considered 'no composite keys' a limitation.

So I've been watching the mailing lists of both CakePHP and Catalyst. I couldn't convince myself that CakePHP would allow for composite keys. In order to evaluate Catalyst, I have bought the book by Jonathan Rockaway and am working thought that.

This is the end of the first day at that and I thought note a couple my initial impressions.

On the book: It is worth visiting the errata. I went thought this and pencilled it into the book before I started reading.

On Catalyst: It seems a little complicated for my tastes. I'm expect that 'complicated' will become 'powerful' as I gain experience in it. We will see.

TIP for today: when creating a model in catalyst, and using a database with a user and password, you'll need to use something like: ...create=static dbi:Pg:dbname=testdatabase testuser testpassword if you want to include a username and password.

brief introduction

The purpose of this blog is to record my experiences while setting up a data centre for some folks.

This is mainly focusing on technology and tools which are used in the work.

Expect frameworks (catalyst), database, linux, perl, security.

if I manage a post every day I spend working on the technology behind the datacentre I'll be pleased.

first post!

Get the difficult first post out the way.