Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 
Índice general » Mundo Perl » Módulos » Control de acceso CGI::Session Responder al tema
Nuevo tema


Página 1 de 2  [ 27 mensajes ]  Ir a página 1, 2  Siguiente
 
Nota 2010-11-15 14:56 @664

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Control de acceso CGI::Session
Muy buenas,
estoy empezando con Perl, y estoy un poco perdida con el tema de CGI::Session. Tengo un programa Perl, muy sencillo ejecutado desde Apache, y la cuestión es que tengo que realizar un CGI que me ayude a controlar el acceso a este archivo, y la verdad es que no sé cómo empezar... Me gustaría que me dierais alguna indicación.

En sí consistiría en realizar un programa en el que haya que introducir un usuario y contraseña y se compruebe en una base de datos de MySQL si ese usuario existe para poder tener acceso al programa ya existente.

La verdad que para no tener ni idea de Perl creo que me he metido en un lío grande.

Gracias por la ayuda de antelación.


Nota 2010-11-15 18:13 @800
Avatar de Usuario
Administrador
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España
Mensajes: 10249
Re: Control de acceso CGI::Session
Bienvenida a los foros de Perl en Español, noa86.

CGI::Session tiene un módulo asociado, que es CGI::Session::Tutorial, donde vienen ejemplos (busca por la palabra login).

Si no te aclaras con los ejemplos y la documentación, deja otro mensaje por aquí e iremos paso a paso.

_________________
JF^D Perl programming


Nota 2010-11-16 03:59 @208

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Re: Control de acceso CGI::Session
Ya he mirado ese tutorial y otros más, pero no consigo aclararme cómo tengo que programarlo...

Tengo realizado esto:

Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
  1. #gestor.perl
  2.  
  3. #!/usr/bin/perl
  4.  
  5. print "content-type:text/html \n\n";
  6.  
  7. print "<html> <body>
  8. <FORM ACTION=hola.perl METHOD=POST>
  9. <center><p>Identificate</p>
  10. <p>Introduce usuario: <input type=text name=usuario size=10     maxlength=10></p>
  11. <p>Introduce contraseña: <input type=password name=pwd size=10 maxlength=10></p>
  12. <p><input type=submit name=entrar value=entrar></p></center>
  13. </FORM>
  14. </body></html>";


De esta manera todavía no realizo todavía ningún control de sesiones ni nada por el estilo. Cuando le doy a entrar voy directamente a hola.perl. Lo que quiero conseguir es que validando ese usuario y contraseña introducidos, que deberían de estar en una base de datos, tenga acceso o no a hola.perl.

¿Dónde tengo que crear la sesión? Lo que quiero es que se controle en qué "sesión" estamos... y sólo pueda acceder a "hola.perl" si alguien ha autorizado "en la misma sesión"...


Nota 2010-11-24 00:20 @055
Avatar de Usuario
Administrador
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España
Mensajes: 10249
Re: Control de acceso CGI::Session
Tienes toda la razón, noa86: la información disponible de CGI::Session es algo escasa.

Por Internet se pueden encontrar algunas referencias y ejemplos. Los que he encontrado:

* Creating and validating Sessions in Perl CGI

* Creating and validating Sessions in Perl CGI (el mismo autor en otro foro)

Pero el sitio más claro que he encontrado, aunque sorprendente, es el fichero CGI::Session::CookBook. Digo que es sorprendente porque este fichero no pertenece a la distribución actual de CGI::Session, sino a una anterior, la v3.95.

El caso es que es un poco más claro que el CGI::Session::Tutorial, pero al ser de una versión anterior, cambian unos pequeños detalles.

He preparado un pequeño ejemplo, que es un resumen del ejemplo mostrado por CGI::Session::CookBook. Realmente, la solución que hay que adoptar es la que indica en ese fichero, no el ejemplo que sigue a continuación.

Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #
  3. # Ejemplo de CGI::Session para login
  4. #
  5. use strict;
  6. use warnings;
  7. use diagnostics;
  8.  
  9. use CGI::Session;
  10. use CGI ':standard';
  11. use CGI::Carp qw'fatalsToBrowser warningsToBrowser';
  12.  
  13.  
  14. ## Creamos el objeto CGI
  15. my $cgi = CGI->new();  
  16.  
  17. ## Creamos el objeto CGI::Session
  18. my $session = CGI::Session->new("driver:File", $cgi, {'Directory'=>'/tmp/'})
  19.     or die CGI::Session->errstr;
  20.  
  21. ## Enviamos la cookie de sesión al usuario
  22. print $session->header;
  23.  
  24. # Aquí guardaremos el perfil del usuario
  25. my $perfil;
  26.  
  27. ## Inicialización
  28. if ( not $session->param('~registrado') ) {     # si el usuario no está registrado
  29.  
  30.     # vemos si se está registrando en este momento
  31.     if (my $nombre = $cgi->param('login_nombre')) {
  32.         my $passwd = $cgi->param('login_passwd');  
  33.  
  34.         # Vemos si es un usuario conocido por nosotros
  35.         # si lo es, obtenemos su perfil
  36.         if ($perfil = usuario_registrado($nombre, $passwd)) {
  37.            
  38.             # Guardamos el perfil asociado a la sesión
  39.             $session->param('perfil', $perfil);
  40.             $session->param('~registrado', 1);
  41.         }
  42.         else {  # Es un desconocido, le pedimos que rellene el registro otra vez
  43.             presenta_login('Usuario desconocido');
  44.             exit;
  45.         }
  46.     }
  47.     else {      # No está registrado ni se está registrando
  48.        presenta_login('Identifíquese');
  49.        exit;
  50.     }
  51. }
  52. else {          # es un usuario registrado (hay una sesión de él)
  53.     # recuperamos el perfil, desde la sesión
  54.     $perfil = $session->param('perfil');
  55. }
  56.  
  57.  
  58. # A partir de aquí, sabemos qué usuario es, y su perfil
  59. # Podemos presentarle las opciones propias de un usuario registrado
  60. my $nombre = $perfil->{nombre};         # otra forma de hacerlo sería recuperar esta información
  61. my $email  = $perfil->{email};          # desde la base de datos, ya que sabemos qué usuario es
  62.  
  63. if ($cgi->param('Desconectar')) {       # caso de que el usuario quiera desconectarse
  64.     $session->clear(['~registrado']);   # olvidamos que estaba registrado
  65.  
  66.     print       # despedida
  67.         start_html('Desconexión'),
  68.         h1('Desconexión'),
  69.         hr(),
  70.         p("Adios, $nombre"),
  71.         end_html()
  72.         ;
  73. }
  74. else {          # una página normal
  75.     print
  76.         start_html('Bienvenido'),
  77.         h1('Bienvenido'),
  78.         hr(),
  79.         p("Bienvenido $nombre ($email)"),
  80.         hr(),
  81.         p(a({-href=>'ficheros.html'},'Ver lista de ficheros')),
  82.         p(a({-href=>$cgi->url() . '?Desconectar=1'},'Desconectar')),
  83.         end_html()
  84.         ;
  85. }
  86.  
  87. # Perfil de un determinado usuario
  88. sub usuario_registrado {
  89.     my ($nombre, $passwd) = @_;
  90.  
  91.     # aquí consultaríamos una base de datos, por ejemplo
  92.     if ($nombre eq 'JF'  and  $passwd eq '2010') {
  93.         # si es un usuario en nuestra base de datos, recuperamos su perfil
  94.         return { nombre => $nombre, email => 'email@direccion.com' };
  95.     }
  96.      
  97.     return;
  98. }
  99.  
  100. # Presenta el formulario de entrada
  101. sub presenta_login {
  102.     my $titulo = shift;
  103.  
  104.     print
  105.         start_html,
  106.         h1('Registro de entrada: ' . $titulo),
  107.         start_form,
  108.         p('Nombre: '     . textfield('login_nombre')),
  109.         p('Contraseña: ' . password_field('login_passwd','',8,8)),
  110.         p(),
  111.         submit('Entrar'),
  112.         end_form,
  113.         end_html()
  114.         ;
  115. }
  116.  
  117. __END__

Este programa se puede llamar varias veces. Responderá de distinta manera según responda el usuario. Es un CGI, así que debemos respetar las reglas de programación de los CGI. Como buenos programadores de Perl, somos unos vagos, así que usaremos el módulo CGI y sus funciones de creación de código HTML. Esto tiene la ventaja de hacer el código mucho más corto y claro.

Al principio, de la línea 5 a la 7, ponemos las condiciones de funcionamiento y programación. Nada fuera de lo normal.

Cargamos los módulos necesarios, de la 9 a la 11. Según el CookBook, hay que cargar primero CGI::Session, antes que el módulo CGI. El módulo CGI::Carp nos servirá para ver los errores de programación en la propia pantalla del navegador. Así no tendremos que mirar los ficheros de registro de actividad del servidor web, para buscar esos errores. Cuando el programa funcione bien lo podremos quitar.

El programa comienza en la línea 15, donde crearemos un objeto CGI, que representará la llamada del usuario a este programa.

Después creamos el objeto CGI::Session, en la línea 19. Indicaremos (en este ejemplo), que queremos guardar los datos de la sesión en el directorio /tmp, en forma de ficheros, y que recoja los datos enviados por el usuario a través del objeto $cgi (o dicho de otra manera, $session usará el objeto $cgi para aquellas funciones que en otras ocasiones haríamos solo con el objeto $cgi. Ejemplo: la función header()).

En la línea 22 enviamos al navegador del usuario la cabecera HTTP de respuesta, en la que incluiremos la galleta (cookie) de sesión. De esta manera, estamos ya creando una sesión, pero solo para tener una primera comunicación con el usuario. No guardamos nada ni sabemos qué usuario es. Es solo que creamos un fichero, en el lado del servidor, donde guardaremos los datos de la futura posible sesión, y una galleta en el lado del cliente.

En la línea 25 declaramos una variable, $perfil, donde guardaremos el perfil del usuario, en caso de que sepamos quién es.

Comenzamos con las pruebas en la línea 28. Ahí miraremos a ver si el el usuario se ha registrado en la sesión correctamente. Para ello, usaremos el objeto $session. El método new() que hemos usado en la línea 18 crea una nueva sesión, en caso de que el usuario se conecte por primera vez, o recupera la sesión que el usuario guarda en su navegador, si no es la primera vez que se conecta. De alguna forma, con estas dos líneas y la 22, tenemos resuelto el tema de crear y recuperar las cookies de sesión en el lado del cliente.

Para saber si el usuario está registrado en una sesión, la línea 28 intenta recuperar el valor del parámetro '~registrado'. El carácter '~' no significa nada para CGI::Session. Solo tiene significado para nosotros, los programadores: es un recuerdo de que ese parámetro no es uno de los "normales", como por ejemplo el nombre, la contraseña, o el correo electrónico. Éste es una bandera, con valores 0 o 1, indicando si el usuario de esta sesión se ha registrado correctamente.

En caso de que no esté registrado, saltamos a la línea 31, donde comprobaremos si el usuario está respondiendo al formulario de entrada, con su nombre y contraseña. Solo tenemos que leer los parámetros pasados por el formulario, que el objeto $cgi ha recogido.

Teniendo un nombre y una contraseña, pasamos a la línea 36, donde comprobaremos si ese usuario está en nuestra base de datos de usuarios registrados. Y si es así, recuperaremos su perfil.

El perfil es el conjunto de datos del usuario que almacenaremos dentro de la sesión. Pueden ser datos que, aunque podamos recuperar de la base de datos de usuarios, queremos mantener fuera mientras la sesión se mantiene viva. Podría ser información del estado o de la página que está visitando, por ejemplo. Información que no es necesario guardar en la base de datos y con guardarla en el fichero de sesión, nos vale. En este ejemplo, el perfil consistirá en una referencia a un hash, con dos claves: nombre y correo electrónico.

Si hemos conseguido recuperar un perfil de usuario, estamos en la línea 39. Allí, guardaremos el perfil del usuario en el fichero de sesión. Y en la línea siguiente, marcamos la bandera de '~registrado' a 1. La próxima vez que el usuario ejecute este u otro programa parecido, sabrán que la sesión pertenece a un usuario identificado (sabemos quién es) y registrado (coincide su nombre y contraseña con la que tenemos en nuestra base de datos).

En caso de que no encontremos a ese usuario en nuestra base de datos, llegamos a la línea 43, donde le presentaremos el formulario de registro de entrada, y terminamos.

Si el usuario no estaba registrado y tampoco nos estaba enviando sus credenciales, llegamos a la línea 48, donde hacemos lo mismo de antes: formulario de registro y terminamos el programa.

Pero si es un usuario que ya estaba registrado, llegamos a la línea 54, donde recuperamos el perfil del usuario.

Lo que hagamos a partir de esa línea ya depende de nosotros, de lo que queramos enseñarle. En este ejemplo, solo vamos a sacar sus datos, y la opción de 'desconectar' de la sesión.

En las líneas 60 y 61 recuperamos información de su perfil. Y como sabemos quién es, podríamos luego conectarnos a la base de datos y recuperar más información del usuario.

En la línea 63 comprobamos si, el usuario, lo que quiere es desconectar. Si es así, en la línea 64 borramos el parámetro '~registrado' (el usuario no quiere seguir registrado en esta sesión). Y a continuación (líneas 66 y siguientes) le presentamos un adiós. Para ello, usaremos las funciones de generado HTML de CGI, para crear una página HTML sencilla (todas las del ejemplo serán así).

Pero si el usuario no quiere desconectar, llegaremos a la línea 75, donde le presentaremos una página de bienvenida, sus datos, y el enlace de desconexión.

Nada más. Este ejemplo no hace nada más de cara al usuario, pero de la misma manera que hemos creado la bifurcación para la desconexión podríamos crear otras para otras tareas. Y... en ese momento nos daremos cuenta de que quizás sea mejor ir a aprender CGI::Application, que es mucho más completo que todo esto.

Siguen las subrutinas del programa.

En la línea 88 y siguientes, comprobaríamos si el usuario está en nuestra base de datos, y si es así, devolvemos su perfil. Aquí lo he simplificado a una cuestión muy sencilla (un if()).

Y las líneas 101 y siguientes presentan el formulario de registro de entrada. Nada fuera de lo normal, salvo que recibe un $titulo como parámetro, para informar al usuario de porqué le vuelve a salir el formulario (la línea 43 indica que es un usuario desconocido o ha fallado la contraseña, y la línea 48, que es la primera vez que entra).

Y ya está. Pero recuerda que esta es una de las muchas formas de usar este módulo. Y tampoco es la más óptima. Solo es una demostración. Lo más profesional es usar el módulo HTML::Template para la generación de las páginas, junto con la opción associate y el objeto de sesión. De todo esto sí se comenta en el Tutorial.

Y tampoco es bueno que un solo programa haga todo. Quizás lo mejor sería hacer uno que se encargase de la parte de login (registro) y luego otros, para cada tarea. En cada uno de ellos pondremos las mismas líneas: recuperar la sesión anterior o crear una nueva. Si el usuario no está registrado, pues lo desviamos a la de registro. De esto hay un par de ejemplos en los primeros enlaces de este mensaje.

El siguiente nivel de perfeccionamiento, es ir directamente a CGI::Application, que es mucho más completo, extenso (y naturalmente, complejo), pero permite crear aplicaciones web más completas (y complejas), pero sin llegar a la solución completa del entorno de trabajo Catalyst.

Pero aprender CGI::Session está bien, ya que luego nos encontraremos con CGI::Application::Plugin::Session.

_________________
JF^D Perl programming


Nota 2010-11-24 05:15 @260

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Re: Control de acceso CGI::Session
Muchas gracias por la ayuda, me ha ayudado de mucho para entender el funcionamiento. Te lo has currado.


Nota 2010-11-24 12:01 @542

Perlero Nuevo
Registrado: 2008-01-08 09:29 @437
Ubicación: Santiago, Chile
Mensajes: 28
Re: Control de acceso CGI::Session
:lol: :lol: :lol: :lol:

Jejejeje, disculpa, pero al leer
Citar:
Como buenos programadores de Perl, somos unos vagos
no había encontrado una definición tan buena. Es que lo dicho es una gran realidad.

¡¡¡Que viva Perl, que viva Cut & Paste!!!


Nota 2010-11-24 12:15 @552
Avatar de Usuario
Administrador
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España
Mensajes: 10249
Re: Control de acceso CGI::Session
No, no tiene que ver con el Corta y Pega, que tantos problemas ha generado y sigue generando en la informática actual.

En lugar de la palabra "vago" debería haber escrito la correcta: "perezoso". Es una de las tres virtudes del programador, según Larry Wall.

Ese concepto hace referencia a la reutilización del código, pero se refiere al uso de módulos y paquetes ya construidos antes, bien sea por otros o por nosotros mismos (no reinventar la rueda). Vamos, usar CPAN siempre que sea posible.

_________________
JF^D Perl programming


Nota 2010-11-24 12:29 @562

Perlero Nuevo
Registrado: 2008-01-08 09:29 @437
Ubicación: Santiago, Chile
Mensajes: 28
Re: Control de acceso CGI::Session
A lo mismo me refería.

Con el "cortar y pegar" o, más bien "copiar y pegar", usar rutinas que hemos visto que funcionan y no estar haciendo 10 veces lo mismo :D


Nota 2011-03-03 12:30 @562

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Re: Control de acceso CGI::Session
¿Alguna web donde haya algún ejemplo de CGI::Session y CGI::Session:Auth, etc, todo lo que conlleva CGI::Session? Estoy buscando en Google pero no encuentro...

Si sabe alguien de alguna página con algún ejemplo. Gracias.


Nota 2011-03-05 16:54 @746
Avatar de Usuario
Vive para Perl en Español
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia
Mensajes: 551
Re: Control de acceso CGI::Session
Bueno, yo uso mucho el CGI::Session. Es mejor que preguntes lo que quieres hacer. No creo que exista una web con ejemplos de eso. Es que es tan fácil que con lo que está en el CPAN es suficiente.

Mejor si quieres te puedo ayudar si me agregas o preguntas en el foro.

_________________
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org


Nota 2011-03-29 11:14 @509

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Re: Control de acceso CGI::Session
He modificado cosas del código que me aportó explorer y me funciona perfectamente, pero ahora quiero poner tiempo de expiración. Me expira poniendo $session->expire('+5m'), por ejemplo, pero no me sale ningún mensaje. Mirando tutoriales he realizado esto.

Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
  1. ## Creamos el objeto CGI
  2. my $cgi = CGI->new();  
  3.  
  4. ## Creamos el objeto CGI::Session
  5. $dbh = DBI->connect("DBI:mysql:$database:localhost",$user,$passwd) or die("Can't connect to db: ",$dbh->errstr);
  6. my $session = CGI::Session->new("driver:MySQL", $cgi, {Handle=>$dbh})    or die CGI::Session->errstr;
  7.  
  8. ## Enviamos la cookie de sesión al usuario
  9. print $session->header;
  10.  
  11.  
  12. my $perfil;
  13.  
  14.  
  15. ## Inicialización
  16. if ( not $session->param('~registrado') ) {     # si el usuario no está registrado
  17.    
  18.    $session = CGI::Session->load("driver:MySQL", $cgi, {Handle=>$dbh}) or die CGI::Session->errstr();
  19.  
  20.         if ( $session->is_expired){
  21.            print $session->header(),
  22.                 $cgi->start_html(),
  23.                 $cgi->p("Your session timed out! Refresh the screen to start new session!"),
  24.                 $cgi->end_html();
  25.                 exit(0);
  26.    }
  27.  
  28.         if ($session->is_empty){
  29.                 $session = $session->new("driver:MySQL", $cgi, {Handle=>$dbh}) or die $session->errstr;
  30.                 $session -> expire('+2m');
  31.         }


No sé si estoy poniendo correctamente las líneas de load() y new() o qué tengo mal pero cuando me expira el tiempo, me vuelve a identificación de usuario pero no me muestra aviso de que ha expirado el tiempo...


Gracias de antemano...


Nota 2011-03-29 11:37 @526
Avatar de Usuario
Administrador
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España
Mensajes: 10249
Re: Control de acceso CGI::Session
Viendo el código, si no se ejecuta $session->is_expired, cuando sabemos que la sesión ha expirado, es quizás porque en la línea 16 sí que ha encontrado el parámetro '~registrado'.

Quizás debas cambiar el orden... Deberías, primero, comprobar si la sesión ha expirado o no. Y luego, si no ha expirado, preguntar si está registrado o no.

Editado: veo en el CGI::Session, en la explicación de expire(), que también se puede asociar un tiempo de expiración para un determinado argumento, así que, también, podrías escribir $session->expire('~registrado', '+10m'), y de esa manera, cuando pasen 10 minutos, el parámetro '~registrado' es eliminado de la $session, y la línea 16 funcionará.

_________________
JF^D Perl programming


Nota 2011-03-29 12:02 @543

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Re: Control de acceso CGI::Session
Lo he puesto
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
  1. ## Inicialización
  2. $session = CGI::Session->load("driver:MySQL", $cgi, {Handle=>$dbh}) or die CGI::Session->errstr();
  3. if ( $session->is_expired){
  4.            print $session->header(),
  5.                 $cgi->start_html(),
  6.                 $cgi->p("Your session timed out! Refresh the screen to start new session!"),
  7.                 $cgi->end_html();
  8.                 exit(0);
  9.    }
  10.  else{
  11. if ( not $session->param('~registrado') ) {     # si el usuario no está registrado
  12.  
  13.         if ($session->is_empty){
  14.                 $session = $session->new("driver:MySQL", $cgi, {Handle=>$dbh}) or die $session->errstr;
  15.                 $session -> expire('+2m');
  16.         }
  17. }

pero tampoco me funciona. Sí que me expira, pero no me da el mensaje de is_expired().

¿En el load() y en el new() tengo que poner "driver:MySQL", $cgi, {Handle=>$dbh}, no? Ya que las sesiones se me guardan en la base de datos...


Nota 2011-03-29 12:39 @569
Avatar de Usuario
Administrador
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España
Mensajes: 10249
Re: Control de acceso CGI::Session
$dbh es la variable donde has guardado la conexión con la base de datos, así que unas líneas antes has debido abrir esa conexión (línea 5). Y sí, debes cargar la sesión con load().

El problema que veo, en el primero código que has publicado, es que has creado la sesión en la línea 6, envías el header() en la línea 9, y luego vienen las líneas que preguntan si la sesión ha expirado. Ahí sí que hay un error: la sesión no está expirada porque acabas de crearla en la línea 6.

Y otro detalle... envías dos veces los header(): en la línea 9 y en la línea 21.

Entonces... para mí sobran esas dos primeras líneas, la 6 y la 9.

Recuerda que puedes usar la función dump() para ver el contenido de la sesión, pero fíjate bien dónde colocas esa llamada: debe estar después de la ejecución de header(). Lo normal es ponerlo justo antes de enviar el end_html().

Estoy buscando a ver si veo un ejemplo completo...

_________________
JF^D Perl programming


Nota 2011-03-29 13:06 @588

Perlero Nuevo
Registrado: 2010-11-15 14:43 @655
Mensajes: 93
Re: Control de acceso CGI::Session
Pero si elimino la línea 9 no me carga la página... me da error


Responder al tema  [ 27 mensajes ]  Ir a página 1, 2  Siguiente

Reglas del Foro
No puedes abrir nuevos temas en este Foro
No puedes responder a temas en este Foro
No puedes editar tus mensajes en este Foro
No puedes borrar tus mensajes en este Foro
No puedes enviar adjuntos en este Foro

Publicidad

Socializa

Síguenos por Twitter

Suscríbete GRATUITAMENTE al Boletín de Perl en Español

Saltar a:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Traducción al español por Huan Manwë para phpbb-es.com
phpBB SEO