tag:blogger.com,1999:blog-43023955411756214392024-03-16T12:53:17.866-06:00Paraiso del desarrolladorShadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-4302395541175621439.post-24141060716892642032022-04-10T14:24:00.005-05:002022-04-10T14:26:45.847-05:00Generar de Fichas Wisp Gratis<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"></blockquote><div style="text-align: justify;"><span style="font-family: arial;">Debido a la necesidad de muchos colegas que me han solicitado configuraciones y procedimiento para realizar fichas y así poder vender servicio de internet a sus clientes me di a la tarea de realizar un pequeño pero funcional programa de escritorio, este programa o aplicación esta desarrollado en java por lo cual funciona en cualquier sistema operativo con la única condición de tener instalada la maquina virtual de java (hay muchos tutoriales sobre como instalar java en windows, Linux, mac, etc.. etc..). </span></div><div style="text-align: justify;"><span style="font-family: arial;"><br /></span></div><div style="text-align: justify;"><span style="font-family: arial;"><br /></span></div><div style="text-align: justify;"><span style="font-family: arial;">El programa o aplicación en cuestión es un archivo ejecutable (por la maquina virtual de java) con la extensión .jar como se muestra a continuación:
</span></div><div><span style="font-family: arial;"><br /></span></div><div><span style="font-family: arial;"><br /></span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1jCzB61INkgqzDiYM1zn_fXs3uN9RYDL3W9voRnZ5CsmkDlTI1hM4j8pysaxJwB-YTphGlIPzQAltJOf0779NHR0HBe54L4QyuoTf-nYZHBkhLVuCKVr27VwMsqkX1ujx78UTUg8mYjAozFivB8D4Ep_775G8vbkZA-OAqL0BMsFD5htjPeRP5kPKYA/s492/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2012.56.49.png" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: arial;"><img border="0" data-original-height="232" data-original-width="492" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1jCzB61INkgqzDiYM1zn_fXs3uN9RYDL3W9voRnZ5CsmkDlTI1hM4j8pysaxJwB-YTphGlIPzQAltJOf0779NHR0HBe54L4QyuoTf-nYZHBkhLVuCKVr27VwMsqkX1ujx78UTUg8mYjAozFivB8D4Ep_775G8vbkZA-OAqL0BMsFD5htjPeRP5kPKYA/s320/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2012.56.49.png" width="320" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: arial;"><br /></span></div><span style="font-family: arial;"><br /></span><div style="text-align: justify;"><span style="font-family: arial;">Al ejecutar con doble click se abrirá la pantalla principal del sistema que se ve como se muestra en la siguiente imagen:</span></div><div><span style="font-family: arial;"><br /></span></div><div><span style="font-family: arial;"><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxiI5D-Ez2zKXvmiZTvVqOHteFTZUehsu8X36hMJPBAQj2T7MVndU8oIb3OGEDyT2111Ahdm4mQZ2UmvuVpgDBi9uLUbKhUQvqQZU4OhUT3RX3hzsr3MLxRRf0aRtTa16ucLi4zBoJBuNfrATR0nkRlHczRvYhDIRIqd1FFXar4QMUiaEWh4gPSVavEw/s2390/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2012.43.21.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1576" data-original-width="2390" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxiI5D-Ez2zKXvmiZTvVqOHteFTZUehsu8X36hMJPBAQj2T7MVndU8oIb3OGEDyT2111Ahdm4mQZ2UmvuVpgDBi9uLUbKhUQvqQZU4OhUT3RX3hzsr3MLxRRf0aRtTa16ucLi4zBoJBuNfrATR0nkRlHczRvYhDIRIqd1FFXar4QMUiaEWh4gPSVavEw/w400-h264/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2012.43.21.png" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div></div><div><span><a name='more'></a></span><div class="separator" style="clear: both; text-align: justify;"><br /></div></div><div><br /><span style="font-family: arial;">Lo que debemos hacer es agregar la ip del mikrotik al cual te quieres conectar para generar las fichas, después el usuario y el password y si los datos son correctos el sistema se conectara al mikrotik (vía api) mostrando los siguientes datos:</span></div><div><span style="font-family: arial;"><br /></span></div><div><span style="font-family: arial;"><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYIFClh6g7I6B3nkiX020bpNtB8xqWV7m_Kwq-m1eOFgAqlQezM4BbIFspP4-y-gGJ2VzLVuph3McQN8M2rGlWFP4SL0UXgGP8oqr03Yp-h1ajyAiaZegSB4X98qH1-3q5Ym9WtkbL3lhJWocq9sGXZS6XCHxZ9ku--7LcR-a96MbSl4VpBYoGhn1nGw/s2348/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2013.41.35.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1572" data-original-width="2348" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYIFClh6g7I6B3nkiX020bpNtB8xqWV7m_Kwq-m1eOFgAqlQezM4BbIFspP4-y-gGJ2VzLVuph3McQN8M2rGlWFP4SL0UXgGP8oqr03Yp-h1ajyAiaZegSB4X98qH1-3q5Ym9WtkbL3lhJWocq9sGXZS6XCHxZ9ku--7LcR-a96MbSl4VpBYoGhn1nGw/w400-h268/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2013.41.35.png" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">Como podemos notar, en el panel verde muestra información básica sobre nuestro mikrotik al cual estamos conectados, en el panel azul aparecen las diversas opciones que tenemos disponibles para generar las fichas.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div></div><div><div class="separator" style="clear: both; text-align: justify;"><b>* Normal y tiempo:</b> se refiere a que genera la ficha con usuario y contraseña y la duración de la misma esta definida por un limite de tiempo ya sea en minutos, horas o días.</div></div><div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><b>* Normal y megas:</b> se creara la ficha con usuario y contraseña pero la duración de la misma estará determinada por la cantidad de megas asignada el parámetro Limite de trafico que será una cantidad en megas ojo cuentan megas de bajada y megas de subida.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><b>* PIN y tiempo :</b> la ficha solo pide un pin de n dígitos para loguearse y la duración esta determinada por el limite de tiempo.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><b>*PIN y megas:</b> la ficha pide un pin de n dígitos y la duración esta determinada por la cantidad de megas definida.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">Los demás paramentros se entienden solos a excepción de perfil, cabe aclarar que <b><span style="color: #e06666;">la aplicación no configura el mikrotik para hacer uso del Hotspot,</span></b> esta configuración debes crearla por tu cuenta y crear tus perfiles, ojo e<b><i>l perfil no define la duración de la ficha, sino mas bien la velocidad de navegación y el tipo de tiempo en el caso de que se quiera hacer tiempo corrido o tiempo pausado</i></b> pero eso es otro tema, esta aplicación cargará los perfiles definidos en tu mikrotik a la hora de hacer la configuración de tu Hotspot, sino hiciste perfiles esta el perfil por default, y también agregue la opción de crear un perfil desde la aplicación muy básico, solo define el nombre del perfil y la velocidad a la que van a navegar tus fichas.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiIWhUoBaiTKIyZbr3Q1NgoMbWi718iCtocGL1cPv9ynz6xOtqO8xE2e_pVJFi9hnKjCL-BnzTcJczKID4G-jK7Yq1jxiYPcrX1krUTwghVAamD-_0RAgDDBjbE_Kzg4ZdejljpoeY3Rp_OTT5pAK13aKhtI_QatGMVQiGhx_n5p7IAyH2El5k2KgmNA/s1322/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2014.04.05.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1194" data-original-width="1322" height="361" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiIWhUoBaiTKIyZbr3Q1NgoMbWi718iCtocGL1cPv9ynz6xOtqO8xE2e_pVJFi9hnKjCL-BnzTcJczKID4G-jK7Yq1jxiYPcrX1krUTwghVAamD-_0RAgDDBjbE_Kzg4ZdejljpoeY3Rp_OTT5pAK13aKhtI_QatGMVQiGhx_n5p7IAyH2El5k2KgmNA/w400-h361/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2014.04.05.png" width="400" /></a></div><br /><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">Finalmente una vez que hayas configurado los parámetros de la ficha de acuerdo a tus necesidades pulsan al botón generar fichas lo cual hace 2 procesos:</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">El primer proceso crea las fichas directo al mikrotik y el segundo proceso llena el recuadro de abajo con los datos cargados al mikrotik para posteriormente pulsar en el botón imprimir lo que generara un PDF con la plantilla por defecto de las fichas.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhohaEe60q1K83noqkLO7S7fUUGcbEmZwPGpFrjyDhybTUJPSfN1LPaMFVjUlcHUpiztegHdfoBV5hbJUkNXUch-ZLcVSa1TPgvteIRjrWYAvHRWbrgx1ZKlirt-PwPwaOLDRCvWMty2bj6HnhOCy-u_kekLoKqNWJ8luGbOCLUiSOpex71rZeUphG6YQ/s2012/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2014.05.48.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1388" data-original-width="2012" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhohaEe60q1K83noqkLO7S7fUUGcbEmZwPGpFrjyDhybTUJPSfN1LPaMFVjUlcHUpiztegHdfoBV5hbJUkNXUch-ZLcVSa1TPgvteIRjrWYAvHRWbrgx1ZKlirt-PwPwaOLDRCvWMty2bj6HnhOCy-u_kekLoKqNWJ8luGbOCLUiSOpex71rZeUphG6YQ/w400-h276/Captura%20de%20Pantalla%202022-04-10%20a%20la(s)%2014.05.48.png" width="400" /></a></div><br /><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">Espero les sea de utilidad el programa no tiene ningún costo si alguien desea hacer una donación o un soporte para que le explique mas a detalle el funcionamiento contácteme :D</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><span style="font-size: large;"><br /><span style="font-family: arial;"><a href="https://drive.google.com/file/d/1cNqSpv1YZAiSWYKjXoaIfWdx_gF49iE9/view?usp=sharing" target="_blank">Descargar</a></span></span></div><div><br /></div><div><br /></div>Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com1tag:blogger.com,1999:blog-4302395541175621439.post-26671651042194999822018-10-01T20:42:00.000-05:002018-10-03T12:39:37.495-05:00SadWisp v2.0 Instalando Versión Beta<br />
Ya esta disponible la beta del sistema SadWisp v2.0 a continuación explico como instalarlo para poder realizar las pruebas correspondientes, es importante recordar que se requiere de ambientación en el pc donde se vaya a instalar (<a href="http://paraisodeldesarrollador.blogspot.com/2018/09/sadwisp-v20-requisitos-de-instalacion.html" target="_blank">Requisitos para instalar SadWisp</a>) en la imagen siguiente se muestran las características disponibles y también las características pendientes así como las restricciones de la versión de prueba:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-Kc5TjczNRGI/W7LCaE-PmEI/AAAAAAAABH0/ZRe2E3_eqBcCtQnzQPRad3eztLqLgxHWgCLcBGAs/s1600/SadWispInicio.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="760" data-original-width="1600" height="190" src="https://2.bp.blogspot.com/-Kc5TjczNRGI/W7LCaE-PmEI/AAAAAAAABH0/ZRe2E3_eqBcCtQnzQPRad3eztLqLgxHWgCLcBGAs/s400/SadWispInicio.PNG" width="400" /></a></div>
<br />
<br />
<a name='more'></a><br />
<br />
<span style="font-size: large;"><i>Pasos para la instalación.</i></span><br />
<br />
1.- Descargar el archivo empaquetado pueden hacerlo desde este <a href="https://mega.nz/#!gio33QxI!KxUEkevxOkwITA9H3Eb4C0yze4Bj67VPTnARPD6lFMk" target="_blank">link</a><br />
<br />
2.- Como ya tenemos instalado el motor de base de datos que en nuestro caso es Postgress, abrimos la herramienta de administración llamada pgAdmin, dicha herramienta luce mas o menos así:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-NxLT9iK1H_k/W7LD_JuL_cI/AAAAAAAABII/QLG03BqTFjQr1Gfj60zorZhf_j2c3O1LQCEwYBhgL/s1600/postgres.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="374" data-original-width="838" height="177" src="https://4.bp.blogspot.com/-NxLT9iK1H_k/W7LD_JuL_cI/AAAAAAAABII/QLG03BqTFjQr1Gfj60zorZhf_j2c3O1LQCEwYBhgL/s400/postgres.PNG" width="400" /></a></div>
<br />
<br />
3.- Seleccionamos nuestro servidor y damos doble clic con lo cual nos abrirá una ventana donde nos pedirá el password que pusimos al inicio, para este ejemplo es "root" si el password es correcto se conectara al servidor y mostrará las bases de datos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-o8V5VtnICCw/W7LEoVoXHaI/AAAAAAAABIY/bUAns3Rxi9MW5FxRNSh7RilqkM_72l53QCLcBGAs/s1600/postgresw.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="608" data-original-width="969" height="250" src="https://3.bp.blogspot.com/-o8V5VtnICCw/W7LEoVoXHaI/AAAAAAAABIY/bUAns3Rxi9MW5FxRNSh7RilqkM_72l53QCLcBGAs/s400/postgresw.PNG" width="400" /></a></div>
<br />
4.- Sobre el apartado de "Databases" dar clic derecho crear nueva base de datos<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-MBmcm-eeCN4/W7LFDD5s36I/AAAAAAAABIg/3dl9Q8JQIzIwmjd46toigL1f0Y25Cb9mQCLcBGAs/s1600/postgres3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="199" data-original-width="805" height="98" src="https://2.bp.blogspot.com/-MBmcm-eeCN4/W7LFDD5s36I/AAAAAAAABIg/3dl9Q8JQIzIwmjd46toigL1f0Y25Cb9mQCLcBGAs/s400/postgres3.PNG" width="400" /></a></div>
<br />
5.-En la ventana que aparece únicamente escribir el nombre de la base de datos para el ejemplo "sadwispDb" como se muestra en la imagen y pulsar "Save" <b>un dato importante es que el usuario con el que va configurado el sistema es "postgres" y el password es "root"</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-7ikTiY5KmIg/W7LFcSGBIMI/AAAAAAAABIs/vdb2xCkGDHUf-AP_xhuCpBu7zq46tPvIwCLcBGAs/s1600/postgres4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="860" data-original-width="798" height="400" src="https://1.bp.blogspot.com/-7ikTiY5KmIg/W7LFcSGBIMI/AAAAAAAABIs/vdb2xCkGDHUf-AP_xhuCpBu7zq46tPvIwCLcBGAs/s400/postgres4.PNG" width="370" /></a></div>
<br />
<br />
Con eso es suficiente en cuanto a lo que se requiere para la base de datos.<br />
<br />
6.- Nos vamos a la carpeta de instalación de tomcat dentro del directorio bin buscamos el archivo startup.bat<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-MoE2_9g8bqM/W7LGQdZudhI/AAAAAAAABI4/L_kHQCpoLa44sh0QmHDanEKJtOOfWMe5QCLcBGAs/s1600/tomcat.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="819" data-original-width="1299" height="251" src="https://4.bp.blogspot.com/-MoE2_9g8bqM/W7LGQdZudhI/AAAAAAAABI4/L_kHQCpoLa44sh0QmHDanEKJtOOfWMe5QCLcBGAs/s400/tomcat.PNG" width="400" /></a></div>
<br />
7.- Le damos doble clic y nos abrirá una ventana de comandos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-p0W7qmNmcNY/W7LHEjR0F5I/AAAAAAAABJU/PZJac2xEaIAXinkuHs7KcC9H_EdiZRpggCLcBGAs/s1600/tomcat2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="397" data-original-width="1402" height="112" src="https://3.bp.blogspot.com/-p0W7qmNmcNY/W7LHEjR0F5I/AAAAAAAABJU/PZJac2xEaIAXinkuHs7KcC9H_EdiZRpggCLcBGAs/s400/tomcat2.PNG" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
8.-Cuando nos aparezca la leyenda "Server startup in ..." vamos al navegador y escribimos "http://localhost:8080" veremos la siguiente imagen indicándonos que nuestro contenedor de aplicaciones esta listo y funcionando<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-al-ofcB3gQQ/W7LHjcGFz-I/AAAAAAAABJg/iSGIFfC-9boffDjn_teVChSAkKH-i4k3ACLcBGAs/s1600/tomcat3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="538" data-original-width="1550" height="138" src="https://2.bp.blogspot.com/-al-ofcB3gQQ/W7LHjcGFz-I/AAAAAAAABJg/iSGIFfC-9boffDjn_teVChSAkKH-i4k3ACLcBGAs/s400/tomcat3.PNG" width="400" /></a></div>
<br />
<br />
9.- Para instalar el sistema únicamente tenemos que copiar el empaquetado descargado en el paso 1 a la carpeta webapps que esta dentro del directorio de instalación de tomcat la carpeta con el mismo nombre la crea el servidor en automático.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-G_xs2klnXGc/W7LIA648jEI/AAAAAAAABJo/5kNtzC4YRGMDoRVGWQpkBZexP1tI0GzzACLcBGAs/s1600/tomcat4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="391" data-original-width="1000" height="156" src="https://1.bp.blogspot.com/-G_xs2klnXGc/W7LIA648jEI/AAAAAAAABJo/5kNtzC4YRGMDoRVGWQpkBZexP1tI0GzzACLcBGAs/s400/tomcat4.PNG" width="400" /></a></div>
<br />
10.- El servidor iniciara la instalación del sistema y en la ventana de comandos empezara a pintar varias lineas, después de 3 minutos dependiendo el procesador que tengan mostrará la siguiente leyenda "sadwisp.war has finished in ..." esto indica que el sistema se ha instalado si sale algun error la unica causa es que el usuario y password de la base de datos no es "postgres" ni "root".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-jyfyCG0FPI0/W7LLBN48FXI/AAAAAAAABKA/kveRVwIP9eohLTRvJPEvqp4o_OfHqr0gACLcBGAs/s1600/tomcat5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="591" data-original-width="1503" height="156" src="https://2.bp.blogspot.com/-jyfyCG0FPI0/W7LLBN48FXI/AAAAAAAABKA/kveRVwIP9eohLTRvJPEvqp4o_OfHqr0gACLcBGAs/s400/tomcat5.PNG" width="400" /></a></div>
<br />
11.- Cuando se termina la instalación vamos al navegador y ponemos la siguiente url "http://localhost:8080/sadwisp/" con esto ya deberemos ver el sistema en linea.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-XLy1a6UiS_c/W7LL5J5Vc8I/AAAAAAAABKM/wNM9liGARogf9MFpcCEOUDxxzUgGQWmlgCLcBGAs/s1600/sadwispOnline.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="1391" height="147" src="https://2.bp.blogspot.com/-XLy1a6UiS_c/W7LL5J5Vc8I/AAAAAAAABKM/wNM9liGARogf9MFpcCEOUDxxzUgGQWmlgCLcBGAs/s400/sadwispOnline.PNG" width="400" /></a></div>
<br />
Espero que los que de verdad estén interesados sigan los pasos para realizar la instalación y si necesitan ayuda no duden en comentar aquí o en el grupo de FB.<br />
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-69293266548523001012018-09-29T22:25:00.000-05:002018-10-03T12:34:19.429-05:00SadWisp v2.0 Requisitos de Instalación<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-Iinbg8ASzgo/W7BB6ux_5JI/AAAAAAAABHc/SyZ29oVYADwEZHD7JuSydJcMRUrpW-fIACLcBGAs/s1600/SadWisp.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="750" data-original-width="1600" height="187" src="https://2.bp.blogspot.com/-Iinbg8ASzgo/W7BB6ux_5JI/AAAAAAAABHc/SyZ29oVYADwEZHD7JuSydJcMRUrpW-fIACLcBGAs/s400/SadWisp.PNG" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Como muchos de ustedes ya saben, me encuentro realizando la segunda versión del sistema para administración de clientes #SadWisp de la cual pondré a disposición una versión de prueba, debido a que muchos usuarios quieren testearla y apoyar con su experiencia y sus puntos de vista, para ello me dí a la tarea de realizar este post explicando los requisitos y el procedimiento para realizar la instalación del sistema SadWisp.</div>
<div style="text-align: justify;">
<br /></div>
<span style="font-size: large;"><i>Requisitos minimos de Hardware:</i></span><br />
<br />
* Computadora con procesador dual core o superior<br />
* 2GB en ram<br />
* 1GB en disco duro<br />
<br />
<span style="font-size: large;"><i>Programas a Instalar:</i></span><br />
<br />
* JDK Java (Compilador de Java ) Descarga <a href="https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html" target="_blank">aquí</a> versión 8<br />
* Postgres (Base de Datos) Descarga <a href="https://www.enterprisedb.com/download-postgresql-binaries" target="_blank">aquí</a> bajen versión 9.6<br />
* Tomcat 8 (Contenedor de Aplicaciones) Descarga <a href="https://tomcat.apache.org/download-80.cgi" target="_blank">aquí </a>bajen versión 8.5.34 formato zip<br />
* SadWisp Trial Pondre el link aquí cuando este completa.<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
<span style="font-size: large;"><i>Pasos para instalación:</i></span><br />
<br />
Instalación de Java, aquí un vídeo explicativo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/kPWezAZGPks/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/kPWezAZGPks?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
Instalación de postgres <b>Nota, el password debe ser "root" y el puerto debe ser 5433</b> aquí un vídeo explicativo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/DPorVjq14-A/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/DPorVjq14-A?feature=player_embedded" width="320"></iframe></div>
<br />
Instalación de Tomcat aquí un vídeo explicativo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/2dPvsL32lPs/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/2dPvsL32lPs?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
<br />
<div style="text-align: justify;">
Estos serian los requisitos necesarios para proceder a instalar el sistema, a todos los que gusten probarlo pueden ir ambientando la maquina que van a utilizar y en breve sacaré otro tutorial ya con la versión de prueba y la forma de instalarlo.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-66039859187375381372016-09-21T19:57:00.001-05:002016-09-21T19:57:08.752-05:00SadWisp modulo de clientes <div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Continuando con la guia paso a paso de como funciona el sistema SadWisp (Sistema de Administración para Wisp) toca el turno a la explicación de lo que se puede hacer para el seguimiento de pagos de nuestros clientes.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/--MknwY94hJw/V-Mkqm__B2I/AAAAAAAAA0Y/CoNXuqpWrUcd_T4cmosEfYMPF9bDGWzZACK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.58.32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://3.bp.blogspot.com/--MknwY94hJw/V-Mkqm__B2I/AAAAAAAAA0Y/CoNXuqpWrUcd_T4cmosEfYMPF9bDGWzZACK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.58.32.png" width="400" /></a></div>
<br />
<a name='more'></a><br /><br />
<br />
<div style="text-align: justify;">
Una vez que nos logueamos en el sistema debemos ir al menú de "Clientes" en la parte superior de la página, con esto nos mostrará la lista de nuestros clientes que tengamos registrados.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-1lUcQIaEvzw/V-MlRoKT89I/AAAAAAAAA0g/9qxS4X3AYfYjSbsTSJqG87MXds8AK3OPQCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.26.07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="138" src="https://3.bp.blogspot.com/-1lUcQIaEvzw/V-MlRoKT89I/AAAAAAAAA0g/9qxS4X3AYfYjSbsTSJqG87MXds8AK3OPQCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.26.07.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
Para agregar un nuevo cliente, damos click en el botón "Nuevo Cliente" y proporcionamos la información solicitada.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-LH5yTDe1g2Q/V-Mm6YNAWSI/AAAAAAAAA0o/r6FTKE8sheM1eS_5rdlqHPG72ANGW2LkQCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.29.05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="215" src="https://3.bp.blogspot.com/-LH5yTDe1g2Q/V-Mm6YNAWSI/AAAAAAAAA0o/r6FTKE8sheM1eS_5rdlqHPG72ANGW2LkQCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.29.05.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
<b>*Es muy importante colocar en el campo "name" el nombre que se le asigno a ese usuario en la opción de cola simple del mikrotik esto con el fin de poder monitorear y suspender al usuario por falta de pago.</b></div>
<br />
<div style="text-align: justify;">
Una vez que completamos todos los campos, damos click en crear, y sí no existen errores de validación podremos ver algo como esto</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-IJ6h6dq0ODE/V-MoGzMjFJI/AAAAAAAAA0w/y0Diaq5w6r8Lew3Tu7uMzKdvFv8OGVPJwCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.37.44.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="https://4.bp.blogspot.com/-IJ6h6dq0ODE/V-MoGzMjFJI/AAAAAAAAA0w/y0Diaq5w6r8Lew3Tu7uMzKdvFv8OGVPJwCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.37.44.png" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
En esta pantalla tiene 3 columnas que son importantes, la primera al darle click en alguna valor de la columna "Nombre" nos llevara al detalle del cliente, desde ahí podremos editar su información.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-05Xae5pIOTM/V-Mo68FbylI/AAAAAAAAA04/n7kLdEd-QLE-QuyJKapFoIZn5t4OgG8kQCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.41.51.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="331" src="https://4.bp.blogspot.com/-05Xae5pIOTM/V-Mo68FbylI/AAAAAAAAA04/n7kLdEd-QLE-QuyJKapFoIZn5t4OgG8kQCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.41.51.png" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Si damos click en alguna valor de la columna "Nombre mikrotik" nos llevara a los detalles de la cola simple registrada en el mikrotik con ese nombre.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Y0rLuqGg4Io/V-MqDnTXJEI/AAAAAAAAA1A/fBnz8wMWiGcvpuDn_sO2mwA5JM04z0uGQCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.46.48.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" src="https://3.bp.blogspot.com/-Y0rLuqGg4Io/V-MqDnTXJEI/AAAAAAAAA1A/fBnz8wMWiGcvpuDn_sO2mwA5JM04z0uGQCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.46.48.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
<b>* Nota sino estamos conectados al mikrotik nos presentara la pantalla de conexión, ahí ponemos ip y las credenciales.</b></div>
<br />
<div style="text-align: justify;">
Finalmente si damos click en algún valor de la columna "Historial de pago" nos mostrara una pantalla con el historial del cliente que se ira generando automáticamente de acuerdo al día de corte registrado.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-6Z14dfiXYcA/V-Mq3LiwVfI/AAAAAAAAA1I/DLHm1YqJaekT1NVSNls3cOwkKvh0pYEKwCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.48.33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="https://2.bp.blogspot.com/-6Z14dfiXYcA/V-Mq3LiwVfI/AAAAAAAAA1I/DLHm1YqJaekT1NVSNls3cOwkKvh0pYEKwCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.48.33.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
Mes con mes se agregara un registro a esa pantalla para indicarnos que el usuario esta pendiente de pago del mes correspondiente, esta información también servirá para poder enviar un mensaje de correo al cliente indicándole que su fecha de pago se acerca o bien esta vencida.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-SVXjOOOddB0/V-MrQBcRaKI/AAAAAAAAA1Q/lma_fuwZQJcxPaeAIj_SLrqGK95w0ZFywCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.51.57.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="127" src="https://3.bp.blogspot.com/-SVXjOOOddB0/V-MrQBcRaKI/AAAAAAAAA1Q/lma_fuwZQJcxPaeAIj_SLrqGK95w0ZFywCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-21%2Ba%2Bla%2528s%2529%2B19.51.57.png" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Una vez que el cliente nos ha pagado el mes correspondiente, damos click al botón registrar pago y se desactivan las notificaciones para ese cliente para ese mes.</div>
<br />
Aun faltan funciones por agregar pero poco a poco las subiré al software y para los clientes registrados será transparente.<br />
<br />
<br />
Saludos<br />
No olviden comentar.<br />
<br />
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-72777451365494311832016-09-20T21:14:00.001-05:002016-09-20T21:17:41.216-05:00SadWisp sistema de administración para Wisp<br />
<div style="text-align: justify;">
El motivo de esta entrada es para darles a conocer el sistema SadWisp el cual tiene como principal objetivo el apoyo en el seguimiento de los pagos de los clientes para proveedores de servicios de comunicaciones a través de radios, sin embargo, también incluye un modulo para el control total de las fichas de usuarios en el apartado Hotspot que sirve para vender internet con un limite de tiempo.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Xm6n51g81tc/V-HmhnHbo9I/AAAAAAAAAy8/2uAu-Rg01Q0NxN6G8Icbl4r9UEMjQ__JQCK4B/s1600/sadLogo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-Xm6n51g81tc/V-HmhnHbo9I/AAAAAAAAAy8/2uAu-Rg01Q0NxN6G8Icbl4r9UEMjQ__JQCK4B/s400/sadLogo.png" /></a></div>
<br />
Para tener acceso al sistema únicamente se requiere de un registro con un correo electrónico valido, completar los datos solicitados y dar click en crear.<br />
<br />
<a name='more'></a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-w6usi2IasO4/V-HoeQ7McSI/AAAAAAAAAzE/mvFdEu3SZd0PnZDJhaXkJWFa4sY7VbGeQCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.53.48.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="210" src="https://1.bp.blogspot.com/-w6usi2IasO4/V-HoeQ7McSI/AAAAAAAAAzE/mvFdEu3SZd0PnZDJhaXkJWFa4sY7VbGeQCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.53.48.png" width="400" /></a></div>
<br />
<br />
<br />
Si los datos son correctos se le enviara un correo electrónico a la dirección proporcionada y podrá iniciar sesión con los datos registrados anteriormente.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ZxQ5KqWwcVU/V-HpF9Bsh9I/AAAAAAAAAzM/mSSrTjZME4MHwkqCZnObXmNhNjZAAov_gCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.57.16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://3.bp.blogspot.com/-ZxQ5KqWwcVU/V-HpF9Bsh9I/AAAAAAAAAzM/mSSrTjZME4MHwkqCZnObXmNhNjZAAov_gCK4B/s320/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.57.16.png" width="320" /></a></div>
<br />
<br />
Ya registrados iniciamos sesión y tendremos a nuestra disposición el modulo de clientes y el modulo de hotspot<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-vwAUwor5oiE/V-HpeZzHMVI/AAAAAAAAAzY/YcFfMkCDFl8kdO0Rps1FlJ08Z6DzA9qOACK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.58.32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" src="https://4.bp.blogspot.com/-vwAUwor5oiE/V-HpeZzHMVI/AAAAAAAAAzY/YcFfMkCDFl8kdO0Rps1FlJ08Z6DzA9qOACK4B/s320/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B20.58.32.png" width="320" /></a></div>
<br />
<br />
Hacemos click en el modulo de hotspot y nos pedira los datos del mikrotik al cual nos vamos a conectar de manera remota, es importante tener en cuenta que el puerto que utiliza el api de Mikrotik es <span style="background-color: #22242c; color: #dedede; font-family: monospace; font-size: 13px; white-space: pre-line;">8728</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-KLg2T5GboMI/V-Hp6XiJYRI/AAAAAAAAAzg/MbFmeTMbjWgfxr6zWa0Tzpm6L3GnsBgTgCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B21.00.22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="https://2.bp.blogspot.com/-KLg2T5GboMI/V-Hp6XiJYRI/AAAAAAAAAzg/MbFmeTMbjWgfxr6zWa0Tzpm6L3GnsBgTgCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B21.00.22.png" width="400" /></a></div>
<br />
<br />
Sì los datos de conexión son correctos, se mostrará la siguiente pantalla:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-PsDMCsnmEds/V-Hq00D1C9I/AAAAAAAAAzs/Kptz9-wRiywdGac2YU_QiCF5BabqWwYHQCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B19.01.47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://4.bp.blogspot.com/-PsDMCsnmEds/V-Hq00D1C9I/AAAAAAAAAzs/Kptz9-wRiywdGac2YU_QiCF5BabqWwYHQCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B19.01.47.png" width="400" /></a></div>
<br />
Como podemos observar nos presenta los usuarios activos en ese momento, y de lado derecho una lista de las fichas vencidas es decir que ya fueron utilizadas y se termino el tiempo correspondiente, desde ahí podemos seleccionar la casilla de la ficha que queremos eliminar y pulsar el botón de arriba que dice "Eliminar usuarios" esto borrara la ficha de nuestro sistema mikrotik para evitar que siga ocupando espacio.<br />
<br />
Para generar nuevas fichas pulsamos el botón "Generar usuarios" y nos presenta la siguiente pantalla:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-KTbqhhlW_Pw/V-HreRynXcI/AAAAAAAAAz0/6k9DKdDhzqM2yll01nnupKujSjb9cPuZgCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B21.07.35.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://4.bp.blogspot.com/-KTbqhhlW_Pw/V-HreRynXcI/AAAAAAAAAz0/6k9DKdDhzqM2yll01nnupKujSjb9cPuZgCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B21.07.35.png" width="400" /></a></div>
<br />
Aquí podemos observar que nos pide ciertos valores el perfil lo obtiene directamente de los perfiles configurados en nuestro mikrotik y que nos sirve para limitar la velocidad que queremos darle a nuestros usuarios, el prefijo es con lo que va a iniciar cada usuario, los demás parámetros creo que son muy descriptivos, una vez que llenemos esos datos pulsamos generar y el sistema creara y dará de alta dichos usuarios en el mikrotik.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-mFO9Y_disro/V-HsMioMblI/AAAAAAAAA0A/Cw5dSTAlPGE3sGKX2Wc7tNSiKuigIwDfwCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B21.10.38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://2.bp.blogspot.com/-mFO9Y_disro/V-HsMioMblI/AAAAAAAAA0A/Cw5dSTAlPGE3sGKX2Wc7tNSiKuigIwDfwCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-20%2Ba%2Bla%2528s%2529%2B21.10.38.png" width="400" /></a></div>
<br />
<br />
Por ultimo solo nos queda darle al botón de imprimir y el sistema nos descargara un archivo pdf con el formato asignado el cual de momento tiene una plantilla fija pero que podrá ser totalmente personalizada en unos días mas.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-re6yjKIuDFs/V-Httkc39wI/AAAAAAAAA0I/bYQiYKw0Dc82Ftakb3SOiXpxjxbflrfkwCK4B/s1600/Captura%2Bde%2Bpantalla%2B2016-09-14%2Ba%2Bla%2528s%2529%2B17.33.38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="355" src="https://1.bp.blogspot.com/-re6yjKIuDFs/V-Httkc39wI/AAAAAAAAA0I/bYQiYKw0Dc82Ftakb3SOiXpxjxbflrfkwCK4B/s400/Captura%2Bde%2Bpantalla%2B2016-09-14%2Ba%2Bla%2528s%2529%2B17.33.38.png" width="400" /></a></div>
<br />
<br />
<br />
Saludos.<br />
<br /></div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com8tag:blogger.com,1999:blog-4302395541175621439.post-75204682568755235362015-07-24T14:31:00.001-05:002015-07-24T14:31:46.527-05:00Tareas programadas Quartz plugin<br />
<div style="text-align: justify;">
Quartz plugin permite a nuestras aplicaciones Grails tener la capacidad de programar tareas que se ejecutaran utilizando un intervalo especifico de tiempo o bien mediante un cron.</div>
<div style="text-align: justify;">
<br /></div>
<b>Cron</b><br />
<br />
<blockquote class="tr_bq" style="text-align: justify;">
En el sistema operativo Unix, cron es un administrador regular de procesos en segundo plano (demonio) que ejecuta procesos o guiones a intervalos regulares (por ejemplo, cada minuto, día, semana o mes). Los procesos que deben ejecutarse y la hora en la que deben hacerlo se especifican en el fichero crontab. El nombre cron viene del griego chronos (χρόνος) que significa "tiempo".
</blockquote>
<div style="text-align: justify;">
</div>
<a name='more'></a><br /><br />
<br />
<b>Instalando Quartz plugin</b><br />
<br />
<div style="text-align: justify;">
Para instalar quartz plugin únicamente basta con agregar la siguiente línea en la sección plugins de nuestro BuildConfig.groovy</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:java">compile ":quartz:1.0.2"
</pre>
<br />
<br />
<br />
<b>Programando tareas</b><br />
<br />
<div style="text-align: justify;">
Para crear una nueva tarea se ejecuta el comando “grails créate-job” seguido del nombre de nuestra tarea. Grails creará una nueva tarea y la dejara en el directorio “grails-app/jobs”.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Después de ejecutar el comando nuestra tarea programada se verá así:
</div>
<br />
<pre class="brush:java">class TareaProgramadaJob {
static triggers = {
simple repeatInterval: 5000l // execute job once in 5 seconds
}
def execute() {
// execute job
}
}
</pre>
<br />
<br />
<div style="text-align: justify;">
Como podemos observar hay un trigger que le indica a la tarea que se debe ejecutar cada 5 segundos, también podemos establecer una hora específica por medio de un cron, haciendo los cambios quedaría de la siguiente manera:</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:java">class TareaProgramadaJob {
static triggers = {
cron name: 'ejemplo', cronExpression: "00 00 02 * * ?"
}
def execute() {
// execute job
println "esta tarea se ejecutará todos los días a las 2 am"
}
}
</pre>
<br />
<br />
<div style="text-align: justify;">
Así establecemos que debe ejecutarse todos los días a las 2 de la mañana. Para entender a detalle la cronExpression les dejo la siguiente tablita:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-x2kNAR03yNY/VbKRfnPC8zI/AAAAAAAAAsM/1pyr-xBa3ro/s1600/cron.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-x2kNAR03yNY/VbKRfnPC8zI/AAAAAAAAAsM/1pyr-xBa3ro/s1600/cron.PNG" /></a></div>
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-18627463229269252102015-07-23T00:24:00.000-05:002015-07-23T00:25:36.234-05:00Como enviar un email en Grails usando mail plugin<br />
<div style="text-align: justify;">
Actualmente se hace requisito interactuar con el usuario de nuestra aplicación mediante el uso de correo electrónico, desde algo tan simple como enviarle un recordatorio hasta ofrecerle la posibilidad de recuperar su contraseña si por algún motivo la ha olvidado, es por eso que en las siguientes líneas mostraremos como enviar correos electrónicos desde nuestra aplicación grails con la ayuda de mail plugin. </div>
<br />
<b>Instalando Mail Plugin</b><br />
<br />
Para instalar mail plugin únicamente basta con agregar la siguiente línea en la sección plugins de nuestro BuildConfig.groovy<br />
<br />
<pre class="brush:java">compile ":mail:1.0.7"
</pre>
<br />
<br />
<a name='more'></a><br />
<br />
<br />
<b>Configurando Mail Plugin</b><br />
<br />
En este ejercicio realizaré la configuración para utilizar una cuenta de correo “Gmail” como remitente de los correos que enviará mi aplicación, para ello agregamos lo siguiente a nuestro Config.groovy<br />
<br />
<pre class="brush:java">//confuguración del correo desde donde se enviarán los mensajes
grails {
mail {
host = "smtp.gmail.com"
port = 587
username = "tu.cuenta.correo@gmail.com"
password = "tupassword"
props = ["mail.smtp.auth":"true", "mail.smtp.starttls.enable":"true"
]
}
}
</pre>
<br />
<br />
<b>Enviando un mail desde un controller </b><br />
<br />
Mail plugin nos proporciona un servicio que podemos utilizar en cualquier controller, veamos un ejemplo:<br />
<br />
<pre class="brush:java">class EnviaCorreoController {
def mailService
def index() {
//se envia el correo de alta de nuevo usuario
mailService.sendMail {
to "algún.correo@gmail.com"
from "tu.cuenta.correo@gmail.com"
subject "Aquí va el asunto"
html "Este es un correo de <b>ejemplo</b>"
}
}
</pre>
<br />
<br />
<div style="text-align: justify;">
Ahora solo ejecutamos nuestra aplicación y nos dirigimos a la ruta indicada que desatará el evento del envió del correo electrónico, ¿qué pasa? Nos ha marcado un error, ¿se parece a este?:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-_4JA7DLmgGE/VbB4icd3V1I/AAAAAAAAArk/WOaAkrZwjUA/s1600/error%2Bmail.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="127" src="http://1.bp.blogspot.com/-_4JA7DLmgGE/VbB4icd3V1I/AAAAAAAAArk/WOaAkrZwjUA/s400/error%2Bmail.PNG" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Eso es porque google implemento nuevos mecanismos de seguridad pero no se preocupen tiene solución, solo debemos seguir la url que nos muestra en el error y nos mostrará la configuración de nuestra cuenta:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zNKkvFTMo70/VbB4ocU3a1I/AAAAAAAAArs/poR_ZXXqMVg/s1600/mi%2Bcuenta.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="http://3.bp.blogspot.com/-zNKkvFTMo70/VbB4ocU3a1I/AAAAAAAAArs/poR_ZXXqMVg/s400/mi%2Bcuenta.PNG" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Una vez logueados nos vamos al apartado Sing.in & security de ahí buscamos la opción que dice Allow less secure apps y la ponemos a “On”:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-EfD-d0LOoPI/VbB44xRBDLI/AAAAAAAAAr0/GDFuCJ3QlDU/s1600/menos%2Bseguridad.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="144" src="http://3.bp.blogspot.com/-EfD-d0LOoPI/VbB44xRBDLI/AAAAAAAAAr0/GDFuCJ3QlDU/s400/menos%2Bseguridad.PNG" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Una vez realizado el cambio volvemos a probar nuestra aplicación y ahora veremos que no sale más el error y si revisamos en la bandeja del correo destinatario veremos que tenemos un nuevo correo electrónico. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Con esto concluimos este tutorial y dejamos para un siguiente algunas características avanzadas como por ejemplo incluir estilos al correo, adjuntar archivos y presentar imágenes en el cuerpo del correo, espero sus comentarios.
</div>
<div style="text-align: justify;">
<br /></div>
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com2tag:blogger.com,1999:blog-4302395541175621439.post-6223083219398659062015-05-27T14:41:00.000-05:002015-05-27T14:41:42.120-05:00ReCaptcha en Grails con “ReCaptcha and Mailhide support for Grails”<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-B6_T3CaQ6WI/VWYNnc2k5II/AAAAAAAAAps/v8KMne3PeJU/s1600/recaptcha.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="204" src="http://4.bp.blogspot.com/-B6_T3CaQ6WI/VWYNnc2k5II/AAAAAAAAAps/v8KMne3PeJU/s320/recaptcha.PNG" width="320" /></a></div>
<br />
<br />
<b>¿Qué es ReCaptcha? </b><br />
<b><br /></b>
<br />
<blockquote class="tr_bq" style="text-align: justify;">
<b><i>Wiky:</i></b> Recaptcha o reCAPTCHA es una extensión de la prueba Captcha que se utiliza para reconocer texto presente en imágenes. Emplea por tanto la prueba desafío-respuesta utilizada en computación para determinar cuándo el usuario es o no humano para, a su vez, mejorar la digitalización de textos.
Recaptcha se basa en el hecho de que para un ser humano puede ser simple determinar el texto presente en una imagen cuando para una máquina esta tarea resulta en ocasiones demasiado compleja.</blockquote>
<br />
<b>¿Qué es Captcha? </b><br />
<br />
<blockquote class="tr_bq" style="text-align: justify;">
<i><b>Wiky:</b></i> Captcha o CAPTCHA son las siglas de Completely Automated Public Turing test to tell Computers and Humans Apart (prueba de Turing completamente automática y pública para diferenciar computadoras de humanos).</blockquote>
<div style="text-align: justify;">
<br /></div>
<b>¿Cuál es el principio de Recaptcha? </b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i><b>Wiki:</b></i> Cuando se digitaliza un documento impreso se toman fotografías del mismo y esas fotografías se convierten a texto empleando sistemas OCR. Sin embargo, ocurre que hay palabras que presentan dificultades para ser reconocidas automáticamente: aquellas que contienen letras deformes, manchas producto de defectos en la impresión del papel, páginas con polvo, entre otras. Estas palabras pueden ser identificadas por personas de manera mucho más confiable que por un sistema OCR computarizado. Recaptcha emplea esta facilidad del ser humano, para así lograr identificar un ser un humano de un programa de computadora.</blockquote>
<br />
<a name='more'></a><br /><br />
<i>Para saber más: http://es.wikipedia.org/wiki/Captcha http://es.wikipedia.org/wiki/Test_de_Turing</i><br />
<br />
<div style="text-align: justify;">
En esta entrada instalaremos el famoso plugin “ReCaptcha and Mailhide support for Grails” para ello basta con agregar a nuestro archivo BuildConfig.groovy
</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:java">…
compile ':recaptcha:1.2.0'
…
</pre>
<pre class="brush:java"></pre>
<div style="text-align: justify;">
Después de la instalación debemos ejecutar el siguiente comando para realizar una preconfiguración del plugin:
</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:java">grails recaptcha-quickstarts
</pre>
<pre class="brush:java"></pre>
<div style="text-align: justify;">
Nos pedirá elegir entre integrated or standalone elegimos integrated. Al terminar en nuestro Config.groovy se habrán agregado al final las siguientes líneas:
</div>
<div style="text-align: justify;">
<br /></div>
<br />
<pre class="brush:java">// Added by the Recaptcha plugin:
recaptcha {
// These keys are generated by the ReCaptcha service
publicKey = ""
privateKey = ""
// Include the noscript tags in the generated captcha
includeNoScript = true
// Include the required script tag with the generated captcha
includeScript = true
// Set to false to disable the display of captcha
enabled = true
}
mailhide {
// Generated by the Mailhide service
publicKey = ""
privateKey = ""
}
</pre>
<br />
<b>Obteniendo PublicKey y PrivateKey </b><br />
<br />
<div style="text-align: justify;">
Para obtener nuestras keys es necesario ir a la siguiente dirección: <a href="https://www.google.com/recaptcha/admin#list" rel="nofollow" target="_blank">Administración de Recaptcha</a> donde nos mostrara una pantalla como la siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-GiNyPWABjFU/VWYZYmIohkI/AAAAAAAAAp8/mmRvvfuqFTE/s1600/admin%2Brecaptcha.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="267" src="http://4.bp.blogspot.com/-GiNyPWABjFU/VWYZYmIohkI/AAAAAAAAAp8/mmRvvfuqFTE/s400/admin%2Brecaptcha.PNG" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
El formulario es muy sencillo y bastante intuitivo por lo cual al registrar un nuevo sitio nos dará nuestras claves al instante:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-S2N5mYZSxgU/VWYZv2omlBI/AAAAAAAAAqE/blMpmkqDumo/s1600/claves.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="75" src="http://3.bp.blogspot.com/-S2N5mYZSxgU/VWYZv2omlBI/AAAAAAAAAqE/blMpmkqDumo/s400/claves.PNG" width="400" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Para terminar la configuración únicamente nos resta meter esos datos en donde corresponden dentro del archivo Config.groovy
</div>
<div style="text-align: justify;">
<br /></div>
<br />
<b>Añadiendo Rechaptcha a nuestras Vistas</b><br />
<br />
Añadir el plugin a nuestras vistas es tan simple como solo poner:<br />
<br />
<pre style="background: white;"><b><span style="background: #F7FAFF; color: navy; font-size: 9.0pt;"><</span></b><b><span style="background: #F7FAFF; color: #660e7a; font-size: 9.0pt;">recaptcha</span></b><b><span style="background: #F7FAFF; color: navy; font-size: 9.0pt;">:recaptcha/><o:p></o:p></span></b></pre>
<br />
<recaptcha:recaptcha>Con este simple tag, tendremos el siguiente resultado en pantalla:</recaptcha:recaptcha><br />
<recaptcha:recaptcha><br /></recaptcha:recaptcha>
<recaptcha:recaptcha><br /></recaptcha:recaptcha>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-d7RKatOdW_s/VWYcPbBIeWI/AAAAAAAAAqQ/b97RBBOQEEE/s1600/recaptchaform.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="http://4.bp.blogspot.com/-d7RKatOdW_s/VWYcPbBIeWI/AAAAAAAAAqQ/b97RBBOQEEE/s400/recaptchaform.PNG" width="400" /></a></div>
<recaptcha:recaptcha><br /></recaptcha:recaptcha>
<recaptcha:recaptcha><br /></recaptcha:recaptcha><b>
Validando la respuesta del plugin
</b><br />
<pre class="brush:java">def save = {
def user = new User(params)
...other validation...
def recaptchaOK = true
if (!recaptchaService.verifyAnswer(session, request.getRemoteAddr(), params)) {
recaptchaOK = false
}
if(!user.hasErrors() && recaptchaOK && user.save()) {
recaptchaService.cleanUp(session)
...other account creation acivities...
render(view:'showConfirmation',model:[user:user])
}
else {
render(view:'create',model:[user:user])
}
}
</pre>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-64375523464589323572015-05-14T18:54:00.000-05:002015-05-14T21:42:08.407-05:00Mi experiencia con Uber en el Distrito Federal<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-CQcMh38U0sg/VVUwnWJ2O2I/AAAAAAAAApA/Ssb9sHzrla4/s1600/Uberlogo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-CQcMh38U0sg/VVUwnWJ2O2I/AAAAAAAAApA/Ssb9sHzrla4/s1600/Uberlogo.jpg" /></a></div>
<br />
<br />
<b>¿Qué es <a href="https://www.uber.com/cities/mexico-city" target="_blank">Uber</a>? </b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>Según Wiki: Uber es una empresa internacional que proporciona a sus clientes una red de transporte, a través de su software de aplicación móvil, que conecta los pasajeros con los conductores de vehículos registrados en su servicio, los cuales ofrecen un servicio de transporte.</i> </blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<i>Según mi experiencia:</i> Una plataforma que me permite pedir un taxi seguro y tenerlo en menos de 10 a un precio justo y con mejor servicio que los taxis tradicionales.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A continuación hablare de los beneficios y las ventajas que le veo al servicio a partir de mi propia experiencia y punto de vista con base en las preguntas que junto con otros compañeros tuvimos la oportunidad de realizar al conductor de la unidad donde nos toco viajar.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<b>Un poco de preámbulo</b><br />
<br />
<div style="text-align: justify;">
Como casi todas las empresas en el Distrito Federal, donde trabajo ofrecen el servicio de taxi a muy bajo costo para los empleados y esto se debe principalmente a que la empresa tiene un convenio con la empresa transportista que es más o menos bajo costo a cambio de utilizarlos como taxis de planta, sin embargo no daré el nombre de la empresa (le llamaremos Elite) pero se describen como: “un servicio ejecutivo, eficiente y profesional” de lo cual ya hablaremos después, el caso es que nos encontrábamos laborando arduamente cuando decidimos pedir una unidad con “Elite“ eran aproximadamente las 6:30 pm y a pesar de que dicha empresa tiene 3 números para ordenar un taxi la verdad es que en dos de ellos ni siquiera entraba y en el tercer numero simplemente enviaba a buzón, como aún era temprano decidimos esperar y llamar más tarde (puesto que en el df es hora pico y aparte comenzaba a lloviznar y la ciudad se vuelve un caos) estuvimos intentando de las 7:00 pm hasta casi las 9:30 sin obtener respuesta alguna.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<a name='more'></a><br />
<br />
<br />
<b>Uber la salvación</b><br />
<br />
<div style="text-align: justify;">
Ya cuando habíamos decidido salir y tomar el primer taxi de la calle, un compañero que es roomie nuestro nos dijo: ¿Por qué no pedimos un uber? A lo cual sorprendidos respondimos que si el podía pedirlo que lo hiciera y nos íbamos todos juntos, tranquilamente saco su teléfono y como bien curioso me dispuse a observar y pedirle que me dejara ver cómo funcionaba así que entro a la aplicación pulso dos tres botones y en menos de 20 segundos ya teníamos una unidad a dos o tres cuadras de nosotros, también al mismo tiempo la aplicación proporciono datos del chofer, y su vehículo, así como también nos dejó ver en todo momento su ubicación en un mapa tipo google hasta que llego por nosotros, el tiempo que tardó en llegar desde que se contactó hasta que nos recogió fue de menos de 10 minutos.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<b>La primera impresión </b><br />
<br />
<div style="text-align: justify;">
Al momento de reconocer el vehículo que se acercaba notamos un auto en perfectas condiciones de modelo reciente y en excelente estado visual, al momento de abordar nuestro conductor (que era una chica y no pondré el nombre por obvias razones) nos saludó amablemente y nos invitó a ponernos cómodos, se presentó e inmediatamente después nos preguntó nuestro destino y si había alguna ruta en especial por la cual nos queríamos ir, enseguida nos ofreció agua y dulces.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-7aG2xAcJLWI/VVU1WGlZJfI/AAAAAAAAApM/CNzmlMrNS3U/s1600/dulces.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-7aG2xAcJLWI/VVU1WGlZJfI/AAAAAAAAApM/CNzmlMrNS3U/s320/dulces.jpg" width="240" /></a></div>
<br />
<br />
<b>La entrevista a nuestro conductor Uber</b><br />
<br />
<div style="text-align: justify;">
Como era de esperarse ni mis compañeros ni yo pudimos aguantarnos las ganas (es que somos de pueblo) y amablemente preguntamos si podía darnos más información acerca de su “trabajo”, una vez que nos dio entrada diciendo “pregunten lo que gusten” le soltamos el siguiente interrogatorio:</div>
<div style="text-align: justify;">
<br /></div>
<b> • ¿Siempre ha sido taxista? </b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>No, Yo era gerente comercial de una importante empresa </i></blockquote>
<br />
<b> • ¿Por qué decidió asociarse en uber? </b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>Porque soy madre y tengo hijos, en mi anterior empleo me la pasaba viajando y tenía muy poco tiempo para estar con ellos, con uber administro mi tiempo y puedo estar con ellos cuando quiero.</i></blockquote>
<br />
<b>• ¿Cumple con un horario de trabajo? </b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>No, solo trabajo en la mañana, de 9 a 1 y de 4 a 8 aproximadamente, viernes, sábado y domingo trabajo hasta que el cuerpo aguante, no es necesario cumplir un horario. </i></blockquote>
<br />
<b>• ¿Qué se necesita para trabajar como conductor de uber?</b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>Primero necesitas tener un auto propio, que cumpla con las condiciones que solicita uber, por ejemplo si es “uber x” debe ser un sedán de no más tres años de antigüedad y si es “uber black” debe ser un auto de lujo, después debes pasar una serie de exámenes que van desde saber conducir, conocimiento de la ciudad, hasta exámenes psicológicos y de confianza, finalmente al pasar estos exámenes uber emite un certificado y ya pues registrarte y comenzar a dar el servicio.</i></blockquote>
<br />
<b>• ¿Qué problemas tienen como conductores? </b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>“Ahorita andamos en una cacería de brujas” hace poco los traxistas “registrados” hicieron una manifestación para exijir que uber sea prohibido en la ciudad de mexico, alegando que es competencia desleal y que nosotros no pagamos impuestos ni estamos afiliados a una regualación, cosa que es totalmente falsa porque como mencionamos anteriormente todos los conductores de uber estamos certificados y pagamos los impuestos de nuestros vehículos además brindamos un servicio muy seguro y de calidad, deribado de esta manifestación Mancera dio la orden de que si nos sorprenden vehículos particulares prestando servicio de transporte, serán remitidos al corralón.</i></blockquote>
<br />
<div style="text-align: justify;">
<b> • ¿Al ser un vehículo particular sin logos ni nada sospechoso, como se dan cuenta que están prestando servicio? </b></div>
<blockquote class="tr_bq" style="text-align: justify;">
<i>Aquí en el DF casi casi te aplican el tehuacanazo, los mismos taxistas dan aviso a las patrullas quienes llegan te detienen y comienza el interrogatorio. </i></blockquote>
<br />
<b>• La pregunta obligada ¿deja trabajar con uber?</b><br />
<blockquote class="tr_bq" style="text-align: justify;">
<i>Pues deja para pagar el auto, deja para pagar la gasolina, deja para pagar los gatos, sí si deja…</i></blockquote>
<br />
<br />
<b>Conclusiones</b><br />
<br />
<div style="text-align: justify;">
Desde que solicitamos la unidad hasta que nos dejó en nuestro destino la experiencia es totalmente aceptable, los autos son modernos, cobran por km y no por tiempo, no tienes que soportar el mal humor de las señoritas cuando llamas a Elite, te ofrecen agua y dulces, son amables, puedes calificar tu servicio para que sirva de referencia para los demás clientes, además de que siempre sabes quién te lleva, pues tienes la opción de revisar su historial y sus calificaciones como conductor, no necesitas traer efectivo y en todo momento uber monitorea tu viaje, cuentas con seguro de viajero, puedes dividir el costo del viaje e incluso puedes facturar de manera rápida y sencilla, pero lo mejor es que no están nada caros pues nuestro viaje costo 112 pesos mientras que en la empresa normal nos cobran 120 y un taxi regular cobra en promedio 85 pesos por el mismo recorrido.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<b><i> Ahora cuéntanos tu experiencia:
¿Qué te pareció el servicio?, ¿Qué ventajas le ves y qué desventajas?, ¿lo recomiendas o volverías a usar? </i></b><br />
<br />
<br />
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-33813787279478577952015-05-11T19:00:00.002-05:002015-05-11T19:02:04.952-05:00Ajax Autocomplete en Grails<br />
<div style="text-align: justify;">
En esta ocasión voy a mostrar un pequeño ejemplo de un campo que nos va mostrando sugerencias de valores validos de acuerdo a lo que el usuario va escribiendo, un caso típico del uso de estos campos es para introducir la ubicación.
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-KDuVkH55xeg/VVE7D7waLKI/AAAAAAAAAow/p1izIQQcbp8/s1600/autocomplete.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-KDuVkH55xeg/VVE7D7waLKI/AAAAAAAAAow/p1izIQQcbp8/s400/autocomplete.PNG" /></a></div>
<br />
<a name='more'></a>
<br />
<b>Configurando Grails con los js de Ajax Autocomplete
</b><br />
<br />
<div style="text-align: justify;">
Al momento de realizar este tutorial estoy utilizando la versión 2.4.4. de Grails, y utilizaremos los siguientes js: <a href="https://www.devbridge.com/sourcery/components/jquery-autocomplete/">https://www.devbridge.com/sourcery/components/jquery-autocomplete/</a> una vez que hemos descargado los archivos js los agregamos “web-app/js/ después solo agregamos el import en la vista donde lo vayamos a utilizar por ejemplo: </div>
<div style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
<b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; font-size: 9.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"><</span></b><b><span style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; font-size: 9.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">g</span></b><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; font-size: 9.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">:javascript </span></b><b><span style="background: #F7FAFF; color: blue; font-family: "Courier New"; font-size: 9.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">src</span></b><span style="background: rgb(247, 250, 255); font-family: 'Courier New'; font-size: 9pt;">="</span><b><span style="background: #F7FAFF; color: green; font-family: "Courier New"; font-size: 9.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">jquery.autocomplete.js</span></b><span style="background: rgb(247, 250, 255); font-family: 'Courier New'; font-size: 9pt;">"</span><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; font-size: 9.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">/></span></b><span style="font-family: 'Courier New'; font-size: 9pt;"><o:p></o:p></span></div>
<br />
Finalmente dentro de nuestro formulario agregamos un campo de texto por ejemplo:<br />
<br />
<pre style="background: white;"><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;"><</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">g</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">:textField </span></b><b><span lang="EN-US" style="background: #F7FAFF; color: blue; font-size: 9.0pt; mso-ansi-language: EN-US;">class</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-size: 9pt;">="</span><b><span lang="EN-US" style="background: #F7FAFF; color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">form-control</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-size: 9pt;">" </span><b><span lang="EN-US" style="background: #F7FAFF; color: blue; font-size: 9.0pt; mso-ansi-language: EN-US;">id</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-size: 9pt;">="</span><b><span lang="EN-US" style="background: #F7FAFF; color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">location</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-size: 9pt;">" </span><b><span lang="EN-US" style="background: #F7FAFF; color: blue; font-size: 9.0pt; mso-ansi-language: EN-US;">name</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-size: 9pt;">="</span><b><span lang="EN-US" style="background: #F7FAFF; color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">localtion</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-size: 9pt;">"</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">/></span></b><span lang="EN-US" style="font-size: 9pt;"><o:p></o:p></span></pre>
<br />
En la misma vista donde vayamos a utilizer la herramienta es necesario agregar el siguiente script:<br />
<br />
<pre style="background: white;"><span lang="EN-US" style="background: rgb(239, 239, 239); font-size: 9pt;"><</span><b><span lang="EN-US" style="background: #EFEFEF; color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">script </span></b><b><span lang="EN-US" style="background: #EFEFEF; color: blue; font-size: 9.0pt; mso-ansi-language: EN-US;">type=</span></b><b><span lang="EN-US" style="background: #EFEFEF; color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">"text/javascript"</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-size: 9pt;">></span><span lang="EN-US" style="font-size: 9pt;">
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">$</span></b><span lang="EN-US" style="font-size: 9pt;">(</span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">function</span></b><span lang="EN-US" style="font-size: 9pt;">() {
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">$</span></b><span lang="EN-US" style="font-size: 9pt;">(</span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">"#location"</span></b><span lang="EN-US" style="font-size: 9pt;">).</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">autocomplete</span><span lang="EN-US" style="font-size: 9pt;">({
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">paramName</span></b><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">'q'</span></b><span lang="EN-US" style="font-size: 9pt;">,
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">ajaxSettings</span></b><span lang="EN-US" style="font-size: 9pt;">:{</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">type</span></b><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">'GET'</span></b><span lang="EN-US" style="font-size: 9pt;">,
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">async</span></b><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">false</span></b><span lang="EN-US" style="font-size: 9pt;">,
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">dataType</span></b><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">'json'</span></b><span lang="EN-US" style="font-size: 9pt;">},
</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">transformResult</span><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">function</span></b><span lang="EN-US" style="font-size: 9pt;">(response) {
</span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">return </span></b><span lang="EN-US" style="font-size: 9pt;">{
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">suggestions</span></b><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">$</span></b><span lang="EN-US" style="font-size: 9pt;">.</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">map</span><span lang="EN-US" style="font-size: 9pt;">( response.</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">data</span><span lang="EN-US" style="font-size: 9pt;">, </span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">function</span></b><span lang="EN-US" style="font-size: 9pt;">(data) {
</span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">return </span></b><span lang="EN-US" style="font-size: 9pt;">{ </span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">value</span></b><span lang="EN-US" style="font-size: 9pt;">: data.</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">name</span><span lang="EN-US" style="font-size: 9pt;">, </span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">data</span></b><span lang="EN-US" style="font-size: 9pt;">: data.subtext };
})
};
},
</span><b><span lang="EN-US" style="color: #660e7a; font-size: 9.0pt; mso-ansi-language: EN-US;">serviceUrl</span></b><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">'https://graph.facebook.com/search?type=adcity&method=GET&format=json&suppress_http_code=1'</span></b><span lang="EN-US" style="font-size: 9pt;">,
</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">onSelect</span><span lang="EN-US" style="font-size: 9pt;">: </span><b><span lang="EN-US" style="color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">function </span></b><span lang="EN-US" style="font-size: 9pt;">(suggestion) {
</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">alert</span><span lang="EN-US" style="font-size: 9pt;">(</span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">'You selected: ' </span></b><span lang="EN-US" style="font-size: 9pt;">+ suggestion.</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">value </span><span lang="EN-US" style="font-size: 9pt;">+ </span><b><span lang="EN-US" style="color: green; font-size: 9.0pt; mso-ansi-language: EN-US;">', ' </span></b><span lang="EN-US" style="font-size: 9pt;">+ suggestion.</span><span lang="EN-US" style="color: #7a7a43; font-size: 9.0pt; mso-ansi-language: EN-US;">data</span><span lang="EN-US" style="font-size: 9pt;">);
}
});
});
<span style="background: #EFEFEF;"></</span></span><b><span lang="EN-US" style="background: #EFEFEF; color: navy; font-size: 9.0pt; mso-ansi-language: EN-US;">script</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-size: 9pt;">></span><span lang="EN-US"><o:p></o:p></span></pre>
<br />
<div style="text-align: justify;">
El Api de Facebook trae algunas monerías que pueden ser accedidas por los usuarios sin la necesidad de requerir un toquen de acceso, tal es el caso de lo que Facebook conoce como “search” la cual nos permite buscar nombres de usuarios, lugares, entre otras cosas, para saber más acerca del comando search de Facebook <a href="https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3">https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3</a>.
</div>
<br/>Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com2tag:blogger.com,1999:blog-4302395541175621439.post-54333283709439660552015-04-23T14:28:00.000-05:002015-04-23T14:28:46.233-05:00Login con Facebook parte 2<br />
<div style="text-align: justify;">
Continuando con el tutorial para realizar un login con las credenciales de Facebook desde mi aplicación empezaremos mencionando los siguientes requisitos:
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
1.- Proyecto resultante del ejercicio: <a href="http://paraisodeldesarrollador.blogspot.mx/2015/03/configurar-spring-security-core-plugin.html">Configurar Spring Security Core Plugin 2.0</a>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
2.- Tener configurada nuestra cuenta de Facebook como se muestra en el tema: <a href="http://paraisodeldesarrollador.blogspot.mx/2015/03/login-con-facebook-parte-1.html">Login con Facebook pate 1</a></div>
<br />
<div style="text-align: justify;">
Para que se vea más ilustrativo el tutorial están son mis vistas: a una se puede acceder sin estar logueado y la otra se puede acceder únicamente con un usuario logueado con el rol: “ROLE_USER” y "ROLE_FACEBOOK"
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Así se ve la vista sin seguridad:
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-SRUgz5oDgL0/VTkoY8wi1vI/AAAAAAAAAmo/I9bcShgIFGQ/s1600/sin%2Bseguridad.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-SRUgz5oDgL0/VTkoY8wi1vI/AAAAAAAAAmo/I9bcShgIFGQ/s400/sin%2Bseguridad.PNG" /></a></div>
<br />
<br />
Así se ve la vista con seguridad:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-oVdXncOKA_8/VTkpO50cxuI/AAAAAAAAAm0/xGTvb3eAx1c/s1600/con%2Bseguridad.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-oVdXncOKA_8/VTkpO50cxuI/AAAAAAAAAm0/xGTvb3eAx1c/s400/con%2Bseguridad.PNG" /></a></div>
<br />
<br />
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
Este es el formulario por default que se muestra cuando se intenta acceder a la página que está marcada para ser accedida únicamente por usuarios registrados:
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-k60uuTaDTis/VTkrjI0mXdI/AAAAAAAAAm8/fTpFSMHZ2Uo/s1600/formulario.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-k60uuTaDTis/VTkrjI0mXdI/AAAAAAAAAm8/fTpFSMHZ2Uo/s400/formulario.PNG" /></a></div>
<br />
<br />
<b>Recapitulando:</b>
<br />
<b><br /></b>
<br />
<div style="text-align: justify;">
• La configuración está hecha únicamente mediante el plugin de Spring Security
</div>
<div style="text-align: justify;">
• Podemos acceder a una página sin necesidad de estar logueados y a la otra podemos acceder una vez que nos hemos logueado.
</div>
<div style="text-align: justify;">
• Tenemos la aplicación de Facebook configurada como se muestra en el tutorial mencionado arriba.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Con este pequeño ejemplo nos vamos a seguir para integrar la parte del login con Facebook.
</div>
<br />
<br />
<h3>
Facebook Authentication for Spring Security
</h3>
<br />
<div style="text-align: justify;">
Es el plugin mediante el cual realizaremos la conexión entre Facebook y nuestra aplicación, dicho plugin se integra perfectamente con el de Spring y su configuración es bastante simple, para instalarlo únicamente debemos agregar la siguiente línea a nuestro <i>BuildConfig.groovy</i>
<br />
<i><br /></i></div>
<pre class="brush:java">...
compile ":spring-security-facebook:0.17"
...
</pre>
<br />
<br />
<b>Algunas modificaciones simples al proyecto:</b>
<br />
• Agregar el rol de Facebook al BootStrap para que se carguen desde el inicio quedando así:
<br />
<pre class="brush:java">...
def init = { servletContext ->
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
def facebookRole = new Role(authority: 'ROLE_FACEBOOK').save(flush: true)
def testUser = new User(username: 'me', password: 'password')
testUser.save(flush: true)
UserRole.create testUser, userRole, true
}
...
</pre>
<br />
• Crear la clase "UsuarioFacebook" la cual debe contener la siguiente estructura requerida por el plugin:
<br />
<pre class="brush:java">class UsuarioFacebook {
Long uid
String accessToken
Date accessTokenExpires
static belongsTo = [user: User] //connected to main Spring Security domain
static constraints = {
uid unique: true
}
}
</pre>
<br />
<div style="text-align: justify;">
Ahora debemos indicarle al plugin cuál es el dominio que se va a utilizar para guardar los usuarios de Facebook, así como también, nuestro app secret y app Id, estos últimos datos son los que obtenemos al configurar una nueva aplicación en nuestra cuenta de Facebook, (primera parte de este tutorial). Agregamos lo siguiente en el archivo <i>Config.groovy</i></div>
<br />
<pre class="brush:java">grails.plugin.springsecurity.facebook.domain.classname='your FacebookUser domain'
grails.plugin.springsecurity.facebook.secret = 'Facebook secret for your app'
grails.plugin.springsecurity.facebook.appId = 'Facebooks's app ID'
</pre>
<br />
<div style="text-align: justify;">
Únicamente nos falta poner nuestro botón para iniciar sesión con Facebook, el código es el siguiente y lo podemos poner en cualquier parte o bien desde nuestro formulario de login, para este tutorial lo pondré en el index ya que es la página que tengo a la mando cuando levanto la aplicación:</div>
<br />
<pre class="brush:java"> < facebookAuth:connect permissions="email,user_about_me"/ >
</pre>
<br />
<br />
<div style="text-align: justify;">
Lo que hace el código anterior es pedir el login a Facebook con los permisos especificados en el parámetro “permissions” en este caso le estamos pidiendo acceso a su email e información de perfil.
Ya que levantamos nuestra aplicación y entramos a la página donde pusimos nuestro botón, se verá más o menos así:
<br />
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-nfOvn87rTwk/VTk0CdmGt1I/AAAAAAAAAnM/0iTZJvbjw6s/s1600/boton%2Blogin%2Bcon%2Bfacebook.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-nfOvn87rTwk/VTk0CdmGt1I/AAAAAAAAAnM/0iTZJvbjw6s/s400/boton%2Blogin%2Bcon%2Bfacebook.PNG" /></a></div>
<br />
<br />
<br />
<div style="text-align: justify;">
Una vez que pulsamos el botón de lógin nos debiera enviar inmediatamente a la página de login de Facebook donde debemos poner nuestros datos de Facebook o sí estamos logueados en únicamente nos preguntará si deseamos autorizar la aplicación y los permisos que le daremos, hagamos la prueba ejecutamos la aplicación y pulsamos el botón…
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Así como dejamos configurada nuestra aplicación nos dará un error <b>"la url proporcionada no esta permitida…”</b>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-654z5z6YG0o/VTk5VMreYTI/AAAAAAAAAnc/fQ2OrsbcuZw/s1600/error%2Burl.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-654z5z6YG0o/VTk5VMreYTI/AAAAAAAAAnc/fQ2OrsbcuZw/s400/error%2Burl.PNG" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Esto pasa porque en la configuración de la aplicación no hemos configurado desde que url debemos invocar el login, esto es más como una medida de seguridad para los usuarios de Facebook, ¿Cómo resolverlo? Muy simple:
</div>
<br />
<h3>
Resolviendo error de Facebook: “URL proporcionada no está permitida” </h3>
<br />
<br />
<div style="text-align: justify;">
<b>1.-</b> Vamos a la dirección https://developers.facebook.com/apps/ con la cuenta que utilizamos para configurar la aplicación en la parte 1 de este tutorial
</div>
<div style="text-align: justify;">
<br /></div>
<b>2.-</b> Seleccionar nuestra aplicación en mi caso:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-gTVFB3Cwh-Q/VTk8c6dkoOI/AAAAAAAAAno/xXnIOasDaZQ/s1600/facebook%2Bapps.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-gTVFB3Cwh-Q/VTk8c6dkoOI/AAAAAAAAAno/xXnIOasDaZQ/s400/facebook%2Bapps.PNG" /></a></div>
<br />
<div style="text-align: justify;">
<b>3.-</b> Nos vamos a configuración y de ahí en la pestaña avanzada buscamos la sección OAuth Settings y debemos poner la url desde donde se invocará el login de Facebook, en mi caso quedaría así:
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-qYFELXMfWuM/VTk8lBbSmaI/AAAAAAAAAnw/ZpS0CbT8tAQ/s1600/OAuth%2BSettings.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-qYFELXMfWuM/VTk8lBbSmaI/AAAAAAAAAnw/ZpS0CbT8tAQ/s400/OAuth%2BSettings.PNG" /></a></div>
<br />
<b>4.-</b> Damos guardar cambios.<br />
<br />
<div style="text-align: justify;">
Nuevamente volvemos a nuestra pantalla donde tenemos el botón de login con Facebook y lo presionamos, ahora veremos que nos llevara a una ventana en donde nos informa que la aplicación “nombre que le dimos a nuestra aplicación” quiere acceder a nuestro perfil mostrando los permisos que estamos solicitando, sí estamos de acuerdo pulsamos en aceptar y automáticamente me regresa a la pantalla principal de mi aplicación pero ya logueado.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-uOo_qEzFDho/VTlHA2t1MII/AAAAAAAAAoA/WPIKcrO182w/s1600/autorizar%2Baplicaci%C3%B3n.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-uOo_qEzFDho/VTlHA2t1MII/AAAAAAAAAoA/WPIKcrO182w/s400/autorizar%2Baplicaci%C3%B3n.PNG" /></a></div>
<br />
<br />
<div style="text-align: justify;">
<i>Con esto no nos queda más que ir a la página “conSeguridad” y verificar que efectivamente la está mostrando. Espero les sea de ayuda este tutorial, más adelante sobrescribiremos uno de los servicios del plugin de Facebook para obtener más datos y también la foto de perfil del usuario que se loguea.
</i></div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com1tag:blogger.com,1999:blog-4302395541175621439.post-63827425014206493922015-04-07T12:26:00.001-05:002015-04-07T12:26:51.111-05:00Como sobrevivir al trabajo de desarrollador en 5 pasos<br />
<div style="text-align: justify;">
Este post lo voy a dirigir a todas aquellas personas, que como yo en algún momento empiezan a trabajar de desarrolladores, ya sea por su propia cuenta o alguna empresa o consultoría, y les quiero compartir los pasos para sobrevivir a este ritmo de trabajo, a la presión, pero sobre todo orientarlos sobre qué hacer cuando nos piden que utilicemos alguna herramienta que no dominamos o bien que ni siquiera conocemos, yo les voy a compartir lo que hago cuando me topo con esta situación.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<strong>1.- Investigar ¿qué es?, o ¿qué hace? la herramienta/tecnología que me solicitaron: </strong>
Cuando te topes con que te dicen vas a desarrollar en este IDE, o vas a utilizar tal herramienta, o simplemente te topas con alguna tecnología que no conoces, <u>lo primero es investigar todo lo que se pueda sobre dicha tecnología/herramienta</u>, para eso tenemos wiki pedía, google y cientos de bloggers que como este intentan ayudar al desarrollador en su andar diario.
</div>
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
<strong>2.- Revisar las versiones liberadas y sus compatibilidades: </strong>
Algo que me sucedía comúnmente y que es un error que la mayoría de los que empezamos a programar cometemos, es que una vez que nos informamos o indagamos sobre la herramienta que tenemos que utilizar lo que hacemos es bajar siempre las últimas versiones, y ahí está el error porque nos podemos llevar pequeñas sorpresas, una de ellas es la compatibilidad entre las versiones que tenemos instaladas y la herramienta que queremos ocupar, <u>la recomendación aquí es revisar los issues(reportes de error, bugs) de dicha herramienta y buscar y descargar siempre una versión estable que se integre sin problemas con las demás herramientas con las que estamos desarrollando. </u> por poner un ejemplo: no podemos correr glassfish 3.0 con JDK 1.4, porque JDK 1.4 no soporta las anotaciones requeridas por glassfish, pero también nos enteramos que un entorno amigable y estable es glassfish 2.1 con JDK 1.5 funciona perfectamente, entonces nos decidimos por usar esa combinación.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<strong>3.-Instalar la versión más idónea y estable que conviva con nuestro entorno:</strong>
Ya que vimos los reportes de error y los posibles problemas a los que nos podemos encontrar con las últimas versiones, también vamos a poder indagar sobre que versiones si pueden correr y convivir amigablemente, entonces el punto aquí es instalarlas.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<strong>4.- Comenzar con el ejemplo más sencillo:</strong>
Una vez que ya tenemos el concepto, ya tenemos la herramienta funcionando, lo que sigue es tomar el ejemplo más básico, y hacerlo funcionar, si hasta aquí no puedo hacer el ejemplo más sencillo (podría ser el clásico hola mundo) debo regresar al punto 1.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<strong>5.- Empezar a utilizar dicha tecnología, destrozando ejemplos ya hechos: </strong>
Este es quizá el punto más importante de todos, ya que aquí lo que debemos hacer es empezar a jugar con los ejemplos que ya estén hechos, aquí debemos averiguar que pasa si hago esto, que pasa si quito aquello, y también debemos tener una idea ya clara de que es lo que queremos hacer con esta tecnología para que sin darnos cuenta ya nos encontremos trabajando con la herramienta o la tecnología solicitada.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Estos son los puntos más importantes que yo realizo cada vez que me piden algo que no domino del todo o que ni siquiera conozco, ya que cubren la mayoría de los puntos que nos pueden dar sorpresas cuando empezamos a ver algo nuevo en nuestro trabajo, concretamente en el mundo de los desarrolladores, donde, <strong>cuando apenas empiezas a familiarizarte con alguna herramienta o empiezas a dominarla, ó decepción ya hay otra nueva que hace más cosas o mejores que la que estabas aprendiendo</strong>, y es necesario volver a repetir este proceso de aprendizaje para no quedarnos obsoletos.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
PD, en este adicionalmente, y concuerdo con OscarRyz, habría falta mencionar un paso "0" que textualmente dice:
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
"<i>Yo añadiría, un paso 0, conocer la plataforma en la que se va a desarrollar. Esto es también muy importante, ya que sirve para conocer el resto de las librerías y frameworks que le agregan cosas.</i>"
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Espero sus comentarios =)</div>
<div style="text-align: justify;">
<br /></div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com2tag:blogger.com,1999:blog-4302395541175621439.post-25741371094139667012015-03-26T13:45:00.000-06:002015-03-26T13:45:36.463-06:00Tips: println vs log.debug<br />
<div style="text-align: justify;">
El titulo de esta entrada puede ser algo raro sin embargo la mayoría de nosotros estamos acostumbrados a debuguear con el famosísimo <b>“println”</b> antes de usar <b>“el debugger”</b>, si ese es tu caso este pequeño tip te interesa.
</div>
<br />
<br />
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-Du-2NKtu_f0/VRRfBa4W4vI/AAAAAAAAAlk/-KWot_TiEKQ/s1600/log.debug.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Du-2NKtu_f0/VRRfBa4W4vI/AAAAAAAAAlk/-KWot_TiEKQ/s400/log.debug.PNG" /></a></div>
</div>
<br />
<br />
<div style="text-align: justify;">
Como podemos observar en la imagen anterior hay dos líneas cuyo contenido es exactamente el mismo <i>“el valor recibido es..”</i> pero podemos notar que la instrucción en un caso es el famosísimo <i>“println”</i> y en la otra tenemos un log.debug, si nosotros lanzamos nuestra aplicación y desde web entramos al index del controlador Ejemplo, únicamente veremos la salida de consola “el valor recibido es”, pero ¿por qué si yo puse dos líneas? Esto es porque la configuración del log está establecida por defaul a error.
</div>
<a name='more'></a>
<br />
<br />
<b>Niveles de Log</b>
<br />
<br />
<div style="text-align: justify;">
Existen diferentes niveles de log, esto es porque seguramente no queremos llenar nuestra consola con un montón de mensajes de cualquier tipo, para ello y depende también de nuestra manera de colocarlos, existen diferentes niveles de log:
</div>
<br />
<div style="text-align: justify;">
<b>• OFF:</b> este es el nivel de mínimo detalle, deshabilita todos los logs.
</div>
<div style="text-align: justify;">
<b>• FATAL:</b> se utiliza para mensajes críticos del sistema, generalmente después de guardar el mensaje el programa abortará.
</div>
<div style="text-align: justify;">
<b>• ERROR:</b> se utiliza en mensajes de error de la aplicación que se desea guardar, estos eventos afectan al programa pero lo dejan seguir funcionando, como por ejemplo que algún parámetro de configuración no es correcto y se carga el parámetro por defecto.
</div>
<div style="text-align: justify;">
<b>• WARN:</b> se utiliza para mensajes de alerta sobre eventos que se desea mantener constancia, pero que no afectan al correcto funcionamiento del programa.
</div>
<div style="text-align: justify;">
<b>• INFO:</b> se utiliza para mensajes similares al modo "verbose" en otras aplicaciones.
</div>
<div style="text-align: justify;">
<b>• DEBUG:</b> se utiliza para escribir mensajes de depuración. Este nivel no debe estar activado cuando la aplicación se encuentre en producción.
</div>
<div style="text-align: justify;">
<b>• TRACE:</b> se utiliza para mostrar mensajes con un mayor nivel de detalle que debug.
</div>
<div style="text-align: justify;">
<b>• ALL:</b> este es el nivel de máximo detalle, habilita todos los logs (en general equivale a TRACE).
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
El uso de cada nivel dependerá de lo que queramos mostrar, por ejemplo si quiero enviar un mensaje dentro de un ciclo puedo utilizar log.debug “en el ciclo $i …” y si ocurre algo mal dentro de mi ciclo que estaba previamente dentro de un try-catch puedo poner un log.error “ocurrio un error dentro del ciclo …” de esta manera dependiendo del nivel de log establecido se mostraran o no los mensajes.
</div>
<div style="text-align: justify;">
<br /></div>
<br />
<b>Cambiando el nivel de log</b>
<br />
<br />
<div style="text-align: justify;">
Para cambiar el nivel del log debemos ir al archivo “Config.groovy” y en el apartado log4j poner el nivel de log seguido de la clase o clases a las que queremos aplicarlo ejemplo:
</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:java">
info ‘grails.app.controllers’ //establece nivel de log debug para todos nuestros controladores
debug ‘grails.app.controllers.com.test.EjemploController’ //establece nivel de log info para el controlador Ejemplo.
</pre>
<br />
<br />
<div style="text-align: justify;">
Una vez que cambiamos el nivel de log para al ejecutar la aplicación y correr el programa veremos la siguiente salida:</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/--f9-9Z1xQ1I/VRRgkyWrKmI/AAAAAAAAAl8/Md5uFL4XRG8/s1600/salida.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/--f9-9Z1xQ1I/VRRgkyWrKmI/AAAAAAAAAl8/Md5uFL4XRG8/s400/salida.PNG" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Como podemos observar se pintan dos líneas: la original del println y la de debug que además de lo que hemos puesto trae información que puede ser importante para nosotros como por ejemplo la hora y el nombre del controlador desde donde proviene el mensaje.
<br />
<b>Conclusiones: </b>si son de los que usan println para debuguear sus aplicaciones, les aconsejo que utilicen los niveles de log, aunque es mejor utilizar el debugger.
</div>
<br />Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-65367730933343267132015-03-24T19:05:00.000-06:002015-03-24T19:05:08.086-06:00Login con Facebook parte 1<div style="text-align: justify;">
En estos tiempos son cada vez más los sitios web en los que te permiten realizar la autenticación por medio de redes sociales siendo Facebook la más usada para tal fin, en este pequeño tutorial vamos a realizar la conexión para poder autenticarnos a una aplicación externa con nuestra cuenta de Facebook.
</div>
<br />
Al momento de la realización del tutorial ocupamos las siguientes versiones: Grails 2.4.4 y Java 1.7<br />
<br />
<div style="text-align: justify;">
Crearemos un nuevo proyecto exclusivamente para este ejemplo, en el, lo primero que debemos realizar es la instalación y configuración de Spring Security Core, una opción es como lo muestro aquí (<a href="http://paraisodeldesarrollador.blogspot.mx/2015/03/configurar-spring-security-core-plugin.html">Configurar Spring Security Core Plugin</a>).
</div>
<br />
<br />
<div style="text-align: justify;">
Este tutorial lo vamos a dividir en dos partes, esta primera, la cual consta de las configuraciones que debemos realizar en Facebook para dejar “lista” una aplicación para poder loguearnos y la segunda que tratara sobre el código en nuestra aplicación para enlazar el formulario de login de Facebook.
</div>
<div style="text-align: justify;">
<br /></div>
<b>Creando una nueva aplicación en Facebook</b>
<br />
<br />
1.- Entrar a la url https://developers.facebook.com, la cual al momento de realizar este tutorial muestra lo siguiente:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-KFdAt9ble80/VRIHGATAVMI/AAAAAAAAAkk/4sHcNe-m8vY/s1600/imagen%2B1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-KFdAt9ble80/VRIHGATAVMI/AAAAAAAAAkk/4sHcNe-m8vY/s400/imagen%2B1.PNG" /></a></div>
<br />
<br />
<a name='more'></a>
2.- En el menú “My Apps” seleccionar “Add a new App”
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-L1WSstIiFco/VRIHVmcR1II/AAAAAAAAAko/jWQpBt-qhRU/s1600/nueva%2Bapp.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-L1WSstIiFco/VRIHVmcR1II/AAAAAAAAAko/jWQpBt-qhRU/s400/nueva%2Bapp.PNG" /></a></div>
<br />
<br />
3.- Elegimos sitio web y posteriormente escribimos el nombre para nuestra App
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-gej2p39LjC8/VRIH3VMmSXI/AAAAAAAAAkw/3h044CjyodA/s1600/nombre%2Bde%2Bnuestra%2Bapp.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-gej2p39LjC8/VRIH3VMmSXI/AAAAAAAAAkw/3h044CjyodA/s400/nombre%2Bde%2Bnuestra%2Bapp.PNG" /></a></div>
<br />
<br />
4.- Seleccionamos la categoría mas adecuada
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-9O6QqSne3tI/VRIH99q1vgI/AAAAAAAAAk8/4Y46vxruPNg/s1600/categoria.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-9O6QqSne3tI/VRIH99q1vgI/AAAAAAAAAk8/4Y46vxruPNg/s400/categoria.PNG" /></a></div>
<br />
<br />
5.- Le damos en “Create App”
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-M_tl2PTbSuo/VRIIMdviYhI/AAAAAAAAAlE/nSuCEp49xNg/s1600/app%2Bcreada.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-M_tl2PTbSuo/VRIIMdviYhI/AAAAAAAAAlE/nSuCEp49xNg/s400/app%2Bcreada.PNG" /></a></div>
<br />
<br />
<div style="text-align: justify;">
6.-Pulsamos “Skip Quick Star” (esquina superior derecha) y finalmente nos muestra el escritorio de nuestra aplicación
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-BGtkMtdGank/VRIIapUwboI/AAAAAAAAAlM/P2R2NK_j8AI/s1600/escritorio.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-BGtkMtdGank/VRIIapUwboI/AAAAAAAAAlM/P2R2NK_j8AI/s400/escritorio.PNG" /></a></div>
<br />
<br />
<div style="text-align: justify;">
Con esto ya tenemos creada nuestra aplicación en Facebook, la cual nos permitirá ser el puente entre Facebook y nuestra aplicación externa para poder loguearnos, en este punto ya tenemos asignado un App ID y un App Secret que son las llaves que requerimos para conectarnos a Facebook desde el plugin de Spring Security.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Nota:</b> Aunque tener el App ID y App Secret ya nos permiten configurar el plugin de Spring Security aún faltan algunas configuraciones para lograr el correcto funcionamiento de la integración de Facebook con nuestra apliación, estas configuraciones adicionales las veremos en el siguiente tutorial.</div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com6tag:blogger.com,1999:blog-4302395541175621439.post-21434883899973739812015-03-19T13:44:00.000-06:002015-03-19T13:44:15.012-06:00Tips: Enviar mensajes de error desde “controller” en Grails<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
En algún momento de nuestra aplicación vamos a tener la
necesidad de enviar mensajes de error a nuestras pantallas directamente desde
nuestro controlador, a continuación les dejo la forma de hacerlo.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-9eZ_1eq1qs0/VQskQHtNgzI/AAAAAAAAAkM/5BL4SXL0a74/s1600/contrasenia.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-9eZ_1eq1qs0/VQskQHtNgzI/AAAAAAAAAkM/5BL4SXL0a74/s1600/contrasenia.PNG" height="163" width="320" /></a></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<a name='more'></a>
<br />
<div class="MsoNormal" style="text-align: justify;">
<b>En nuestra GSP debemos poner el siguiente código:</b><o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br />
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
<b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"><</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">g</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">:if </span></b><b><span lang="EN-US" style="background: #F7FAFF; color: blue; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">test</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-family: 'Courier New';">="</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">${</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">flash</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-family: 'Courier New';">.</span><span lang="EN-US" style="background: #F7FAFF; color: green; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">message</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">}</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-family: 'Courier New';">"</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">></span></b><b><span lang="EN-US" style="color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"><br />
</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';"><</span><b><span lang="EN-US" style="background: #EFEFEF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">div </span></b><b><span lang="EN-US" style="background: #EFEFEF; color: blue; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">class</span></b><b><span lang="EN-US" style="background: #EFEFEF; color: green; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">="alert
alert-info"</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';">> <o:p></o:p></span></div>
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
<b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"> </span></b><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">${</span></b><b><span style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">flash</span></b><span style="background: rgb(247, 250, 255); font-family: 'Courier New';">.</span><span style="background: #F7FAFF; color: green; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">message</span><span style="background: rgb(247, 250, 255); font-family: 'Courier New';">?.encodeAsHTML()</span><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">} <o:p></o:p></span></b></div>
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
<b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"> </span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';"></</span><b><span lang="EN-US" style="background: #EFEFEF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">div</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';">></span><span lang="EN-US" style="font-family: 'Courier New';"><br />
</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"></</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">g</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">:if></span></b><b><span lang="EN-US" style="color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"><br />
<span style="background: #F7FAFF;"><</span></span></b><b><span lang="EN-US" style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">g</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">:if </span></b><b><span lang="EN-US" style="background: #F7FAFF; color: blue; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">test</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-family: 'Courier New';">="</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">${</span></b><b><span lang="EN-US" style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">flash</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-family: 'Courier New';">.</span><span lang="EN-US" style="background: #F7FAFF; color: green; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">error</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">}</span></b><span lang="EN-US" style="background: rgb(247, 250, 255); font-family: 'Courier New';">"</span><b><span lang="EN-US" style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">></span></b><b><span lang="EN-US" style="color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"><br />
</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';"><</span><b><span lang="EN-US" style="background: #EFEFEF; color: navy; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">div </span></b><b><span lang="EN-US" style="background: #EFEFEF; color: blue; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">class</span></b><b><span lang="EN-US" style="background: #EFEFEF; color: green; font-family: "Courier New"; mso-ansi-language: EN-US; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">="alert
alert-danger"</span></b><span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';">> <o:p></o:p></span></div>
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
<span lang="EN-US" style="background: rgb(239, 239, 239); font-family: 'Courier New';"> </span><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">${</span></b><b><span style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">flash</span></b><span style="background: rgb(247, 250, 255); font-family: 'Courier New';">.</span><span style="background: #F7FAFF; color: green; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">error</span><span style="background: rgb(247, 250, 255); font-family: 'Courier New';">?.encodeAsHTML()</span><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">}<o:p></o:p></span></b></div>
<br />
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
<b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"> </span></b><span style="background: rgb(239, 239, 239); font-family: 'Courier New';"></</span><b><span style="background: #EFEFEF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">div</span></b><span style="background: rgb(239, 239, 239); font-family: 'Courier New';">></span><span style="font-family: 'Courier New';"><br />
</span><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;"></</span></b><b><span style="background: #F7FAFF; color: #660e7a; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">g</span></b><b><span style="background: #F7FAFF; color: navy; font-family: "Courier New"; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">:if></span></b><span style="font-family: 'Courier New';"><o:p></o:p></span></div>
<br /></div>
<div style="text-align: justify;">
<pre class="brush:java"><div style="text-align: justify;">
Son dos simples condiciones que pintaran el mensaje normal o de error respectivamente, si es que existieran.</div>
</pre>
</div>
<div class="MsoNormal" style="text-align: justify;">
<div style="text-align: justify;">
<br /></div>
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
<b>En el Controlador </b><o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Para enviar un mensaje desde cualquier controlador debemos
poner:<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt; text-align: justify;">
<div class="MsoNormal" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; margin-bottom: 0.0001pt;">
<span style="color: #660e7a; font-family: "Courier New"; font-size: 12.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">flash</span><span style="font-family: 'Courier New'; font-size: 12pt;">.</span><span style="color: green; font-family: "Courier New"; font-size: 12.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">message </span><span style="font-family: 'Courier New'; font-size: 12pt;">= </span><b><span style="color: green; font-family: "Courier New"; font-size: 12.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">"mensaje de éxito"<o:p></o:p></span></b></div>
<div class="MsoNormal" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal">
<b>ó</b><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<br />
<div class="MsoNormal" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; margin-bottom: 0.0001pt;">
<span style="color: #660e7a; font-family: "Courier New"; font-size: 12.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">flash</span><span style="font-family: 'Courier New'; font-size: 12pt;">.</span><span style="color: green; font-family: "Courier New"; font-size: 12.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">error </span><span style="font-family: 'Courier New'; font-size: 12pt;">= </span><b><span style="color: green; font-family: "Courier New"; font-size: 12.0pt; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES-MX;">"mensaje de error"</span></b><span style="font-family: 'Courier New'; font-size: 12pt;"><o:p></o:p></span></div>
<br /></div>
<code>
</code>
<div class="MsoNormal" style="background: white; margin-bottom: 0.0001pt;">
</div>
<code>
</code>Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-91403023292365460382015-03-12T13:36:00.000-06:002015-03-12T13:38:26.535-06:00Tips Spring Security Core Plugin 2.0 en Grails<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-vbel8nWdMMU/VQHouYtYNrI/AAAAAAAAAj0/sebjQlnD92U/s1600/tip.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-vbel8nWdMMU/VQHouYtYNrI/AAAAAAAAAj0/sebjQlnD92U/s1600/tip.jpg" height="310" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Durante las pruebas que realice después de la instalación del plugin me di cuenta de algunas cosas que dicho plugin incorpora en esta nueva versión, las cuales son:</div>
<br />
<b><br /></b>
<b>Error al poner directamente la URL para logout </b><br />
<div style="text-align: justify;">
Esto es porque ahora por defecto solo las peticiones POST pueden desencadenar un cierre de sesión, para permitir el cierre por acceso GET debemos agregar la siguiente línea a nuestro archivo "Config.groovy"</div>
<div style="text-align: justify;">
<br /></div>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 12pt;"><pre style="font-family: 'Courier New'; font-size: 12pt;">grails.plugin.springsecurity.logout.postOnly = <span style="color: #000043; font-weight: bold;">false</span></pre>
</pre>
<b><br /></b>
<b>Mensaje de error de Hibernate "Table "USUARIO_ROL" not found; SQL statement" </b><br />
<div style="text-align: justify;">
Según mencionan en StackOverflow es un bug que no causa ningún problema, <a href="http://stackoverflow.com/questions/23858953/grails-2-4-and-hibernate4-errors-with-run-app" rel="nofollow" target="_blank">aquí explican</a> como quitar el mensaje.</div>
<div style="text-align: justify;">
<br /></div>
<b><br /></b>
<b>Ahora el algoritmo de encriptación por default es: bcrypt.</b><br />
<div style="text-align: justify;">
De acuerdo a la documentación oficial este nuevo algoritmo proporciona mucha mas seguridad sin embargo podemos cambiarlo agregando la siguiente línea al archivo "Config.groovy"</div>
<div style="text-align: justify;">
<b><br /></b>
</div>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 12pt;">grails.plugin.springsecurity.password.algorithm=<span style="color: green; font-weight: bold;">'MD5'</span></pre>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 12pt;"><span style="color: green; font-weight: bold;">
</span></pre>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-4062344888483311952015-03-04T15:24:00.001-06:002015-03-05T17:38:49.282-06:00Configurar Spring Security Core Plugin 2.0 en Grails<br/>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-mn1wJNxFCrc/VPd3jsCd3KI/AAAAAAAAAjY/b0kEaZaq84g/s1600/spring.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-mn1wJNxFCrc/VPd3jsCd3KI/AAAAAAAAAjY/b0kEaZaq84g/s320/spring.PNG" /></a></div>
<br/>
<div style="text-align: justify;">
Existen tres formas de configurar el plugin de Spring Security: Annotation, RequestMap y IntercepUrlMap, en tutoriales anteriores describí la forma de hacerlo mediante RequestMap y en esta ocasión veremos como configurarlo mediante Anotaciones, además de que usaremos la versión 2.0 que nos proporciona un script que nos ayudará a crear nuestra configuración de manera rápida y casi automática, asumimos que tenemos un proyecto Grails recién creado, las versiones que utilice al momento de este tutorial son: Grails 2.4.4 y Java 1.7.
</div>
<a name='more'></a>
<br />
<br />
<b>Instalando el plugin de Spring Security </b>
<br />
<br />
<div style="text-align: justify;">
La manera más simple de instalar un plugin es mediante el comando: install-plugin “nombre plugin” en esta ocación también lo haremos manual y para ello nos vamos al archivo “grails-app/conf/BuildConfig” buscamos la sección de plugins y ponemos lo siguiente:
</div>
<br />
<pre class="brush:java">
plugins {
…
compile ':spring-security-core:2.0-RC4'
…
}
</pre>
<br />
<b>* </b>Esta es la manera más recomendable de instalar cualquier plugin o dependencia.
<br />
<br />
<br/>
<b>Configurando el plugin de Spring Security</b>
<br/>
<br/>
<div style="text-align: justify;">
Spring proporciona las configuraciones por default en el archivo: “DefaultSecurityConfig.groovy” todas ellas traen valores por default y se pueden sobreescribir directamente desde el archivo: “Config.groovy” por ahora no necesitamos mover nada para empezar.
</div>
<br />
<br />
<b>Dominios requeridos</b>
<br/>
<br/>
<div style="text-align: justify;">
Spring requeire ciertas clases de dominio, y es aquí donde vamos a utilizar el script que mencionaba al inicio, para crear estas clases basta con ejecutar:
</div>
<pre class="brush:java">
grails s2-quickstart “paquete” “nombreDominios”
</pre>
<br />
por ejemplo:
<pre class="brush:java">
grails s2-quickstart com.testapp.seguridad User Role
</pre>
<div style="text-align: justify;">
Con la instruccion anterior el script creará automáticamente tres clases de dominio: <b><i>User, Rol y UserRole</i></b> las cuales podemos modificar para adaptar a nuestras necesidades, para el ejemplo las dejaremos tal cual se generaron. También se realizan modificaciones en el archivo: “Config.groovy” agregando las siguientes líneas:
</div>
<br/>
<pre class="brush:java">
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.testapp.seguridad.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.testapp.seguridad.UserRole'
grails.plugin.springsecurity.authority.className = 'com.testapp.seguridad.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/': ['permitAll'],
'/index': ['permitAll'],
'/index.gsp': ['permitAll'],
'/assets/**': ['permitAll'],
'/**/js/**': ['permitAll'],
'/**/css/**': ['permitAll'],
'/**/images/**': ['permitAll'],
'/**/favicon.ico': ['permitAll']
]
</pre>
<br/>
<div style="text-align: justify;">
Nos podemos dar cuenta que únicamente se le indica a Spring la ubicación de nuestras clases requeridas y una configuración sencilla sobre los accesos a paginas default de nuestra aplicación.
</div>
<br/>
<br/>
<b>Agregando datos de ejemplo</b>
<br/>
<br/>
Por ahora vamos a poner datos de ejemplo en “BootStrap.groovy” en el cual agregaremos lo siguiente dentro de init:
<br/>
<pre class="brush:java">
def init = { servletContext ->
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
def testUser = new User(username: 'me', password: 'password')
testUser.save(flush: true)
UserRole.create testUser, adminRole, true
assert User.count() == 1
assert Role.count() == 2
assert UserRole.count() == 1
}
</pre>
<br/>
Simplemente estamos definiendo dos roles y un usuario, así como la relación entre el usuario y el rol administrador
<br/>
<br/>
<br/>
<b>Probando la configuración</b>
<br/>
<br/>
Para realizar esta prueba necesitaremos crear un controlador en el cual agregaremos dos métodos por ejemplo:
<br/>
<pre class="brush:java">
def sinSeguridad(){
println "entrando a sin seguridad..."
}
@Secured(['ROLE_ADMIN'])
def conSeguridad(){
println "entrando a la administración de usuarios.."
}
</pre>
<br/>
<div style="text-align: justify;">
Nótese que uno de los métodos esta anotado con “@Secured” que no es más que la anotación de Spring que nos permite realizar la configuración sobre que rol o roles tendrán acceso a ese método.
Después creamos sus respectivas páginas y lanzamos la aplicación, una vez que esté en funcionamiento tratamos de entrar a la página: “conSeguridad” desde la url correspondiente y notaremos que Spring nos envía automáticamente una pantalla simple de Login, sin poner datos cambiamos la url apuntando a la página “sinSeguridad” y podremos ver su contenido sin problemas, nuevamente regresamos a la url “conSeguridad” y ahora en la pantalla de Login pondremos los datos del usuario que previamente dimos de alta en el boostrap (me,password) y presionar el botón Login si las credenciales son correctas ya nos permitirá ver el contenido.
</div>Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-48701879980337770522013-11-27T18:31:00.000-06:002013-11-27T18:31:11.446-06:00Cambiar valores booleanos en la BD con CheckBox desde GrailsEn nuestro día a día como programadores muchas veces nos vamos a enfrentar a la situación de idear un mecanismo para encender o apagar una bandera de alguna tabla en nuestra base de datos, seguramente hay miles de ejemplos así que aquí les muestro mi solución implementada en Grails.
Lo único que necesitamos es un campo de tipo “Boolean” en alguna tabla de nuestra base de datos, en mi caso presento una tabla en pantalla con la información, a esta tabla le agregue una nueva columna donde aparece el checkBox, el código de dicha columna se verá más o menos así:
<pre class="brush:java">
<td><g:checkBox class="checkbox-entidad"
name="entidad" value="${entidad.id}"
checked="${entidad.campoBooleano}"
onchange="cambiarBooleano(this.value);"/> </td>
</pre>
En el código anterior podemos destacar solo tres atributos importantes el value en el cual le asignamos el id de nuestro dominio, checked este atributo va mapeado contra el campo booleano en la tabla esto con el fin de indicar cuales están marcados y cuales no y finalmente la invocación a la función “cambiarBooleano” en el evento onChange del checkBox y el parámetro que le enviamos es el id de la entidad seleccionada.
Lo que nos resta es invocar a una función remota desde JavaScript lo cual lo podemos lograr con el siguiente código:
<pre class="brush:java">
function cambiarBooleano(idEntidad){
<g:remoteFunction
controller="miController"
action="cambiarBooleano"
params="'idEntidad=' + idEntidad"/>
}
</pre>
En el bloque de código anterior solo hacemos una llamada al método cambiarBooleano definido en el controlador, y ahí es donde obtendremos el registro de la entidad y le cambiaremos el valor al campo booleano.
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-28271743752422416122013-09-11T19:11:00.000-05:002013-09-11T19:11:19.737-05:00Como activar el soporte para mapas en Android Virtual Device Manager<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En esta entrada les mostrare un dato curioso del cual no me había percatado pero que suele sernos muy útil a la hora de desarrollar con mapas, como todos ustedes saben uno de los requisitos para poder desarrollar para Android es contar con el SDK y este a su vez contiene el famoso Android Virtual Device Manager.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Creando un emulador</b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Como ya es bien sabido en la siguiente pantalla nos muestra las opciones con las cuales podemos configurar nuestro emulador.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-z1mXWBN1teU/UjEFKwW9QiI/AAAAAAAAAZE/Tvc2vH3hA5I/s1600/creando+el+emulador.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-z1mXWBN1teU/UjEFKwW9QiI/AAAAAAAAAZE/Tvc2vH3hA5I/s400/creando+el+emulador.PNG" width="238" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<a name='more'></a><br /><br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Tomando como ejemplo las opciones que se muestran en la imagen corremos nuestro emulador y una vez que esta en ejecución vamos a las aplicaciones instaladas en donde podemos ver una pantalla como la siguiente: </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vnnbBTvxKic/UjEFXgPCyAI/AAAAAAAAAZM/0NOI4iDI9nI/s1600/sin+soporte+para+mapas.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://3.bp.blogspot.com/-vnnbBTvxKic/UjEFXgPCyAI/AAAAAAAAAZM/0NOI4iDI9nI/s400/sin+soporte+para+mapas.PNG" width="246" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Como podemos ver no tenemos la aplicación de mapas por ningún lado, ahora activar este soporte es bastante sencillo lo que tenemos que hacer es detener el emulador e ir a editar la configuración únicamente tenemos que cambiar el campo Target por alguna de las opciones que inician con “Google API . . .” con esto damos guardar y lanzamos nuevamente nuestra aplicación de nuevo vamos a ver las aplicaciones instaladas y podemos ver que ahora aparece google maps.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-ttrPf0oNscs/UjEGf9ib-zI/AAAAAAAAAZY/cZTtnX_cPNQ/s1600/con+soporte+para+mapas.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-ttrPf0oNscs/UjEGf9ib-zI/AAAAAAAAAZY/cZTtnX_cPNQ/s400/con+soporte+para+mapas.PNG" width="251" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-36353107584619798802013-09-05T15:03:00.000-05:002013-09-05T15:03:17.967-05:00Subiendo una aplicación Grails a Cloud Foundry parte 1<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Muchas de las veces cuando terminamos una pequeña aplicación por pequeña que parezca tenemos el deseo de enseñársela (presumirla) al mundo, y en el caso de las aplicaciones hechas con tecnología Grails es un poco difícil encontrar un servidor gratuito que nos permita hacerlo, sin embargo, no es difícil ya que sí existen algunos PaaS como son Heroku, GAE, CloudFoundry, Jelastic entre otros. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En esta ocasión hablaremos un poco acerca de Cloud Foundry la cual se define así misma como: </div>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq">
The open platform as a service providing a faster and easier way to build, test, deploy and scale applications. </blockquote>
<div style="text-align: justify;">
</div>
<a name='more'></a><br /><br />
<div style="text-align: justify;">
Que traducido sería algo como: Plataforma abierta como un servicio que proporciona una manera mas fácil y mas rápida de construir, probar, implementar y escalar aplicaciones. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En este pequeño tutorial mostraremos la forma de deployar una aplicación Grails utilizando la base de datos que genera en memoria para dar paso a otro tutorial donde indicaremos como hacerlo con alguna base de datos externa pues la finalidad de esta entrada es únicamente tener nuestra aplicación funcionando.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>¿Qué necesitamos? </b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Tener una cuenta en Cloud Foundry (hay unas de prueba de 60 días y 2GB de memoria.)</div>
<div style="text-align: justify;">
Tener una aplicación Grails la cual queramos deployar para probar o presumir a nuestros cuates </div>
<div style="text-align: justify;">
Las ganas de querer hacerlo </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Creando nuestra cuenta en Cloud Foundry </b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Para registrar una nueva cuenta vamos a la siguiente dirección http://cloudfoundry.com/ ahí picamos el gran botón entre naranja y rojo que dice “Free trial” el cual nos envía a un formulario donde nos pide únicamente nuestro correo y un código de invitación (el codigo es opcional) y finalmente el presionamos el botón “CREATE AN ACCOUNT” para recibir la siguiente pantalla. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ptLonGUy3Oo/UijjE8ZOiKI/AAAAAAAAAYs/Hmb5YgZ4M3w/s1600/registro.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="http://3.bp.blogspot.com/-ptLonGUy3Oo/UijjE8ZOiKI/AAAAAAAAAYs/Hmb5YgZ4M3w/s320/registro.PNG" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Después nos llegara un correo con el siguiente texto:
You have been placed on a waiting list for an account on Pivotal CF. We will email you when your account is ready.
Así que no se preocupen pronto recibiremos un nuevo correo con nuestra nueva cuenta esto tarda mas o menos una o dos semanas.
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Vamos a dejar hasta aquí esta parte pues necesitamos la cuenta para iniciar con la configuración y carga de nuestra aplicación, comenten si les gusto.</div>
<div style="text-align: justify;">
<br /></div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-82178023373425083592013-08-26T13:51:00.000-05:002013-08-27T12:54:19.771-05:00Dividiendo una lista en sub listas Groovy
Hay ocasiones en las que nos encontramos con la necesidad de divir una lista en varias sub listas, recién me acaba de pasar y les comparto mi implementación:
<pre class="brush:java">
/*obtener solo 2000 elementos por vez*/
def subListas=[]
def i=0
def inicial = 0
def final= 1999
while(miListota.size()>20000){
subListas[i]=new LinkedList(miListota.subList(inicial, final))
miListota.removeAll(subListas[i])
i++
}
//agregamos el resto de la lista a una nueva posición
subListas[i]= new LinkedList(miListota)
</pre>
Un compañero me sugirió este método que hace totalmente lo mismo pero sin la necesidad de quebrarnos la cabeza para implementarlo.
<pre class="brush:java">
miListota.collate(2000)
</pre>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-88378654849318106392013-07-30T10:42:00.000-05:002013-07-30T10:42:42.175-05:00Instalar y configurar Spring Security en Grails parte 2Esta es la continuación para terminar de configurar Spring Security en Grails, <a href="http://paraisodeldesarrollador.blogspot.mx/2013/06/instalar-y-configurar-spring-security.html">acá la primera parte</a><br />
<br />
Para finalizar la configuración solo nos resta agregar los permisos a la base de datos (en un post anterior muestro como agregar datos a la BD cada vez que se carga nuestra aplicación, para esta parte nos va a ser muy útil) pongamos lo siguiente en el archivo catalogos.sql en el orden en que los pongo aquí mismo:
<br />
<br />
<b>Primero necesitamos definir que roles tendrá nuestro sistema en este ejemplo solo habrá dos: Administrador y Usuarios</b>
<br />
<b><br /></b>
<pre class="brush:sql">insert into rol (id, version, authority ) values (1, 0, 'ROLE_ADMINISTRADOR');
insert into rol (id, version, authority ) values (2, 0, 'ROLE_USUARIO');
</pre>
<br />
<br />
<b>Insertamos los usuarios de ejemplo </b><br />
<b><br /></b>
<pre class="brush:sql">insert into usuario (id, version, username, "password", enabled, account_expired, account_locked, password_expired, nombre, apellido_paterno, apellido_materno, email, fecha_alta) values (1, 0, 'administrador', '5f4dcc3b5aa765d61d8327deb882cf99', 1, 0, 0, 0, 'Administrador', 'del', 'Sistema', 'administrador@example.com', current_timestamp);
insert into usuario (id, version, username, "password", enabled, account_expired, account_locked, password_expired, nombre, apellido_paterno, apellido_materno, email, fecha_alta) values (2, 0, 'usuario', '5f4dcc3b5aa765d61d8327deb882cf99', 1, 0, 0, 0, 'usuario', 'del', 'Sistema', 'usuario@example.com', current_timestamp);
</pre>
<br />
<b></b><br />
<a name='more'></a><b><br /></b><br />
<b>Hacemos la relación entre el rol y el usuario </b><br />
<b><br /></b>
<pre class="brush:sql">insert into usuario_rol ( rol_id , usuario_id ) values (1,1)
insert into usuario_rol ( rol_id , usuario_id ) values (2,2)
</pre>
<br />
<br />
<b>Finalmente agregamos los permisos</b><br />
<br />
<pre class="brush:sql">insert into requestmap (id, version, url, config_attribute) values (1, 0, '/admin/dbconsole/**', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (2, 0, '/js/**', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (3, 0, '/css/**', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (4, 0, '/images/**', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (5, 0, '/login/**', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (6, 0, '/logout/**', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (7, 0, '/', 'IS_AUTHENTICATED_ANONYMOUSLY');
insert into requestmap (id, version, url, config_attribute) values (8, 0, '/*', 'IS_AUTHENTICATED_FULLY');
insert into requestmap (id, version, url, config_attribute) values (9, 0, '/usuario/**', 'ROLE_ADMINISTRADOR');
</pre>
<pre class="brush:sql">
</pre>
<pre class="brush:sql">
</pre>
<b>Los controladores:</b>
Una vez que terminamos con las configuraciones es necesario crear los controladores que son la puerta de entrada y salida a nuestra aplicación:
<br />
<br />
<br />
<b>LoginController</b>
<br />
<b><br /></b>
<pre class="brush:java">class LoginController {
/**
* Dependency injection for the authenticationTrustResolver.
*/
def authenticationTrustResolver
/**
* Dependency injection for the springSecurityService.
*/
def springSecurityService
def loginService
/**
* Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
*/
def index = {
if (springSecurityService.isLoggedIn()) {
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
}
else {
redirect action: 'auth', params: params
}
}
/**
* Show the login page.
*/
def auth = {
println "llega aqui primero"
def config = SpringSecurityUtils.securityConfig
println "verificar si esta loggeado " + springSecurityService.isLoggedIn()
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String view = 'login'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
/**
* The redirect action for Ajax requests.
*/
def authAjax = {
response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
response.sendError HttpServletResponse.SC_UNAUTHORIZED
}
/**
* Show denied page.
*/
def denied = {
if (springSecurityService.isLoggedIn() &&
authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
// have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
redirect action: 'full', params: params
}
}
/**
* Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
*/
def full = {
def config = SpringSecurityUtils.securityConfig
render view: 'index', params: params,
model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
}
/**
* Callback after a failed login. Redirects to the auth page with a warning message.
*/
def authfail = {
def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
String msg = ''
def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
if (exception) {
if (exception instanceof AccountExpiredException) {
msg = g.message(code: "springSecurity.errors.login.expired")
}
else if (exception instanceof CredentialsExpiredException) {
msg = g.message(code: "springSecurity.errors.login.passwordExpired")
}
else if (exception instanceof DisabledException) {
msg = g.message(code: "springSecurity.errors.login.disabled")
}
else if (exception instanceof LockedException) {
msg = g.message(code: "springSecurity.errors.login.locked")
}
else {
msg = g.message(code: "springSecurity.errors.login.fail")
}
}
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
}
else {
flash.message = msg
redirect action: 'auth', params: params
}
}
/**
* The Ajax success redirect url.
*/
def ajaxSuccess = {
render([success: true, username: springSecurityService.authentication.name] as JSON)
}
/**
* The Ajax denied redirect url.
*/
def ajaxDenied = {
render([error: 'access denied'] as JSON)
}
def errorAcceso = {
def model = [:]
return new ModelAndView("/login/Recuperar", model)
}
}
</pre>
<br />
<b><br /></b>
<b>LogoutController</b>
<br />
<b><br /></b>
<pre class="brush:java">class LogoutController {
/**
* Index action. Redirects to the Spring security logout uri.
*/
def index = {
redirect uri: SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
}
}
</pre>
<br />
<br />
Con esto únicamente nos resta crear la pantalla de login que servirá como entrada a nuestra aplicación
<br />
<br />
<b>Pantalla de login </b>
<br />
<b><br /></b>
Por cuestiones de mala interpretación del plugin con respecto al html solo pondré lo que va en el body de nuestra gsp
<br />
<pre class="brush:java"><div class="hero-unit">
<g:if test="${flash.message}">
</g:if><br />
<div class="alert alert-info">
${flash.message}</div>
<br />
<form action="${postUrl}" autocomplete="off" id="loginForm" method="POST">
<legend><g:message code="aplicacion.ingresar"></g:message></legend>
<br />
<div class="control-group">
<label class="control-label" for="username"><g:message code="aplicacion.usuario">:</g:message></label>
<br />
<div class="controls">
<input id="username" name="j_username" placeholder="Usuario" type="text" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="password"><g:message code="aplicacion.password">:</g:message></label>
<br />
<div class="controls">
<input id="password" name="j_password" placeholder="Contraseña" type="password" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-primary" id="submit" type="submit"><g:message code="aplicacion.ingresar"></g:message></button>
</div>
</div>
</form>
</div>
</pre>
<br />
<br />
Listo!!! ahora solo ejecutamos nuestra aplicación y probamos que todo funcione, sí tienen dudas dejen un comentario.Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com1tag:blogger.com,1999:blog-4302395541175621439.post-26509758868913577242013-07-25T12:43:00.001-05:002013-07-25T12:43:59.455-05:00¿Como usar el Debug en Eclipse? <br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/lFLFxVUUD74?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
<br />
<br />
<div style="text-align: justify;">
Actualmente me he dado cuenta que Eclipse es el IDE por excelencia de muchos desarrolladores, el cual cuenta con muchas herramientas ya preinstaladas para su integración con la mayoría de tecnologías existentes y sino se pueden agregar plugis de manera muy simple, en este video demostramos el uso del Debug que es una herramienta muy útil a la hora de buscar errores o simplemente probar el flujo de nuestro código y como muchos no saben usarlo aquí esta un video demostrativo del poder de esta herramienta. </div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-10473742802519512552013-07-17T16:38:00.000-05:002013-07-17T16:38:07.006-05:00Conociendo más a fondo el Blog hecho en Grails llamado Anelisse<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">En esta ocasión me he dado a la tarea de redactar esta
pequeña entrada para seguir dando a conocer mi proyecto iniciando desde el
primer post con lo mas general el cual pueden encontrar en “</span><a href="http://www.javamexico.org/blogs/shadonwk/un_blog_hecho_en_grails_asi_es_y_se_llama_anelisse"><span style="background: rgb(238, 238, 238); color: #6191c5; font-family: "Verdana","sans-serif"; font-size: 10pt; line-height: 115%;">Un Blog hecho en Grails? así es y se llama
Anelisse</span></a><span style="font-family: Calibri;">” para los que no sepan de que se trata les recomiendo
seguir el enlace y después regresar.<o:p></o:p></span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><strong>Página principal de Anelisse</strong></span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-t6V6nV6YlKc/UecKiV1eI5I/AAAAAAAAAWA/AaBN0n1_SbU/s1600/Anelisse+index.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="190" src="http://2.bp.blogspot.com/-t6V6nV6YlKc/UecKiV1eI5I/AAAAAAAAAWA/AaBN0n1_SbU/s400/Anelisse+index.PNG" width="400" /></a></div>
<br />
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">Esta es la página inicial y puede ser usada para mostrar
contenido estático como por ejemplo los datos más importantes de alguna
empresa, o contenido dinámico como pueden ser los post más votados o aquellos
seleccionados por el administrador.<o:p></o:p></span></div>
<div style="text-align: justify;">
<a name='more'></a><br />
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><strong>Blogs<o:p></o:p></strong></span></div>
<div style="text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-QaKN_wzsDc0/UecKmrwK7WI/AAAAAAAAAWY/U7Lz1yrjjzk/s1600/Anelisse+blogs.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="http://3.bp.blogspot.com/-QaKN_wzsDc0/UecKmrwK7WI/AAAAAAAAAWY/U7Lz1yrjjzk/s400/Anelisse+blogs.PNG" width="400" /></a></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">En el menú blogs, podemos ver la lista de las entradas
ordenadas de la más reciente a la más antigua cada ítem de esta lista cuenta
con el título de la entrada, el usuario que la creo, la fecha y la categoría así
como una breve descripción o resumen de la entrada y finalmente al pie se
encuentran datos estadísticos como son: número de comentarios, número de
lecturas, número de votos y un link para leer la entrada completa.<o:p></o:p></span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><strong>Entrada individual</strong></span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"></span> </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-VtCevy-9oME/UecKi1XB9dI/AAAAAAAAAWM/c5BMNzx0zTg/s1600/Anelisse+entrada+individual.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="203" src="http://3.bp.blogspot.com/-VtCevy-9oME/UecKi1XB9dI/AAAAAAAAAWM/c5BMNzx0zTg/s400/Anelisse+entrada+individual.PNG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: Calibri;"><o:p></o:p></span> </div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">En las entradas individuales se muestra el título de la
entrada seguido del usuario que la creo, la fecha y la categoría seguido del
cuerpo completo de la entrada y al final como pie se muestra el número de
lecturas y el número de votos en esta sección falta implementar algo muy
parecido al +1 de google que tendrá la función de incrementar el número de
votos, (únicamente se tiene considerado dar votos positivos aunque esto podría
cambiar) inmediatamente después viene la sección de comentarios donde se
muestra la lista de comentarios ordenados por el más reciente y finalmente si
estas logueado con tu usuario aparece la sección que te permite agregar un
nuevo comentario.<o:p></o:p></span></div>
<div style="text-align: justify;">
<o:p><span style="font-family: Calibri;"> </span></o:p></div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><strong>Comentarios</strong></span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"></span> </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-YeUET-efGeE/UecKgI1mO0I/AAAAAAAAAV8/rrpUip-QsJ0/s1600/Anelisse+comentarios.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="http://2.bp.blogspot.com/-YeUET-efGeE/UecKgI1mO0I/AAAAAAAAAV8/rrpUip-QsJ0/s400/Anelisse+comentarios.PNG" width="400" /></a></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">En la sección de comentarios se despliega la lista iniciando
por el ultimo comentario agregado el cual consta del título del comentario<span style="mso-spacerun: yes;"> </span>seguido del usuario que lo crea y la fecha, después
viene el cuerpo del comentario algo que falta implementar aquí es la misma
sección de votación que funcionara de la misma manera que los votos para las
entradas, otros usuarios pueden darle +1 al comentario si les gusta lo que
incrementará su número de votos haciendo que el usuario incremente su nivel de
reputación.<o:p></o:p></span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><strong>Nueva cuenta de usuario</strong></span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"></span> </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-PMm6p7L4I-4/UecKj_U6S0I/AAAAAAAAAWU/0tEyMwshcN4/s1600/Anelisse+nuevo+usuario.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="http://2.bp.blogspot.com/-PMm6p7L4I-4/UecKj_U6S0I/AAAAAAAAAWU/0tEyMwshcN4/s400/Anelisse+nuevo+usuario.PNG" width="400" /></a></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><o:p></o:p></span> </div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">En la pantalla de login tenemos la liga para crear una nueva
cuenta de usuario la cual nos permitirá entre otras cosas tener nuestro propio
blog para que podamos publicar entradas y aparezcan con nuestro nombre como
autor, para ello solo debemos proporcionar nombre de usuario, elegir una
contraseña y proporcionar una dirección de correo electrónico (la cual va a
servir para verificar la cuenta y recuperación de la contraseña funcionalidades
no implementadas en este punto).<o:p></o:p></span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;"><strong>Lista de usuarios<o:p></o:p></strong></span></div>
<div style="text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-qHTEzOw2PlY/UecONX1B_2I/AAAAAAAAAWo/p_bR4_WRYK4/s1600/Anelisse+usuarios.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="183" src="http://4.bp.blogspot.com/-qHTEzOw2PlY/UecONX1B_2I/AAAAAAAAAWo/p_bR4_WRYK4/s400/Anelisse+usuarios.PNG" width="400" /></a></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">En esta lista podemos ver los usuarios registrados en el
sitio en un ítem compuesto por una imagen de perfil(se carga una por default
pero el usuario puede cambiarla en los ajustes de su cuenta) debajo su nombre
de usuario y a un lado el nivel de reputación con el que cuenta cada usuario.<o:p></o:p></span></div>
<div style="text-align: justify;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt; text-align: justify;">
<span style="font-family: Calibri;">Aún le falta mucho trabajo y hay muchas cosas por pulir,
pero sin duda creo que va caminando bien, así que espero sus comentarios y si
alguien quiere contribuir esta es la dirección del repo en git : </span><a href="https://github.com/Shadonwk/Blog"><span style="color: blue; font-family: Calibri;">https://github.com/Shadonwk/Blog</span></a><o:p></o:p></div>
<div style="text-align: justify;">
</div>
</div>
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com0tag:blogger.com,1999:blog-4302395541175621439.post-45127586793982978262013-06-25T18:20:00.002-05:002013-06-25T18:20:17.681-05:00Instalar y configurar Spring Security en Grails parte 1<br />
En este tutorial aprenderemos a instalar y configurar el plugin de Spring Security para Grails y poder usarlo de manera adecuada en nuestros proyectos, agradeciendo la colaboración de Miguel Coba por las dudas resueltas :D<br />
<br />
<br />
<strong>Instalando el plugin de Spring Security</strong>
<br />
<br />
Para realizar la instalación del plugin (asumimos que ya tenemos un proyecto grails) simplemente necesitamos ejecutar el siguiente comando desde nuestro IDE favorito o bien desde la línea de comandos con Grails.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-zDasckvJ3MA/UcnwfjWrRMI/AAAAAAAAAVc/0WgDlucWA_o/s1600/instalando+spring.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="http://1.bp.blogspot.com/-zDasckvJ3MA/UcnwfjWrRMI/AAAAAAAAAVc/0WgDlucWA_o/s320/instalando+spring.PNG" width="320" /></a></div>
<br />
<br />
<br />
<strong>Configurando el plugin de Spring Security</strong><br />
<strong></strong><a name='more'></a><br />
<strong><o:p></o:p></strong>
Para realizar la configuración de como spring security
define las reglas de accesos existen varias formas de realizarlo, en este
tutorial veremos la configuración por Requestmap almacenados en la base de
datos (las otras opciones son: por anotaciones y por un mapa definido en
Config.groovy <a href="http://grails-plugins.github.io/grails-spring-security-core/docs/manual/"><span style="color: blue; font-family: Calibri;">http://grails-plugins.github.io/grails-spring-security-core/docs/manual/</span></a>lo primero que debemos realizar es la creación de algunos dominios que son
requeridos por el plugin estos son: Usuario, Rol, Requestmap y UsuarioRol.
<br />
<br />
<strong>Usuario:</strong>
<br />
<pre class="brush:java">
class Usuario {
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
String nombre
String apellidoPaterno
String apellidoMaterno
String email
Date fechaAlta
static constraints = {
username(blank: false, unique: true)
password(blank: false)
nombre(blank: false, size: 2..100)
apellidoPaterno(blank: false, size: 2..50)
apellidoMaterno(blank: false, size: 2..50)
email(email: true, blank: false)
fechaAlta()
}
static mapping = {
password column: '`password`'
}
Set<rol> getAuthorities() {
UsuarioRol.findAllByUsuario(this).collect { it.rol } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService?.encodePassword(password)
}
}
</pre>
<strong></strong><br />
<strong>Rol:</strong>
<br />
<pre class="brush:java">class Rol {
String authority
static mapping = {
cache true
}
static constraints = {
authority blank: false, unique: true
}
}
</pre>
<strong></strong><br />
<strong>UsuarioRol:</strong>
<br />
<pre class="brush:java">
import org.apache.commons.lang.builder.HashCodeBuilder
class UsuarioRol implements Serializable {
Usuario usuario
Rol rol
boolean equals(other) {
if (!(other instanceof UsuarioRol)) {
return false
}
other.usuario?.id == usuario?.id &&
other.rol?.id == rol?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (usuario) builder.append(usuario.id)
if (rol) builder.append(rol.id)
builder.toHashCode()
}
static UsuarioRol get(long usuarioId, long rolId) {
find 'from UsuarioRol where usuario.id=:usuarioId and rol.id=:rolId',
[usuarioId: usuarioId, rolId: rolId]
}
static UsuarioRol create(Usuario usuario, Rol rol, boolean flush = false) {
new UsuarioRol(usuario: usuario, rol: rol).save(flush: flush, insert: true)
}
static boolean remove(Usuario usuario, Rol rol, boolean flush = false) {
UsuarioRol instance = UsuarioRol.findByUsuarioAndRol(usuario, rol)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(Usuario usuario) {
if(usuario.id)
executeUpdate 'DELETE FROM UsuarioRol WHERE usuario=:usuario', [usuario: usuario]
}
static void removeAll(Rol rol) {
executeUpdate 'DELETE FROM UsuarioRol WHERE rol=:rol', [rol: rol]
}
static mapping = {
id composite: ['rol', 'usuario']
version false
}
}
</pre>
<strong></strong><br />
<strong>RequestMap:</strong>
<br />
<pre class="brush:java">
class Requestmap {
String url
String configAttribute
static mapping = {
cache true
}
static constraints = {
url blank: false, unique: true
configAttribute blank: false
}
}
</pre>
Lo siguiente que tenemos que hacer es realizar algunas configuraciones en Config.groovy primero que nada indicándole el algoritmo que utilizara spring security para la encriptación de los passwords para ello basta con indicar la siguiente línea donde le indicamos que use MD5:
<br />
<br />
<pre class="brush:java">
grails.plugins.springsecurity.password.algorithm='MD5'
</pre>
<div class="brush:java">
</div>
No pensé que se hiciera demasiado grande el tutorial por lo cual dejamos hasta aquí la primera parte continuando con la inserción de los querys requeridos y las pantallas de login en la siguiente parte, espero les sea de ayuda.
Shadonwkhttp://www.blogger.com/profile/06128702580802035181noreply@blogger.com2