Archivos del sitio
Chikilicuatre y la inyección de lógica en la capa de cliente
No comments please :-)
¡¡¡Teclea, teclea!!!
El javascripy mola mogollón,
funciona en explorer y también en firefox.
Ponle javascripy a esa paginita,
que el javascripy la deja muy bonita.
Abre ventanas,
muestra mensajes,
valida formularios,
mi amol ya tu sabes!
Programan los seniors,
Programan los juniors,
Programa mi jefe con acentos en el function!
Y el javascripy se programa asi:
1-El tag <script>
2-el function vars
3-el alert-confirm
4-el return trú
Programa el javascripy,
Programa el javascripy,
programan los heavys también los frikis
Programan en la offis, programan en la uni,
Programan los fruittis y también los lunnis.
Programa Maradona esnifando una raya,
y Juan Carlos le dice: ¿Porque no usas ajax?
En el formulario de un triste portal,
pusieron javascripy y ya pudo validar
¡¡¡Validar!! ¡¡Validar, validarr, validarrr!!!
Y el javascripy se programa asi:
1-El tag <script>
2-el function vars
3-el alert-confirm
4-el return trú
Matar un proceso externo desde Java (por nombre, no por pid)
Recientemente nos hemos enfrentado a un problema en uno de nuestros proyectos.
Resulta que el servidor OpenOffice que usamos en ese proyecto para determinadas tareas, en algunas circunstancias se queda totalmente “tonto”. El proceso esta ahi, el servidor no hace crash, pero no responde a ninguna llamada.
Decidimos cortar por lo sano, y hacernos un daemon que chequease si el servidor estaba respondiendo. Si no responde, matamos el servidor, y lo rearrancamos.
No tiene mucho misterio el tema.
Pero nos enfrentamos a algo que nunca antes habiamos hecho: Como matar un proceso que no habiamos iniciado nosotros y del que unicamente sabiamos su nombre?
Bueno, buscando un poco en google, y sacando ideas de un foro aqui, y otro foro alli, llegamos a desarrollar esta funcion que quizas le sea de ayuda a alguien que tenga en el futuro un problema similar.
Por supuesto el daemon debe tener privilegios de nivel suficiente para ser capaz de acabar con el proceso a matar, en nuestro caso “soffice”.
private void matarSoffice() {
String osName = System.getProperty("os.name");
String cmd = "";
if(osName.toUpperCase().contains("WIN")){//S.O. Windows
cmd+="tskill soffice";
}else{//Solo ha sido probado en win y linux
cmd+="killall soffice";
}
Process hijo;
try {
hijo = Runtime.getRuntime().exec(cmd);
hijo.waitFor();
if ( hijo.exitValue()==0){
System.out.println("soffice matado con exito");
}else{
System.out.println("Incapaz de matar soffice. Exit code: " + hijo.exitValue()+"n");
}
} catch (IOException e) {
System.out.println("Incapaz de matar soffice.");
} catch (InterruptedException e) {
System.out.println("Incapaz de matar soffice.");
}
}
Hala pues,
OpenCms: difama y vencerás
Últimamente vengo observando en diversos grupos de opinión de nuestro entorno una creciente animadversión hacia OpenCms como plataforma de gestión de contenidos, indiferentemente de la versión de la que hablemos (la versión 7 ya lleva bastante tiempo estabilizada). Puedo entender cierto picorcillo contra una serie de experiencias de hace ya varios años, basadas en implantaciones de un pseudo-OpenCms 5 que tenía por delante un fuerte desarrollo frontend para dotarle de funcionalidades de las que no disponía esa versión. El problema (y la ventaja) del software libre es que tienes ahí el código fuente, listo para adaptarlo a tus necesidades. Pero claro, si lo “adaptas demasiado”, te separas de la línea principal de desarrollo y te quedas anclado en la versión antigua. Sin embargo, de eso no tiene la culpa el software (en este caso, OpenCms), sino el equipo que forman los contratados para hacer algo, y los que contratan eso.
La mayoría de organizaciones que buscan un CMS requieren una serie de características muy difíciles de conjugar:
- Que sea software libre, y además gratuito.
- Que los usuarios puedan ser dueños y señores de su web, pudiendo introducir contenidos con editores WYSIWYG, imágenes (y que se auto-redimensionen), contenidos estructurados (noticias, eventos, ficheros, etc.), con herramientas sencillas y usables…
- Que a pesar de todo ello, se mantenga la accesibilidad de la página (algo complicado, porque los editores visuales no pueden generar HTML semánticamente correcto). ¿Quién le impide a un usuario poner un título con una etiqueta que no sea una <h1>, <h2>, …<hN>?
- Circuitos y flujos de aprobación de los contenidos.
- Gestión de permisos de edición y publicación sobre diferentes áreas funcionales, recursos, etc. Por ejemplo, “el grupo de prensa puede crear noticias”, etc.
- Velocidad, estabilidad y alta disponibilidad: cacheo, posibilidad de balanceo de carga, clusterización…
- Posibilidad de definir nuevos contenidos de la forma más sencilla posible, y la máxima flexibilidad para plasmar estos contenidos en la zona web (por ejemplo, un evento, que se pueda desplegar como un calendario).
- Facilidad de mantenimiento (tanto a nivel Sistemas como Desarrollo), de forma que la evolución del portal sea lo menos costosa posible.
- Publicación/despublicación diferida (programada para una fecha concreta).
- En muchos casos, soporte multi-idioma.
- Soporte de plantillas y temas.
- Posibilidad de introducir zonas privadas con autenticación de usuarios (con funciones de registro, recordatorio de contraseñas, roles y visibilidad, etc.).
- Funcionalidades más o menos avanzadas: indexación de contenidos (web, ficheros, etc.) y búsqueda, autogeneración del mapa de la web, autogeneración de migas (breadcrumbs) de navegación, autogeneración de menús, etc etc etc.
A lo largo de mi vida profesional he probado innumerables plataformas CMS. En Carrefour España fui el Jefe de Proyecto responsable de la creación de la intranet corporativa de la empresa, basada en el entonces novedosísimo PhpNuke versión 6 :-) desarrollada por los nunca suficientemente valorados Simplelogica. He sido siempre un gran defensor de PHP como plataforma de desarrollo rápido, con plataformas bastante interesantes (Joomla, Drupal…) y veo con interés las apariciones de otras alternativas como Plone (Python), frameworks de desarrollos como Ruby On Rails, etc. Sin embargo, en este mercado suelen confundirse mucho los productos de portal, como era ese PhpNuke, mal llamados CMSs, con los productos de gestión de contenidos, como son OpenCms, Vignette, etc. De hecho, en tecnologías Java hablamos de dos especificaciones distintas: la JSR-170 para la persistencia de contenidos y la JSR-168 más orientada a portales, y en concreto a la estandarización de los componentes portlets.
En el caso de la Junta de Andalucía, que me pilla bastante cerca, no puedo entender cómo se puede poner en duda la utilización de OpenCms (al menos su última versión 7). Cumple a rajatabla todos los requisitos que se suelen solicitar, como los que he enumerado anteriormente, pero además tiene una serie de ventajas de gran importancia:
- Tiene excelentes características de rendimiento (cacheo avanzado, posibilidad de clusterizar y balanceo de carga…).
- Es coherente con la apuesta tecnológica (JAVA). Y eso es MUY importante para una organización que haya hecho una apuesta por una tecnología. Cuando ya dispones de programadores formados, de personal de Sistemas (muchos de ellos funcionarios de la propia Junta) que sabe gestionar servidores de aplicaciones y motores de servlets como JBoss, Oracle iAS, Tomcat, o SGBDR como Oracle 9i ó 10g, ¿de verdad es buena idea comenzar a desarrollar con plataformas como Python o PHP? No quiero decir que estas plataformas sean mejores o peores (como siempre, dime para qué), pero en una gran organización la estandarización es realmente importante.
- A pesar de ser Open Source, tienen una empresa detrás (en este caso, Alcakon) que asegura la estabilidad, e incluso, por qué no decirlo, la posibilidad de acceder a servicios de soporte y mejoras de pago. Nunca olvidemos que la estrategia comercial del Software Libre se basa en los servicios. Ocurre igual con otros productos Open Source de moda como Alfresco, Open Office, algunas distribuciones de Linux, Tomcat, Hibernate, JBoss y tantos otros…
No sé si estaré influenciado por el excelente nivel de mis compis en OpenCms. No sólo se han ido encargando de realizar las traducciones al castellano, sino que la verdad es que han desarrollado portales estupendos, permitiendo a usuarios de dudoso nivel técnico (pedían que se les enseñase a copiar y pegar, verídico) meter, por ejemplo, complejos mapas de Google con zonas sensibles que desplegaban vídeos Youtube y galerías de imágenes Lightbox. Sacar a la luz portales en una semana. Y experiencias super-interesantes técnicamente, como crear una infraestructura OpenCms 6 clonable, de forma que se puedan crear múltiples portales (en este caso, para Ayuntamientos de la provincia de Sevilla) en apenas un par de horas de desarrollo, y cambiado el estilo inyectando CSS (al estilo del proyecto CSS Zen Garden de Dave Shea). Dos ejemplos interesantes son la web del Ayuntamiento de Paradas y la del Ayuntamiento de Gelves. Cualquier curioso podrá observar que tienen el mismo HTML. Las últimas noticias que tenía es que más de 50 Ayuntamientos de la provincia están usando, o van a usar, esta tecnología que montamos para la Diputación de Sevilla.
Plataformas como OpenCms, Plone o el excelente Joomla (o Drupal, quizás ya muy desplazado por éste último) son buenas en sí mismas, pero los que las hacen buenas o malas en la realidad son los desarrolladores. Al igual que ocurre con un proyecto JSF, Struts2 o RubyOnRails, el conocimiento es el que marca la diferencia. El problema es que de vez en cuando, se encargan estudios y comparativas a personas que no han estudiado y comparado todas las plataformas, y que tienen claro el resultado objetivo antes de empezar. Para hacer una comparativa seria, debería fijarse un objetivo, y realizar un pequeño piloto con cada alternativa. Analizar diferentes parámetros: facilidad de desarrollo, flexibilidad, ajuste a las necesidades de los usuarios, estabilidad (pruebas de estrés, etc.). Así se puede escribir con propiedad y convencimiento que X es mejor que Y y peor que Z para esta necesidad y este caso concreto.
Siempre será más fácil destruir que construir. Decir “X es una mierda” cala mucho más que un discurso técnico que suele aburrir a todo interlocutor que no se interese tanto por la tecnología como el entusiasta friki que habla de las excelencias de un software complejo. En este caso, creo que OpenCms está sufriendo este tipo de campaña de desprestigio, cuando, como cualquier otra plataforma, los que las harán buenas o malas serán los desarrolladores.
El reto público Viavansi: Paintball
Desde VIAVANSI queremos hacer un reto público a las empresas y clientes de nuestro sector, para resolver nuestras “diferencias” en el campo de batalla :-P
El escenario podría ser el Paintball Sevilla, aunque para que nadie se crea que jugamos con ventaja, aceptamos combatir donde quieran y cuando quieran :-)
Al parecer Guadaltel ya ha recogido el guante…
Desafíos a karts, Wii o futbolín también son bienvenidos.
La duda ecologica
Lo he hablado con algun compañero de viavansi.
Que es mas ecologico? Secarse las manos con papel, o con el secador de aire caliente?
Parece que hay cosas mas faciles como decidir si es mas ecologico usar una taza de ceramica, o un vaso de plastico? Pero, realmente esta tan claro??
Interesante articulo aparecido en tree-nation:
http://www.tree-nation.com/community/econews_comments.php?news_id=281
Por cierto, si no tienes un arbol en Niger, a que esperas? www.tree-nation.com
Framework Seam: autorización en aplicaciones
Como todos ya sabemos uno de los puntos importantes de una aplicación web es el control de la seguridad en cuanto a la autenticación y la autorización de usuarios.
Básicamente a la Autenticación le corresponde la tarea de ver quién es el usuario y a la Autorización le corresponde permitir o no el acceso a las distintas zonas de una aplicación web a partir, por ejemplo, de su perfil en la aplicación.
En este post me centraré en la Autorización, ya que Jboss Seam tiene mucho que decir al respecto, y os muestro una posible implementación para controlar el acceso de un usuario a una “zona” determinada de una aplicación.
Supongamos una aplicación con dos zonas, una zona de administración y una zona de acceso a usuarios. Para la primera zona (http://<aplicacion>/admin) se necesita que el usuario posea el rol “admin”, mientras que para la segunda(http://<aplicacion>/usuario) el rol “usuario”, nos centraremos en la primera, la segunda os la dejo como ejercicio…
También supongamos que tenemos un objeto “authenticator” que implementa los distintos métodos que requiere Seam respectos a la autenticación.
Normalmente, cuando un usuario entra en la aplicación sin haberse logado Seam lanza la excepción “NotLoggedInException” y posteriormente se redirige al usuario a la correspondiente pantalla para logarse. Este comportamiento se controla mediante el archivo “pages.xml”:
<exception class=”org.jboss.seam.security.NotLoggedInException“>
<redirect view-id=”/index.xhtml“>
<message>Usted debe estar logado para acceder a esta página.</message>
</redirect>
</exception>
Tras introducir los datos para el login (usuario y contraseña, certificado digital, etc.), el método “returnTo” del “autenticator” nos redirige a la zona adecuada, según observemos el rol que tiene asignado el usuario, esto lo podemos indicar en el fichero “components.xml”:
<event type=”org.jboss.seam.postAuthenticate“>
<action execute=”#{authenticator.returnTo}“/>
</event>
Una primera propuesta (adelanto que no es la definitiva), para controlar el acceso a la zona “admin” podríamos definir en el pages.xml lo siguiente:
<page view-id=”/admin/*” login-required=”true”>
<restrict>#{s:hasRole(’admin’)}</restrict>
</page>
<exception class=”org.jboss.seam.security.AuthorizationException“>
<end-conversation/>
<redirect view-id=”/index.xhtml“>
<message>Usted no posee los privilegios suficientes para acceder a esta zona.</message>
</redirect>
</exception>
Que en Castellano significa: para las peticiones a “/admin/*” comprueba que el usuario tiene el rol “admin”. Cuando no lo tenga se lanzará la correpondiente excepción “AuthorizationException” y se le redirigirá a “/index.xhtml” mostrándose el mensaje “Usted no posee los privilegios suficientes para acceder a esta zona.”
Quizás si no vamos más allá podamos pensar que tenemos todo controlado, pero ahora imaginemos la siguiente situación:
1) Un usuario entra en la aplicación, se va a la página de Login (por el NotLoggedInException capturado) y se loga correctamente, sin rol “admin” por lo que no debería tener acceso a /admin, de hecho el “return True” le redirige a la zona pública.
2) El usuario que se cree un piratilla escribe a fuego en la barra de direcciones del navegador “/admin” y le da al botón de Enter…
¿Qué pasará?
Lo esperado es que si el usuario pide “manualmente” en /admin tras logarse y obtener únicamente el rol “usuario”, la aplicación genera un AuthorizationException y se le redirigirá a /index.xhtml (pantalla inicial de bienvenida)…
Hazlo y comprobarás que no… el usuario tiene acceso a la zona de administración.
¿Y porqué? Pues una de las causas que he leído en el foro de jboss es que “esa excepción no se trata en la fase de render del JSF” y entonces no tiene el comportamiento que se indica en el pages.xml. Quizás no haya que buscar más porqués y proponer otra solución.
Una segunda propuesta, bastante atractiva aunque después propondré otra ligeramente más refinada, trata de que la aplicación capture correctamente la excepción AuthorizationException, nos redirija al index.xhtml y no suponga tener que redefinir arquitectura de ningún tipo… allá va:
Deberemos crear un nuevo “Controller” como este, especialmente dedicado a controlar el acceso a la zona de administración, quizás se podría usar cualquier controller ya existente, pero así queda más limpito nuestro código (vease “asignación de responsabilidades”):
@Name(”authorizationAdminController”)
@Scope(CONVERSATION)
@Restrict(”#{s:hasRole(’admin’)}”)
public class AuthorizationAdminController extends ControllerJsfApplication {
public void forceCheckAdminAuthorization(){}
}
Vemos que queda un controller práctiamente vacío.
Debido a @Restrict sólo podrán “invocar” a este controller los Identities(usuarios logados) con rol “admin”.
Ahora modificamos nuestro pages.xml de la siguiente forma:
Donde antes teníamos:
<page view-id=”/admin/*” login-required=”true”>
<restrict>#{s:hasRole(’admin’)}</restrict>
</page>
Ahora tenemos:
<page view-id=”/admin/*” login-required=”true” action=”#authorizationAdminController.forceCheckAdminAuthorization}“>
</page>
Con lo que al hacer una petición a “/admin” se ejecutará el action ( authorizationAdminController.forceCheckAdminAuthorization ), el cual no podrá estar accesible si no se posee el rol “admin”, debido a la anotación @Restrict del controller. Si el identity no posee este rol se lanza AuthorizationException, igual que pasaba antes sin usar el controller, sólo que ahora esta excepción si se captura correctamente y se realiza la redirección indicada en el pages.xml.
También deberemos mantener:
<exception class=”org.jboss.seam.security.AuthorizationException”>
<end-conversation/>
<redirect view-id=”/index.xhtml”>
<message>Usted no posee los privilegios suficientes para acceder a esta zona.</message>
</redirect>
</exception>
Con esta modificación conseguimos proteger correctamente la zona “/admin”, un usuario que intente logarse y posteriormente entrar en “/admin”, esta vez se le mostrará el index.xhtml con el mensaje: “Usted no posee los privilegios suficientes para acceder a esta zona.”
Una tercera solución es simplemente un refinamiento de la segunda, y llegamos a ella a través de la pregunta:
Si tenemos 50 zonas de protegidas, ¿tendremos que implementar 50 Controller semejantes a “AuthorizationAdminController” pero con un @Restrict distinto?
Pues no, la solución está en no anotar el Controller con @Restrict, sino anotar el propio método, así podríamos tener un único controller y N métodos para comprobar distintas autorizaciones:
@Name(”authorizationAdminController”)
@Scope(CONVERSATION)
public class AuthorizationAdminController extends ControllerJsfApplication {
@Restrict(”#{s:hasRole(’admin’)}”)
public void forceCheckAdminAuthorization(){}
@Restrict(”#{s:hasRole(’usuario’)}”)
public void forceCheckUsuarioAuthorization(){}
………
@Restrict(”#{s:hasRole(’XXXX’)}”)
public void forceCheckXXXXXXXAuthorization(){}
}
Indicando en el pages.xml el método “forceCheck X Authorization” que corresponde a cada zona las protegeremos convenientemente.
Pues con esto ha acabado lo que ha intentado ser una explicación.
Nunca olvidaré esta “primera vez” en que escribí en xnoccio, espero que hallais disfrutado tanto como yo.
Que la suerte os acompañe !!
Campeones del torneo Starcraft
Bueno señores, para los que habeís preguntado: este fin de semana se ha disputado la Tomares Party que incluía un torneo por parejas de Starcraft, en el cuál participábamos mi hermano y yo (aka Boromir - AxelStone).
Resultado: campeones invictos del campeonato, ganando todas las rondas por 2-0. Aunque no hemos estado a nuestro mejor nivel, aún queda algo de ese clan que fue subcampeón de España ;-).
Para los que pregunteís por el otro torneo, Street Fighter II, no lo gané. Me crucé en cuartos con el que acabó ganando el torneo, y perdí en un ajustadísimo 9-8 (se jugaba a 3 partidas, 3 rounds por partida, así que tuvimos que apurar hasta el final). Desafortunadamente la partida fue calificada como “la final anticipada”, ya que la final se ganó por un rotundo 3-0 en el mejor de 5 partidas. Enhorabuena a Kenji, que es un crack y me dejó fuera en cuartos.
Busca esto rápido
Encuentra lo que buscas de forma sencilla usando el buscador.
Categorías
Encuentra artículos a través de sus "tags"
Archivos mensuales
Encuentra artículos según el mes en el que fueron escritos.



