Luxón: una aplicación catalyst
Como toda herramienta que se precie, Catalyst también tiene su curva de aprendizaje. Siempre he creído que la mejor forma de aprender a usar algo es aplicarlo en un proyecto real, que las pruebas de campo y los experimentos están bien, pero donde uno se curte es en el mundo real.
Voy a escribir una pequeña aplicación llamada Luxon
que permitirá a mis
usuarios de correo efectuar algunas operaciones sobre su cuenta:
- Cambio de contraseña
- Cambio de nombre
- Creación de alias
- Mensajes vacacionales
Así que voy a reunir en esta página una lista de notas sobre tareas comunes,
que siempre se me terminan olvidando, para luego pasar a hablar más en
profundidad de luxón
como tal.
Comenzar una aplicación Catalyst
En el directorio padre que va a contener nuestro nuevo proyecto usamos la siguiente orden:
$ catalyst.pl Luxon
created "Luxon"
created "Luxon/script"
created "Luxon/lib"
created "Luxon/root"
created "Luxon/root/static"
created "Luxon/root/static/images"
...
created "Luxon/script/luxon_fastcgi.pl"
created "Luxon/script/luxon_server.pl"
created "Luxon/script/luxon_test.pl"
created "Luxon/script/luxon_create.pl"
$
Luego podemos añadirlo directamente al repositorio como:
$ svn add Luxon
A Luxon
A Luxon/root
A Luxon/root/static
A Luxon/root/static/images
A (bin) Luxon/root/static/images/btn_120x50_powered_shadow.png
...
$ svn commit -m "- Nuevo proyecto Luxon"
Configurar complementos (plugins)
Abrimos nuestro módulo principal de la aplicación:
$ cd Luxon
$ vim lib/Luxon.pm
y allí nos aseguramos de tener una línea de invocación de Catalyst más o menos como sigue:
1 use Catalyst qw/-Debug ConfigLoader Static::Simple/;
lo que nos muestra los complementos que vamos a cargar en nuestra aplicación. En este caso vemos la disposición predeterminada y que viene a indicar que:
-Debug
: Activa el modo de depuración, que mostrará mensajes en la consola donde iniciamos el servidor de pruebas.ConfigLoader
: este complemento proporciona un mecanismo para cargar valores en la aplicación desde un archivo YAML.Static::Simple
: proporciona una forma simple de servir contenido estático (imágenes y hojas de estilo) desde el servidor de pruebas.
En nuestro caso, además, vamos a añadir estos otros:
Añadir un modelo de datos
Para añadir un modelo de datos a la aplicación usaremos el programa auxiliar que nos permite invocar a los auxiliares correspondientes:
$ script/luxon_create.pl model LDAP
exists "/home/victor/sources/Luxon/script/../lib/Luxon/Model"
exists "/home/victor/sources/Luxon/script/../t"
created "/home/victor/sources/Luxon/script/../lib/Luxon/Model/LDAP.pm"
created "/home/victor/sources/Luxon/script/../t/model_LDAP.t"
$
En este caso estamos usando el modelo LDAP, puesto que nuestro programa debe conectar con un servidor de este tipo y efectuar cambios en él.
Añadir un controlador
El controlador en una aplicación Catalyst es aquél que responde a las
peticiones GET
y POST
del cliente.
En nuestro caso vamos a crear uno específico para tratar con usuarios, dado que el programa puede tener ampliaciones futuras y no queremos dispararnos en el pie.
$ script/luxon_create.pl controller Users
exists "/home/victor/sources/Luxon/script/../lib/Luxon/Controller"
exists "/home/victor/sources/Luxon/script/../t"
created "/home/victor/sources/Luxon/script/../lib/Luxon/Controller/Users.pm"
created "/home/victor/sources/Luxon/script/../t/controller_Users.t"
Añadir una vista
En nuestro caso vamos a usar TTSite dado que queremos crear un lugar de aspecto coherente, y ya tenemos cierta experiencia con él (Taquiones antes de ikiwiki estaba construído con él).
$ script/luxon_create.pl view TT TTSite
exists "/home/victor/sources/Luxon/script/../lib/Luxon/View"
exists "/home/victor/sources/Luxon/script/../t"
exists "/home/victor/sources/Luxon/script/../lib/Luxon/View/TT.pm"
created "/home/victor/sources/Luxon/script/../lib/Luxon/View/TT.pm.new"
created "/home/victor/sources/Luxon/script/../root/lib"
created "/home/victor/sources/Luxon/script/../root/src"
created "/home/victor/sources/Luxon/script/../root/lib/config"
created "/home/victor/sources/Luxon/script/../root/lib/config/main"
created "/home/victor/sources/Luxon/script/../root/lib/config/col"
created "/home/victor/sources/Luxon/script/../root/lib/config/url"
created "/home/victor/sources/Luxon/script/../root/lib/site"
created "/home/victor/sources/Luxon/script/../root/lib/site/wrapper"
created "/home/victor/sources/Luxon/script/../root/lib/site/layout"
created "/home/victor/sources/Luxon/script/../root/lib/site/html"
created "/home/victor/sources/Luxon/script/../root/lib/site/header"
created "/home/victor/sources/Luxon/script/../root/lib/site/footer"
created "/home/victor/sources/Luxon/script/../root/src/welcome.tt2"
created "/home/victor/sources/Luxon/script/../root/src/message.tt2"
created "/home/victor/sources/Luxon/script/../root/src/error.tt2"
created "/home/victor/sources/Luxon/script/../root/src/ttsite.css"
$
Nota: observado que ha creado un archivo con extensión
.new
y cuyo contenido difiere bastante del homónimo sin la extensión. Al parecer Catalyst::Helper proporciona la posibilidad de no sobreescribir un archivo y limitarse a añadir el nuevo contenido de dicha manera. Para desactivar este mecanismo, algo siempre peligroso, se debe usar el parámetro-force
cuando se invoca al auxiliar.
Detalles importantes
Identificación de usuarios
Los usuarios del sistema se identifican mediante el mecanismo PAM , el
cuál ya está preparado para leer de la base de datos del sistema primero, y del
servidor LDAP
a continuación, si el primero no responde ó el usuario no existe
en él; sí, los usuarios virtuales se gestionan de esta forma.
En principio la identificación de usuarios vamos a realizarla contra el
directorio LDAP
, dado que nos interesa en este caso que el programa funcione
en una máquina y los datos estén en otra. PAM
podría perfectamente conectarse
remótamente, pero eso implicaría una instalación de este mecanismo en la
máquina que da servicio web; y no, por razones que no vienen al caso no es eso
lo que me interesa.
Nota: he encontrado un módulo perl llamado Catalyst::Plugin::Authentication::Credential::PAM y cuyo autor es Rafaël Garcia-Suarez que sirve precisamente para emplear
PAM
en Catalyst. No lo he probado pero lo tengo apuntado para más adelante.
Así pues, emplearé la identificación de usuarios usando sesiones y el módulo Catalyst::Plugin::Authentication::Store::LDAP.