<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>3f blog</title>
	<atom:link href="http://blog.soluciones3f.com.ar/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.soluciones3f.com.ar</link>
	<description>Experiencias compartidas</description>
	<lastBuildDate>Thu, 19 Apr 2012 00:32:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Como cambiar el puerto default en que se ejecuta una aplicacion de grails.</title>
		<link>http://blog.soluciones3f.com.ar/2012/04/18/como-cambiar-el-puerto-default-en-que-se-ejecuta-una-aplicacion-de-grails/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/04/18/como-cambiar-el-puerto-default-en-que-se-ejecuta-una-aplicacion-de-grails/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 00:32:55 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[buildconfig]]></category>
		<category><![CDATA[convention]]></category>
		<category><![CDATA[default]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[run-app]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=861</guid>
		<description><![CDATA[Simple&#8230; estoy desarrollando dos aplicaciones en grails que necesito ejecutar simultáneamente. Por default, grails utiliza el puerto 8080 para todas las aplicaciones, entonces no se pueden tener dos aplicaciones a la vez si no se le cambia el puerto a una de ellas. Hasta hoy, utilizaba un comando al estilo grails -Dserver.port=8081 run-app pero siempre [...]]]></description>
			<content:encoded><![CDATA[<p>Simple&#8230; estoy desarrollando dos aplicaciones en grails que necesito ejecutar simultáneamente.</p>
<p>Por default, grails utiliza el puerto 8080 para todas las aplicaciones, entonces no se pueden tener dos aplicaciones a la vez si no se le cambia el puerto a una de ellas.</p>
<p>Hasta hoy, utilizaba un comando al estilo <code>grails -Dserver.port=8081 run-app</code> pero siempre me olvidaba de agregar esos parámetros&#8230;  en fin quería buscar una solución más práctica.</p>
<p>Aunque no lo encontré por ningún lado en la documentación de grails, gracias a google encontré que desde alguna versión bastante vieja, no se cual, también se pueden agregar al BuildConfig.groovy la siguiente linea:</p>
<p><code>grails.server.port.http = 8081</code></p>
<p>Funciona a la perfección en grails 2.0.1 (y al menos a partir de grails 1.3.0 debería funcionar)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/04/18/como-cambiar-el-puerto-default-en-que-se-ejecuta-una-aplicacion-de-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google como calendario por defecto usando gnome-shell</title>
		<link>http://blog.soluciones3f.com.ar/2012/04/15/google-como-calendario-por-defecto-usando-gnome-shell/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/04/15/google-como-calendario-por-defecto-usando-gnome-shell/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 18:39:51 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Sin categoría]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=855</guid>
		<description><![CDATA[Lo que quiero es que los eventos creados en google calendar, aparezcan en el calendario de gnome-shell sin utilizar thunderbird o evolution. Encontré un pequeño script de python que hace justo lo que deseo: https://github.com/vintitres/gnome-shell-google-calendar Primero hay que bajarlo y descompactarlo, (o clonarlo si se sabe que significa) Luego para ejecutarlo hay que tener algunas [...]]]></description>
			<content:encoded><![CDATA[<p>Lo que quiero es que los eventos creados en google calendar, aparezcan en el calendario de gnome-shell sin utilizar thunderbird o evolution.</p>
<p>Encontré un pequeño script de python que hace justo lo que deseo: https://github.com/vintitres/gnome-shell-google-calendar</p>
<p>Primero hay que bajarlo y descompactarlo, (o clonarlo si se sabe que significa)<br />
Luego para ejecutarlo hay que tener algunas dependencias de python instaladas. En mi instalación solo debí ejecutar</p>
<pre class="brush: plain; title: ; notranslate">
sudo apt-get install python-gdata python-iso8601
</pre>
<p>En la página del script figuran otras dependencias pero yo ya las tenía instaladas&#8230;. a saber python-gtk, python-dbug y python-gnomekeyring</p>
<p>Luego se ejecuta el script con ./gnome-shell-google-calendar y listo. Luego de un rato si se accede al calendario se verán los eventos definidos en google calendar.</p>
<p>Lamentablemente si cerramos la ventana o reiniciamos el computador, esto se pierde y hay que volver a ejecutar la aplicación. Por esto la agregué a la lista de aplicaciones a ejecutar al iniciar.</p>
<p>Luego de tener esto, lo único que falta arreglar es el botón de <em>abrir calendario</em> que sin importar como configurase las aplicaciones, siempre intentaba abrir evolution el cual ni siquiera esta instalado.</p>
<p>También googleando encontré la solución más simple: http://askubuntu.com/questions/69349/how-to-change-gnome-shell-calendar-default-application</p>
<p>La unica diferencia, es que yo use firefox para abrir el calendario. Entonces el comando que debí ejecutar es:  </p>
<pre class="brush: plain; title: ; notranslate">
gsettings set org.gnome.desktop.default-applications.office.calendar exec &quot;firefox 'https://www.google.com/calendar'&quot;
</pre>
<p>supongo que si se quiere usar el explorador por default se puede usar el comando: </p>
<pre class="brush: plain; title: ; notranslate">
gsettings set org.gnome.desktop.default-applications.office.calendar exec &quot;/usr/bin/x-www-browser 'https://www.google.com/calendar'&quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/04/15/google-como-calendario-por-defecto-usando-gnome-shell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efectos de la manipulación de metaClass en Groovy / Grails</title>
		<link>http://blog.soluciones3f.com.ar/2012/03/25/efectos-de-la-manipulacion-de-metaclass-en-groovy-grails/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/03/25/efectos-de-la-manipulacion-de-metaclass-en-groovy-grails/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 01:39:22 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[closure]]></category>
		<category><![CDATA[dynamic language]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[integration testing]]></category>
		<category><![CDATA[metaclass]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[unit]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=820</guid>
		<description><![CDATA[Haciendo unas pruebas unitarias en grails me encontré con un comportamiento de Groovy que desconocía. Desde la versión de Groovy 1.6 se puede manipular el metaclass de una instancia (al menos fácilmente) además de hacerlo para toda la clase como es costumbre. Para realizar un test, debía agregar por metaClass dos métodos, uno sobre la [...]]]></description>
			<content:encoded><![CDATA[<p><center><a href="http://groovy.codehaus.org/" target="_blank"><img src="http://groovy.codehaus.org/images/groovy-logo-medium.png" alt="Groovy Logo" width="400" /></a></center></p>
<p>Haciendo unas pruebas unitarias en grails me encontré con un comportamiento de Groovy que desconocía.</p>
<p>Desde la versión de Groovy 1.6 se puede manipular el metaclass de una instancia (al menos fácilmente) además de hacerlo para toda la clase como es costumbre.</p>
<p>Para realizar un test, debía agregar por metaClass dos métodos, uno sobre la clase y otro sobre una instancia particular de dicha clase.</p>
<p>Misteriosamente para mi, al ejecutar el test, me decía que el método que agregaba a la clase no existía. Entonces escribí el siguiente caso de prueba para entender que era lo que estaba pasando</p>
<pre class="brush: groovy; highlight: [6,7]; title: ; notranslate">
class MyTestClass {
}

def myTestInstance = new MyTestClass()

myTestInstance.metaClass.testInstanceMethod = { true }
MyTestClass.metaClass.testClassMethod = { true }

assert myTestInstance.testInstanceMethod() == true, &quot;La instancia tiene el método declarado en el metaClass de la instancia&quot;
assert myTestInstance.testClassMethod() == true, &quot;La instancia tiene el método declarado en el metaClass de la clase&quot;
</pre>
<p>A simple vista este test pareciera funcionar. Agrego a la instancia un método, luego le agrego a la clase otro método y luego testeo que esos métodos existan y que retornen true.</p>
<p>Para mi sorpresa, al ejecutar este script, el resultado fue </p>
<pre class="brush: plain; title: ; notranslate">
groovy.lang.MissingMethodException: No signature of method: MyTestClass.testClassMethod() is applicable for argument types: () values: []
Possible solutions: testClassMethod(), testClassMethod(java.lang.Object)
</pre>
<p>Investigando encontré que si invertía el orden de las líneas 06 y 07, que se encuentran resaltadas en el script anterior, se solucionaban todos los problemas y funcionaba como se esperaba el test.</p>
<p><strong>¿Qué supongo que está sucediendo?</strong></p>
<p>Cuando se modifica el metaclass de una instancia, se copia el estado actual del metaclass de la clase a la que dicha instancia pertenece y se modifica esta copia que queda como una copia privada de la instancia y sin relación con la metaclass de la partió.</p>
<p>Por lo tanto, luego, cuando se modifica el metaclass de la clase, agregándole un nuevo método, este cambio no se ve reflejado en las instancias que previamente fueron modificadas.</p>
<p><strong><u>Moraleja</u>:</strong> siempre modificar el metaclass de las clases primero y luego, cuando ya no quedan modificaciones a nivel clase, se pueden hacer las modificaciones a nivel instancia.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/03/25/efectos-de-la-manipulacion-de-metaclass-en-groovy-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seguridad en sitios web&#8230; o como Oracle apesta</title>
		<link>http://blog.soluciones3f.com.ar/2012/03/11/seguridad-en-sitios-web-o-como-oracle-apesta/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/03/11/seguridad-en-sitios-web-o-como-oracle-apesta/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 18:55:51 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[sociedad]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=814</guid>
		<description><![CDATA[Bueno, antes que nada aviso que estoy muy enojado, asi que no esperen un post educativo o tranquilo. Aviso también que no hablaré sobre bases de datos Oracle (que también apestan por motivos diferentes según mi criterio) sino sobre las contraseñas que nos obligan a poner en páginas webs. Continuamente en diarios, televisión, comentarios de [...]]]></description>
			<content:encoded><![CDATA[<p>Bueno, antes que nada aviso que estoy muy enojado, asi que no esperen un post educativo o tranquilo.</p>
<p>Aviso también que no hablaré sobre bases de datos Oracle (que también apestan por motivos diferentes según mi criterio) sino sobre las contraseñas que nos obligan a poner en páginas webs.</p>
<p>Continuamente en diarios, televisión, comentarios de amigos, spam de antivirus, emails, radio, conocimiento popular, me dijo un amigo de un amigo de un primo, etc que con solo conectarte a internet podes desde contagiarte hepatitis a, hasta que te roben la tarjeta de crédito, te hipotequen la casa y quedes en la ruina&#8230;. sin haber presionado si quiera una tecla. </p>
<p>Es verdad, estoy exagerando un poco, pero muchísimas personas tienen paranoia con la seguridad. Si tan solo se supiera que con un poco de conocimiento y buenas prácticas se les acabaría el negocio a tanta basura pseudo llamada antivirus que esta dando vueltas por ahí..</p>
<p>Pero lo que me molesta en este momento es que me obliguen a tener cuidado con la seguridad en sitios que no lo merecen!</p>
<p>Por ejemplo, que en el banco me obliguen a poner una clave alfanumérica de al menos 8 dígitos, que tenga que cambiarla cada 3 meses y en cada operación deba además escribir un código que saco por una tarjeta de coordenadas&#8230; bueno&#8230; podría decirse que es un banco, debe tener la mayor seguridad del mundo.</p>
<p>En mi opinión NO ! Es uno el que debe darle el valor de seguridad a cada sitio en particular sin que el sitio te lo tenga que venir a imponer tan alegremente hasta el punto de ser inutilizable. Por ejemplo, sin ir mas lejos, a mi me parece más importante tener asegurada la contraseña de mi correo electrónico que la del homebanking&#8230; si total necesito una tarjeta de coordenadas que es un medio físico para hacer cualquier operación que involucre dinero.</p>
<p>Pero esa es mi opinión. Incluso no es lo que me molesta, lo que en verdad me enerva es que sitios totalmente inconsecuentes tengan esa misma política.</p>
<p>Hoy necesitaba bajar el Oracle Java Development Kit 6, y para bajarlo era obligatorio registrarme en la pagina web de Oracle! ya vamos mal&#8230; para que quiero registrarme en ese sitio? para que me llenen aún más de spam?</p>
<p>Pero no termina ahí. Ya estaba registrado (no es la primera vez que necesito descargar un jdk) pero no recordaba la clave&#8230; probé todas las claves habituales.. y nada..  así que debí seguir el procedimiento de recuperación de contraseña.</p>
<p>Lo bueno es que esto fue rápido&#8230; pero cuando quería cambiar la que me habían asignado totalmente in-memorizable por la que yo tenía ganas&#8230; que sorpresa la mía que me obligaran a poner una clave que contenga letras <strong>y números</strong> y además al menos <strong>una letra mayúscula y una minúscula</strong>. Menos mal que no obligaron a poner caracteres no alfanuméricos ! Creo que eso se les pasó, no me extrañaría que pronto deba hacerlo.</p>
<p>Y todo esto para que.. para descargar una aplicación que antes de que Oracle comprara la empresa por unos servidores, se la podía descargar gratuitamente y sin registración !</p>
<p>Oracle no es la única que tiene esta política totalmente estúpida con respecto a la complejidad de contraseñas. Esta plagado de sitios así&#8230; Todo bien con que avisen que la contraseña que estoy ingresando no es segura, pero no me obligues a poner una contraseña que SEGURO me voy a olvidar.</p>
<p>Nunca faltará el que diga que si me olvido la contraseña puedo solicitar su reseteo como hice anteriormente, ¿pero entonces para que corno me dan una contraseña? No tiene sentido tener que elegir una contraseña para que siempre tenga que resetearla.</p>
<p>Ahora bien.. si yo fuera no se.. partner de Oracle y  puediera con esa contraseña gestionar pagos, cuentas corrientes, o descargar aplicaciones no gratuitas al menos, esta bien que use una contraseña más segura. Pero sería yo el que elegiría una contraseña de mayor complejidad evaluando que tan critica considero la información que ahi guardo en cada caso en particular.</p>
<p>Para mi es más confidencial y peligrosa la información que tengo en mi cuenta de Facebook que la que tengo en Oracle. Por Dios&#8230;facebook sabe hasta con que personas, en que lugares y que comí durante mis últimas vacaciones, donde vivo, donde estudio, donde trabajo, con la información que tienen pueden inferir hasta mi sueldo y grupo sanguíneo y no tiene semejante política de contraseñas !</p>
<p>En fin, estoy muy muy enojado con una estupidez como esta. (obviamente estoy de mal humor por otros motivos, y pobre Oracle fue la gota que rebasó el vaso)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/03/11/seguridad-en-sitios-web-o-como-oracle-apesta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>N2CMS, NHibernate (o Hibernate), Oracle y ORA-01461 (LONG y NCLOB)</title>
		<link>http://blog.soluciones3f.com.ar/2012/03/07/n2cms-nhibernate-oracle-ora-01462-long-nclob/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/03/07/n2cms-nhibernate-oracle-ora-01462-long-nclob/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 21:59:09 +0000</pubDate>
		<dc:creator>sebas</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[n2cms]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=767</guid>
		<description><![CDATA[En esta entrega voy a compartir algunos problemas que tuvimos con la bendita conexión a Oracle. Uno de ellos, fue la existencia de un Rack de servidores en el cliente, es decir, más de un servidor funcionando en paralelo. Además, tenían dos versiones del cliente de Oracle conviviendo en el servidor (cosa que no habían [...]]]></description>
			<content:encoded><![CDATA[<p>En esta entrega voy a compartir algunos problemas que tuvimos con la bendita conexión a Oracle.</p>
<p>Uno de ellos, fue la existencia de un Rack de servidores en el cliente, es decir, más de un servidor funcionando en paralelo. Además, tenían dos versiones del cliente de Oracle conviviendo en el servidor (cosa que no habían indicado cuando nos dieron las especificaciones técnicas del servidor y que aparecieron &#8220;oh caramba!&#8221;, cuando se hizo el primer despliegue). Uno era Oracle8i, otro Oracle10g. Nuestra aplicación &#8220;misteriosamente&#8221; se conectaba a veces si, otras veces no&#8230; Como N2CMS (en realidad Hibernate) no soporta el conector 8i, obviamente, esto ocasionaba errores, cuelgues y cosas muy muy raras <img src='http://blog.soluciones3f.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img src="http://freeskier.com/sites/default/files/users/HankLambo/atomic_bomb_explosion.jpg" /></p>
<p>Bueno&#8230; no tanto, pero explotaba <img src='http://blog.soluciones3f.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>En fin, el problema fue el siguiente: cuando en el web.config seleccionamos la conexión, elegimos &#8220;Oracle10g&#8221;, el cual, en el código fuente del N2 usaba el driver &#8220;default&#8221; de Microsoft para conectarse, y este driver, funciona mal. De hecho, el mismo Visual Studio te recomienda no usarlo :S. Conclusión, le modificamos el siguiente código:</p>
<p><strong>ConfigurationBuilder.cs</strong></p>
<pre class="brush: csharp; title: ; notranslate">
case DatabaseFlavour.Oracle:
case DatabaseFlavour.Oracle10g:

Properties[NHibernate.Cfg.Environment.ConnectionDriver] = typeof(NHibernate.Driver.OracleDataClientDriver).AssemblyQualifiedName;
Properties[NHibernate.Cfg.Environment.Dialect] = typeof(NHibernate.Dialect.Oracle10gDialect).AssemblyQualifiedName;
break;
</pre>
<p>Usando OracleDataClientDriver toma el driver proporcionado por el cliente y no el default de Microsoft. Y con eso, se solucionó ese problemita.</p>
<p><img class="alignnone" src="http://images.wikia.com/randomstuffstuff/images/7/7b/Mission-accomplishedBOY.jpg" alt="mision cumplida" width="199" height="236" /></p>
<p>Otro problema que tuvimos fue el largo de los textos. Por algún motivo, el mapeo de los strings no estaba funcionando correctamente y los valores se convertían a un tipo de dato inválido. El error que teníamos era</p>
<p><code>ORA-01461: can bind a LONG value only for insert into a LONG column</code></p>
<p>Eso lo solucionamos modificando la siguiente linea en el código:</p>
<p><strong>ConfigurationBuilder.cs</strong></p>
<pre class="brush: csharp; title: ; notranslate">
ca.Property(x =&amp;gt; x.StringValue, cm =&amp;gt; { cm.Type(NHibernateUtil.AnsiString); cm.Length(stringLength); });
</pre>
<p><img class="alignnone" src="http://images.cheezburger.com/completestore/2011/3/1/3a6b4630-95c9-44fc-8294-535979b8ea82.jpg" alt="flawless victory" width="300" height="225" /></p>
<p>Espero que les sirva, al menos para que no padezcan los mismos sobresaltos que nosotros si tienen los mismos errores.</p>
<p>¡Hasta la próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/03/07/n2cms-nhibernate-oracle-ora-01462-long-nclob/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redirigir un puerto en Linux utilizando IPTables</title>
		<link>http://blog.soluciones3f.com.ar/2012/03/06/redirigir-un-puerto-en-linux-utilizando-iptables/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/03/06/redirigir-un-puerto-en-linux-utilizando-iptables/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 15:30:14 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[gnu linux]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[eth0]]></category>
		<category><![CDATA[iface]]></category>
		<category><![CDATA[interfaces]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[lan]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[port forwarding]]></category>
		<category><![CDATA[red]]></category>
		<category><![CDATA[redes]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[wan]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=801</guid>
		<description><![CDATA[Para los entendidos, esto se llama Port Forwarding y se lo utiliza, cuando tenemos una sola computadora conectada a internet y una o más computadoras conectadas en una red interna, a la primera. Si alguna de las computadora de la red, quiere ser accedida desde internet, no se puede porque la conexión directa a internet [...]]]></description>
			<content:encoded><![CDATA[<p>Para los entendidos, esto se llama Port Forwarding y se lo utiliza, cuando tenemos una sola computadora conectada a internet y una o más computadoras conectadas en una red interna, a la primera.</p>
<p>Si alguna de las computadora de la red, quiere ser accedida desde internet, no se puede porque la conexión directa a internet solo la tiene la primera computadora. Entonces esta debe configurarse para redirigir (forwardear) el trafico correcto a la computadora correcta.</p>
<p>Los routers traen una opción para hacer esto fácilmente, y es mi consejo que si pueden comprar un router para conectarse a internet, y este estar conectado a varias computadoras, es lo más fácil que podrían hacer. Pero a veces esto no es posible y no nos queda otra que configurar una pc.</p>
<p>Sin explayarme mucho, los comandos necesarios para hacer esto fueron:</p>
<pre class="brush: bash; title: ; notranslate">
sudo sysctl net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -p tcp --dport &lt;puerto_origen&gt; -j DNAT --to-destination &lt;ip_destino&gt;:&lt;puerto_destino&gt;
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
</pre>
<p>Donde hay que reemplazar
<puerto_origen> con un puerto que será al que nos conectaremos desde internet e <ip_destino> y
<puerto_destino> con la ip y el puerto de la pc a la que queremos conectarnos realmente.</p>
<p>Esto es muy simple y fácil, pero siempre me lo olvido, por eso es que lo dejo aqui para futura referencia.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/03/06/redirigir-un-puerto-en-linux-utilizando-iptables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mi experiencia con n2cms, Episodio II (Instalación N2CMS y Oracle 10g)</title>
		<link>http://blog.soluciones3f.com.ar/2012/03/02/n2cms-y-oracle-10g/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/03/02/n2cms-y-oracle-10g/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 21:12:32 +0000</pubDate>
		<dc:creator>sebas</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[.net 4]]></category>
		<category><![CDATA[n2cms]]></category>
		<category><![CDATA[oracle 10g]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=763</guid>
		<description><![CDATA[En esta oportunidad me voy a dedicar a contarles sobre la instalación del Framework y los problemas que tuvimos a la hora de ejecutarlo en el cliente. &#8220;Comencemos con la preparación de los ingredientes&#8230;&#8221; Como había adelantado en el post anterior, el archivo web.config es de vital importancia a la hora de instalar correctamente el [...]]]></description>
			<content:encoded><![CDATA[<p>En esta oportunidad me voy a dedicar a contarles sobre la instalación del Framework y los problemas que tuvimos a la hora de ejecutarlo en el cliente.</p>
<p><img class="alignnone" src="http://www.supanet.com/action-heroes--steven-seagal-chef-13548707.jpg" alt="Chef" width="300" height="200" /></p>
<p><em>&#8220;Comencemos con la preparación de los ingredientes&#8230;&#8221;</em></p>
<p>Como había adelantado en el post anterior, el archivo web.config es de vital importancia a la hora de instalar correctamente el sitio. Para poder realizar la instalación se debe setear la propiedad <strong>allowInstallation</strong> en true:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;installer checkInstallationStatus=&quot;true&quot; allowInstallation=&quot;true&quot; /&gt;
</pre>
<p>Si la aplicación está desarrollada en la versión 4 del Framework de .NET, se debe agregar la siguiente línea:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;httpRuntime requestValidationMode=&quot;2.0&quot; /&gt;
</pre>
<p>(No escribirla si la aplicación es 3.5, para más info -&gt;<a href="http://www.asp.net/whitepapers/aspnet4/breaking-changes">http://www.asp.net/whitepapers/aspnet4/breaking-changes</a> )</p>
<p>Ahora que tenemos todos los ingredientes iniciamos la instalación, entrando a (host)/n2/Installation, nos va a pedir que creemos un usuario y su clave (el cual se guarda en el web.config y es conveniente quitarlo luego).</p>
<p>Luego, se nos preguntará si queremos crear una base de datos nueva. Acá vamos a hacer una pequeña pausa.</p>
<p><img class="alignnone" src="http://losfasta.files.wordpress.com/2011/12/neo-bullet-stop.jpg?w=640" alt="stop" width="240" height="240" /></p>
<p>Acá es sumamente importante tener bien armada la connection string en el web.config. En nuestro caso, si recuerdan del post anterior, la conexión debía ser contra una base de datos Oracle 10g.  Afortunadamente en el web.config vienen escritos varios ejemplos de connection strings para distintas db, pero lamentablemente no para Oracle. Intentamos una connection string standard para Oracle, pero por algún motivo no funcionaba. Luego de muchas pruebas y gotas de sudor, la que funcionó tiene la siguiente estructura:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;add name=&quot;N2CMS&quot; connectionString=&quot;Data Source=SERVER;User Id=USUARIO;Password=PASS;Pooling=True;Max Pool Size=10;&quot; providerName=&quot;Oracle.OdpClient&quot;/&gt;
</pre>
<p>name =&gt; desde el código se suele obtener la conexión por este nombre (N2CMS)</p>
<p>Pooling, Max Pool Size =&gt; esto lo pusimos por el cliente, no es fundamental</p>
<p>providerName =&gt; ESTO FUE CLAVE, <strong>el cliente por defecto de Microsoft no nos funcionó bien</strong>&#8230;</p>
<p>Con esto pudimos continuar la instalación, aunque nos toparíamos con otro problema, un Rack de servidores&#8230; tema que abordaré en otro post. Por último, nos daba la opción de importar la información, o de crear un nodo nuevo como inicio. Nosotros elegimos esta última opción, y para que nos deje elegir el tipo de nodo que nosotros queríamos, agregué este código a la clase del modelo:</p>
<pre class="brush: csharp; title: ; notranslate">
[PageDefinition(&quot;Home&quot;, Description = &quot;Página estilo home.&quot;,
TemplateUrl = &quot;~/UI/HomePage.aspx&quot;, &lt;strong&gt;InstallerVisibility = N2.Installation.InstallerHint.PreferredStartPage&lt;/strong&gt;)]
</pre>
<p>Con eso ya cumplimos lo referente a la instalación. Seguiremos en el próximo capítulo !</p>
<p><img class="alignnone" src="http://3.bp.blogspot.com/_YTp9m_1LFbE/SCwNSw71XiI/AAAAAAAAAaU/sx7oRonxeUM/s400/animal%2Bgracioso.jpg" alt="bye" width="256" height="208" /></p>
<p>Hasta la próxima !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/03/02/n2cms-y-oracle-10g/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP Request usando C++ puro</title>
		<link>http://blog.soluciones3f.com.ar/2012/02/28/http-request-usando-c-puro/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/02/28/http-request-usando-c-puro/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 20:21:35 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Sin categoría]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=780</guid>
		<description><![CDATA[Necesitaba realizar un POST sobre una página que estaba en un dominio de un servidor que utilizaba VirtualHost para tener configurados varios dominos sobre una misma ip. Hasta acá parece simple para cualquier persona con cierto conocimiento de programación de hoy en día. De hecho con lenguajes como Java o .NET es casi trivial hacerlo. [...]]]></description>
			<content:encoded><![CDATA[<p>Necesitaba realizar un POST sobre una página que estaba en un dominio de un servidor que utilizaba VirtualHost para tener configurados varios dominos sobre una misma ip.</p>
<p>Hasta acá parece simple para cualquier persona con cierto conocimiento de programación de hoy en día. De hecho con lenguajes como Java o .NET es casi trivial hacerlo.</p>
<p>Pero se me complicó un poco cuando en el requerimiento estaba que debía hacerse con C++ usando la mínima cantidad de dependencias (inclusive librerías externas).</p>
<p>Busqué en internet algún código que hiciera lo que necesitaba, que no tenga una licencia prohibitiva (costosa, inusable, o sencillamente demasiado compleja para resolver el problema en cuestión), y que sea simple y funcionara. Me costó, pero encontré una implementación que parecía cumplir con mis requisitos.</p>
<p>Pero cuando la fui a probar, no funcionaba. La página que debía acceder me decía <strong>forbidden</strong>. ¿Pero cómo era posible esto si cuando accedía con Firefox veía bien la página?</p>
<p>Entonces recurrí el viejo y querido telnet para ver que estaba pasando de la siguiente manera:</p>
<pre class="brush: plain; title: ; notranslate">
fernando@fernando-laptop:~$ telnet dominio-en-shared-hosting.com 80
Trying xx.xx.xx.xx...
Connected to dominio-en-shared-hosting.com.
Escape character is '^]'.
GET /
</pre>
<p>Y para mi sorpresa, lo que veía con telnet era el mismo <strong>forbidden</strong>.<br />
Investigando un poco sobre el protocolo entendí lo que estaba sucediendo.</p>
<p>Para que los VirtualHost de apache funcionen correctamente, en la petición HTTP se tiene que especificar cual es el dominio al que se intenta acceder, si no se especifica se intenta acceder al default, que es el primero de los virtualhost definidos.</p>
<p>¿Pero como se especifica el dominio? Bueno, la forma más facil es escribir en lugar de <em>GET /</em> la url completa del recurso, por ejemplo <em>GET http://dominio-en-shared-hosting.com/</em> de esta forma Apache puede diferenciar el VirtualHost al que se quiere acceder.</p>
<p>Otra forma, es especificando una versión del protocolo 1.0 o superior y agregando el header Host. Ya no sería un GET y nada más, sino que habria que escribir dos lineas.</p>
<pre class="brush: plain; title: ; notranslate">
GET / HTTP/1.0
Host: dominio-en-shared-hosting.com
</pre>
<p>Al usar esta forma, es necesario dejar un <em>enter</em> despues de ingresar la linea de Host (o si se quieren más headers, despues del último header) para que el servidor entienda cuando se dejó de escribir el request y procese la página.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/02/28/http-request-usando-c-puro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mi experiencia con n2cms, Episodio I</title>
		<link>http://blog.soluciones3f.com.ar/2012/02/23/mi-experiencia-con-n2cms-episodio-i/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/02/23/mi-experiencia-con-n2cms-episodio-i/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 21:31:58 +0000</pubDate>
		<dc:creator>sebas</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[content management system]]></category>
		<category><![CDATA[n2cms]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=754</guid>
		<description><![CDATA[Seguramente quienes desarrollen aplicaciones web se habrán topado con la necesidad de elegir un buen Administrador de Contenidos, o CMS para los amigos. En este caso, no sólo teníamos un proyecto de tamaño considerable (una importante universidad argentina), si no que además estábamos &#8220;atados&#8221; a los siguientes requisitos: Plataforma .NET (en su versión 3.5 o [...]]]></description>
			<content:encoded><![CDATA[<p>Seguramente quienes desarrollen aplicaciones web se habrán topado con la necesidad de elegir un buen Administrador de Contenidos, o CMS para los amigos. En este caso, no sólo teníamos un proyecto de tamaño considerable (una importante universidad argentina), si no que además estábamos &#8220;atados&#8221; a los siguientes requisitos:</p>
<ul>
<li>Plataforma .NET (en su versión 3.5 o 4)</li>
<li>Conexión a base de datos Oracle 10g</li>
<li>Manejo de usuarios por Active Directory (usuarios de Windows&#8230; <a href="http://es.wikipedia.org/wiki/Active_Directory">http://es.wikipedia.org/wiki/Active_Directory</a>)</li>
</ul>
<div>Nuestra impresión fue&#8230;</div>
<p><img src="http://www.omgwtfimages.com/uploads/thumb/thumb_6.jpg" alt="Frustracion" width="300" height="176" /></p>
<p>Luego de analizar varias alternativas (en la mayoría de los casos, los requisitos eran limitantes) decidimos probar la siguiente que resultaba muy atractiva (con cierto grado de desconfianza): <a href="http://n2cms.com/">http://n2cms.com/</a></p>
<p>Entre las cosas que prometía (<a href="http://n2cms.com/Features.aspx">http://n2cms.com/Features.aspx</a>) nos habían llamado la atención las siguientes:</p>
<ul>
<li>Cómoda interfaz de usuario (importante para el usuario final del sitio)</li>
<li>Código abierto y &#8220;sencillo&#8221; para leer y extender (importante para el desarrollador, sobre todo si hay que realizar alguna modificación para agregar funcionalidad)</li>
<li>Persistencia con NHibernate, que por ende, daría soporte para Oracle (o cualquier otra base de datos soportada)</li>
<li>Integración con Membership (que además, es configurable para usarse con Active Directory y Oracle)</li>
</ul>
<p><img class="aligncenter" src="http://mygaming.co.za/news/wp-content/uploads/2012/01/Star-Trek-happy-Picard-530x298.jpg" alt="Contento" width="320" height="200" /></p>
<p>Nos lanzamos entonces a la aventura de probar este framework, que sinceramente nos dió más satisfacciones (y muchas !) que disgustos. Poco a poco iré contando los problemas que tuvimos durante el desarrollo y cómo los fuimos solucionando, sobre todo lo apuntado a la integración de Oracle y AD.</p>
<p>Vean cómo armar una aplicación, después del corte.</p>
<p><span id="more-754"></span></p>
<p>Para entrar un poquito en calor, voy a hacer una breve introducción al desarrollo de una aplicación con N2. Por empezar, tomamos como base el &#8220;Minimal Example C#&#8221; de <a href="http://n2cms.codeplex.com/releases/view/70951">http://n2cms.codeplex.com/releases/view/70951</a></p>
<p>En el proyecto encontramos lo siguiente:</p>
<ul>
<li>Una página <strong>Default.aspx</strong> (que realmente no aplica para mostrar contenido, si no que se muestra como mensaje de error)</li>
<li>Una carpeta <strong>Models</strong>, donde se encuentran las clases que modelan al contenido del sitio</li>
<li>Una carpeta <strong>UI</strong>, donde se encuentran las plantillas (templates) asociados a los contenidos definidos en Models</li>
<li>El archivo de configuración<strong> web.config</strong> que es <span style="text-decoration: underline;"><strong>IMPORTANTISIMO</strong></span> durante el transcurso del proyecto, por ejemplo, para setear que base de datos se desea utilizar. El ejemplo viene configurado para una base de datos Sqlite.</li>
</ul>
<p>Para ver el sitio funcionando se puede correr desde Visual Studio (Nosotros usamos la versión 2010). Para ingresar al panel administrativo basta con entrar a la (url)/N2</p>
<p>Además, se puede correr el instalador (desde (url)/N2/Installation) para reiniciar los valores o cambiar la base de datos de origen. La base de datos se basa sólo en 4 tablas.</p>
<p>Quienes estén en dudas, o quieran probarlo, haganlo, es una buena opción. Próximamente les traigo la segunda entrega con algunos detalles más avanzados y concretos.</p>
<p>Hasta la próxima !!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/02/23/mi-experiencia-con-n2cms-episodio-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configurar Subversion Server, con autenticación de usuarios por OpenLDAP y permisos por path utilizando Authz</title>
		<link>http://blog.soluciones3f.com.ar/2012/02/18/configurar-subversion-server-con-autenticacion-de-usuarios-por-openldap-y-permisos-por-path-utilizando-authz/</link>
		<comments>http://blog.soluciones3f.com.ar/2012/02/18/configurar-subversion-server-con-autenticacion-de-usuarios-por-openldap-y-permisos-por-path-utilizando-authz/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 18:05:48 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[gnu linux]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[administracion]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[autenticacion]]></category>
		<category><![CDATA[authz]]></category>
		<category><![CDATA[autorizacion]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[open ldap]]></category>
		<category><![CDATA[openldap]]></category>
		<category><![CDATA[permisos]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.soluciones3f.com.ar/?p=735</guid>
		<description><![CDATA[En Ubuntu 11.04 (y mas nuevos también) ya no se suele utilizar el archivo de configuración de LDAP sino que se usa una base de datos de configuración Esto tiene la ventaja de que no es más necesario reiniciar el servicio al cambiar algún seteo. Por defecto esta base de datos se puede consultar utilizando [...]]]></description>
			<content:encoded><![CDATA[<p lang="es-AR">En Ubuntu 11.04 (y mas nuevos también) ya no se suele utilizar el archivo de configuración de LDAP sino que se usa una base de datos de configuración Esto tiene la ventaja de que no es más necesario reiniciar el servicio al cambiar algún seteo.</p>
<p lang="es-AR">Por defecto esta base de datos se puede consultar utilizando SUDO ya que no tiene un usuario y contraseña. Se puede crear uno o crear una nueva base de datos donde configurar esos usuarios</p>
<p><strong>Información adicional para instalación de OpenLDAP en Ubuntu 11.04: <a href="https://help.ubuntu.com/11.04/serverguide/C/openldap-server.html">Ubuntu Server Guide &#8211; 11.04 &#8211; OpenLDAP Server</a></strong></p>
<p>En esta guia iré relatando los pasos que fui haciendo desde una instalación de Ubuntu 11.04 en blanco con Apache, Subversion y LDAP instalados pero con escasa configuración, hasta culminar con un sistema que me permite agregar usuarios por ldap y actualizar un archivo Authz para poder especificar permisos de SVN con granularidad.</p>
<p><span id="more-735"></span></p>
<h3 lang="es-AR"><a name="Crear_una_nueva_Base_de_datos"></a> Crear una nueva Base de datos</h3>
<p lang="es-AR">En LDAP cada nueva raíz base es una base de datos. Así que si quiero una rama para dc=soluciones dc=com dc=ar y de ahí abrir toda la organización, se debe crear una nueva base de datos comenzando con esa clave.</p>
<p lang="es-AR">Para esto crear un archivo llamado create_database.ldif con el siguiente contenido</p>
<pre class="brush: plain; title: ; notranslate"># Load dynamic backend modules
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: back_hdb

dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=soluciones3f,dc=com,dc=ar
olcAccess: to attrs=userPassword by self write by anonymous auth by  dn=&quot;cn=admin,dc=soluciones3f,dc=com,dc=ar&quot; write by * none
olcAccess: to * by self write by dn=&quot;cn=admin,dc=soluciones3f,dc=com,dc=ar&quot; write by * read
olcLastMod: TRUE
olcRootDN: cn=admin,dc=soluciones3f,dc=com,dc=ar
olcRootPW: miclave
</pre>
<p lang="es-AR">luego ejecutar el siguiente comando</p>
<pre class="brush: plain; title: ; notranslate">sudo ldapadd -H ldapi:/// -Y EXTERNAL -f create_database.ldif</pre>
<p>Ya deberíamos tener una base de datos para la base dc=soluciones3f,dc=com,dc=ar con usuario admin y contraseña miclave. Sin embargo esta base de datos aun no tiene información y habrá que cargar al menos la información base con otro script.</p>
<h3><a name="Primer_estructura_de_la_base_de_datos"></a> Primera estructura de la base de datos</h3>
<p lang="es-AR">Luego de tener configurada la base de datos, se puede comenzar a crear datos. El primer dato que hay que cargar es el DN principal que es la misma base que se especifico en la creación de la base de datos.</p>
<p lang="es-AR">Creamos un archivo que podemos llamar <strong>configuracion_inicial.ldif</strong> con el siguiente contenido</p>
<pre class="brush: plain; title: ; notranslate">dn: dc=soluciones3f,dc=com,dc=ar
objectClass: top
objectClass: dcObject
objectClass: organization
o: Soluciones 3f SRL
dc: soluciones3f</pre>
<p lang="es-AR">Ejecutamos para agregar esta información, que nos pedirá la contraseña que especificamos cuando creamos la base de datos.</p>
<pre class="brush: plain; title: ; notranslate">sudo ldapadd -H ldapi:/// -D &quot;cn=admin,dc=soluciones3f,dc=com,dc=ar&quot; -W -f configuracion_inicial_ldap.ldif</pre>
<p lang="es-AR">Para poder agregar algunos tipos de datos específicos que necesitaremos luego necesitamos también agregar algunos schemas mas al LDAP que son standard. Para esto ejecutamos los siguientes comandos</p>
<pre class="brush: plain; title: ; notranslate">sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif</pre>
<h3 lang="es-AR">Configuración de Apache + SVN con LDAP</h3>
<p lang="es-AR">Lo primero es tener configurado Apache y SVN correctamente. No preocupándonos aun por la autenticación ni autorización.<br />
<strong>La configuración de apache con svn no es el objeto de este documento.</strong></p>
<p lang="es-AR">Una vez configurado el SVN y Apache, debemos configurarlo para utilizar autenticación por medio de LDAP, esto requiere crear algunos usuarios en el directorio.</p>
<p lang="es-AR">Al menos se requieren dos usuarios, uno contra el cual se hará el bind y se obtendrá el usuario y contraseña que se quiere realmente loguear. Estos se pueden crear utilizando alguna herramienta como phpldapadmin. Utilizando el template de <strong>Simple Security Object</strong></p>
<p lang="es-AR">Luego, hay que agregar algunas directivas a la configuración del Location (o VirtualHost) de apache para que valide los usuarios utilizando LDAP. Por ejemplo quedaría de la siguiente manera la configuración de un Location SVN con LDAP</p>
<pre class="brush: plain; title: ; notranslate">&lt;Location /svn&gt;
    DAV svn
    SVNParentPath /var/svn

        AuthLDAPURL ldap://127.0.0.1/ou=people,dc=soluciones3f,dc=com,dc=ar?uid
        AuthLDAPBindDN &quot;uid=admin,dc=soluciones3f,dc=com,dc=ar&quot;
        AuthLDAPBindPassword &quot;admin&quot;
        AuthType Basic
        AuthName &quot;Password Prompt&quot;
        AuthBasicProvider ldap
        require valid-user
&lt;/Location&gt;</pre>
<p lang="es-AR">De todo esto es importante notar AuthLDAPURL que es la url al servidor ldap que se utilizará para validar, indicando cual es el DN base en el cual se encuentran los usuarios con permiso de acceso. Luego del signo de pregunta va el nombre del atributo que se utilizará como nombre de usuario.</p>
<p lang="es-AR">La directiva AuthLDAPBindDN es el usuario de LDAP que se utilizará para buscar los demás usuarios. Este debe tener permisos para buscar usuarios en el directorio, al menos en la rama indicada en AuthLDAPURL</p>
<p lang="es-AR">Finalmente AuthLDAPBindPassword es la contraseña del usuario que se especifica en AuthLDAPBindDN</p>
<p lang="es-AR">Con esta configuración se requiere un usuario válido para leer o escribir en cualquier repositorio.</p>
<p lang="es-AR">Si surgen problemas, en el Log de Apache (/var/log/apache2/error.log) se pueden ver algunos mensajes, aunque no demasiados útiles, y recomiendo también, revisar que la contraseña y DN del usuario que se utiliza para hacer el Bind sean correctos.</p>
<h3 lang="es-AR">Configuración de SVN con grupos de usuarios por directorio</h3>
<p lang="es-AR">Subversion puede gestionar los permisos de los diferentes usuarios para escribir o leer en un repositorio a nivel path. O sea, que un usuario puede escribir en un repositorio pero no en otro, o incluso dentro de un repositorio en algunos directorios puede tener permisos de lectura y otros no&#8230; y cosas así para administrar un poco la seguridad.</p>
<p lang="es-AR">Esta flexibilidad se consigue por medio de archivos Authz los cuales se configuran en Apache, pero nada saben de LDAP lo cual los hacen un tedio de configurar. Pero afortunadamente hay un script en python que permite administrar estos archivos.</p>
<p><strong>Más información en: <a href="http://www.thoughtspark.org/node/26">http://www.thoughtspark.org/node/26</a></strong> <strong>Source del script original en: <a href="https://bitbucket.org/jcscoobyrs/jw-tools">https://bitbucket.org/jcscoobyrs/jw-tools</a></strong></p>
<h4 lang="es-AR"><a name="Requerimientos_del_script"></a> Requerimientos del script</h4>
<ol>
<li>Como no puede ser de otra manera, hay que descargar el script de: <a href="https://bitbucket.org/jcscoobyrs/jw-tools/raw/e3396390e99b/sync_ldap_groups_to_svn_authz/sync_ldap_groups_to_svn_authz.py">BitBucket del creado del script</a></li>
<li>
<p lang="es-AR">El script requiere el modulo de python-ldap por lo que se debe instalar: <em>sudo apt-get install python-ldap</em></p>
</li>
</ol>
<h4 lang="es-AR"><a name="Ejecuci.C3.B3n_del_script"></a> Ejecución del script</h4>
<p lang="es-AR">Luego de instalados los requerimientos y dado permisos de ejecución sobre el script <em>(chmod)</em> se lo ejecuta con el siguiente comando:</p>
<pre class="brush: plain; title: ; notranslate">./sync_ldap_groups_to_svn_authz.py -d &quot;uid=admin,dc=snes3f,dc=com,dc=ar&quot; -g &quot;objectClass=groupOfNames&quot; -u &quot;objectClass=simpleSecurityObject&quot; -i &quot;uid&quot; -p admin -z svn_users.authz</pre>
<p lang="es-AR">En este script se aprecia el parámetro -g que es para indicar cuales objetos son grupos. el parámetro -u para identificar a los que son usuarios y el parámetro -i para indicar, dentro de los usuarios, cual es el atributo que se usa como key</p>
<p lang="es-AR">Se generará un archivo svn_users.authz con al definición de los usuarios y grupos obtenidos desde la el servidor LDAP. En este archivo, se puede agregar ANTES de la sección grupos, otras definiciones y áreas de permisos para los paths.</p>
<p lang="es-AR">El archivo final queda con al forma</p>
<pre class="brush: plain; title: ; notranslate">[algungrupo:/]
@algungrupo = rw
@internal = r

[soluciones3f:/]
@internal = rw

[groups]

### Start generated content: LDAP Groups to Subversion Authz Groups Bridge (2012/02/18 03:10:54) ###
internal = fernando, facundo
algungrupo = jorge

################################################################################
###########   LDAP Groups to Subversion Authz Groups Bridge (Legend)  ##########
################################################################################
### internal = cn=internal,ou=subversion,dc=soluciones3f,dc=com,dc=ar
### algungrupo = cn=algungrupo,ou=subversion,dc=soluciones3f,dc=com,dc=ar
################################################################################

### End generated content: LDAP Groups to Subversion Authz Groups Bridge ###
</pre>
<p lang="es-AR">Se recomienda ajustar bien estos parámetros y pensar donde debería estar el archivo generado, teniendo en cuenta que este deberá ser luego accesible desde apache, y modificado en bases regulares por un cron u otro medio.</p>
<h4 lang="es-AR"><a name="Configuraci.C3.B3n_del_servidor_Apache"></a> Configuración del servidor Apache</h4>
<p lang="es-AR">Con el archivo authz generado, solo resta configurar el servidor apache y el svn para que lo tengan en cuenta. Para este fin se agrega en la configuración del svn una linea con la siguiente forma</p>
<pre class="brush: plain; title: ; notranslate">AuthzSVNAccessFile /etc/svn_users.authz</pre>
<p lang="es-AR">Luego de reiniciar apache deberían validarse correctamente los permisos.</p>
<p lang="es-AR">
]]></content:encoded>
			<wfw:commentRss>http://blog.soluciones3f.com.ar/2012/02/18/configurar-subversion-server-con-autenticacion-de-usuarios-por-openldap-y-permisos-por-path-utilizando-authz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

