Weblogs Código

Variable not found

¿Es ASP.NET Core MVC un middleware?

September 27, 2016 10:48 AM

ASP.NET Core
En más de una ocasión me he topado con artículos que sugerían que ASP.NET Core MVC es un middleware y de hecho, incluso en algunos momentos yo también he tenido la sensación de que podía serlo.

Sin embargo, y esta es la respuesta corta si quieres ahorrar tiempo de lectura, estrictamente hablando no lo es.

La respuesta larga

Está claro que el framework MVC está presente de alguna u otra forma en el pipeline de ASP.NET Core, lo que hace pensar que sí podría existir una especie de "middleware MVC" capaz de engancharse al pipeline para poder participar en el proceso de peticiones.

La respuesta la encontramos fácilmente buceando en el código del framework. Si echamos un vistazo al fuente del extensor UseMvc() que utilizamos para insertar MVC en el pipeline encontramos lo siguiente (he limpiado un poco el código para que se entienda mejor):

/// <summary>
/// Adds MVC to the <see cref="IApplicationBuilder"/> request
/// execution pipeline.
/// </summary>
public static IApplicationBuilder UseMvc(
this IApplicationBuilder app,
Action<IRouteBuilder> configureRoutes)
{
[...]

// Verify if AddMvc was done before calling UseMvc
// We use the MvcMarkerService to make sure if all the services were added.
if (app.ApplicationServices.GetService(typeof(MvcMarkerService)) == null)
{
throw new InvalidOperationException(
Resources.FormatUnableToFindServices(
nameof(IServiceCollection),
"AddMvc",
"ConfigureServices(...)")
);
}

var routes = new RouteBuilder(app)
{
DefaultHandler = app.ApplicationServices
.GetRequiredService<MvcRouteHandler>(),
};

configureRoutes(routes);

routes.Routes.Insert(0,
AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices)
);

return app.UseRouter(routes.Build());
}

Lo que se hace aquí es lo siguiente:
  1. Primero, se verifica que los servicios de MVC fueron añadidos al sistema solicitando una instancia de MvcMarkerService. Si no existe, es que se ha llamado a AddMvc() en la configuración de servicios, por lo que se lanza una excepción.
     
  2. Se crea un RouteBuilder al que se asocia por defecto el handler MvcRouteHandler. En otras palabras, se comienza a preparar un grupo de rutas cuyo proceso será delegado al framework MVC.
     
  3. Se invoca el delegado suministrado por el desarrollador para que añada las rutas al builder que estamos definiendo. Este delegado es el que suele configurar las convenciones de rutas, como en el siguiente código:
    app.UseMvc(routes =>
    {
    // Delegado de configuración de rutas
    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{id?}");
    });
  4. Se insertan en primera posición las rutas definidas por atributos, de forma que tengan prioridad sobre el resto. Por cierto, CreateAttributeMegaRoute(), vaya pedazo de nombre para un método, ¿verdad? ;D
     
  5. Por último, se añade el middleware de routing de ASP.NET Core que hemos configurado.
Este punto es el que andábamos buscando y que da respuesta a la pregunta que nos hacíamos al principio. Por tanto, MVC no se añade al pipeline como un middleware, simplemente configura un RouterMiddleware de forma que las peticiones dirigidas a las rutas configuradas sean procesadas por MvcRouteHandler, que será el encargado de seleccionar la acción e invocarla.

Publicado en Variable not found.

» Leer más, comentarios, etc...

Poesía Binaria

Tus datos en Internet, ¿están realmente seguros?

September 26, 2016 08:34 AM

photo-1470229722913-7c0e2dbbafd3

Vivimos en un mundo conectado. Nuestros datos de usuario están en cientos de webs repartidas por el mundo. Algunas más confiables que otras. Aunque sí que depositamos nuestra confianza en ellas. Enviamos información privada casi sin preguntarnos si los desarrolladores o personal de seguridad de dicha web está realmente preparado y han hecho sus deberes. Sin preguntarnos si la empresa trata bien a sus empleados y si alguien del personal de seguridad traicionaría a todos los usuarios por una buena suma de dinero, o si un pendrive o un falso router wifi en las oficinas centrales puede causar un desastre y una filtración importante de los datos de la compañía donde tenemos nuestros datos… o si eso pasa sólo en las películas.

Bueno, estas cosas pasan de verdad, y tal vez pensemos que nuestros datos no son importantes. Aunque en los últimos meses ha habido filtraciones de muchas páginas (famosas y muy utilizadas, por ejemplo Yahoo, LinkedIn, Slack, Badoo, MySpace), con muchos usuarios que tienen sus datos comprometidos (correos electrónicos, nombres de usuario, contraseñas, actividad en web, direcciones físicas, ciudades, teléfonos, etc). Tal vez el tema de las contraseñas es más complicado porque los desarrolladores suelen estar concienciados y ahora se almacenan hashes, con sal y protegidos con algoritmos de mezclado y seguridad eficientes, pero aunque sea la norma y confiemos en que todo el mundo almacena de forma segura nuestras contraseñas, eso no es así siempre, y no es difícil encontrar alguna web que almacene todas las contraseñas de usuario en texto plano. Y que, cuando dichas contraseñas se filtran, sí podemos decir que estamos 100% expuestos.

Y es que nuestros datos cuentan con la seguridad del sitio con la seguridad más débil en el que lo hayamos dejado. Triste pero cierto, podemos preocuparnos por la seguridad de nuestros datos en decenas de sitios, pero basta con un sitio donde hayamos dejado los datos hace 10 años que no cuente con suficiente protección como para que éstos ya sean de dominio público.

Almacenando claves con hashes

Nota: ¡Quiero resumir todo en tres párrafos! Tal vez haya alguna inexactitud en esto que digo, pero acepto comentarios constructivos :)

Cuando un sitio almacena las contraseñas de manera correcta (con hashes), tenemos que tener en cuenta que esto son mecanismos de cifrado de una sola vía. Es decir, sólo podremos cifrar y no descifrar (o al menos, es muy costoso). Y, supuestamente a cada dato que podamos cifrar le corresponde un único dato cifrado, es decir, no deben existir, o al menos sea muy muy difícil encontrar varios datos a los que les corresponda un único dato cifrado.
En otras palabras, mi contraseña 12345, la almacenaré como 398k745A. De forma que cuando alguien mire nuestra clave no entienda nada, y sea muy difícil llegar al 12345 inicial. Y, por supuesto, no exista otra contraseña que genere el mismo 398k745A.

Ahora bien, cifrar estos datos con algoritmos de hash es algo muy rápido, imaginad una web en la que cientos de usuarios entran cada minuto. Algo que podríamos hacer es un ataque con fuerza bruta, es decir, conocemos el usuario, pues, probemos contraseñas, ¡como cuando en una película intentan averiguar la clave de una caja fuerte! Si lo hacemos contra una web, cada intento puede suponer algunos segundos, y muchas webs suelen restringir el acceso cuando hemos intentado varias contraseñas (como siempre, las que están bien hechas). Aunque si tenemos en nuestra propiedad el hash generado, no tendremos que enviar nada por web, sólo generar hashes y compararlos, y podemos llegar a comprobar varios miles por segundo… y eso puede llegar a ser peor porque si nuestra contraseña es mala seguramente en pocos minutos puedan averiguarla.

Pero los estudiosos de la seguridad (y matemáticos) no están quietos y a menudo descubren fallos en algoritmos de hash por lo que se puede reducir drásticamente el número de intentos necesarios para averiguar una contraseña. Y para esto están los algoritmos de sazonado (sal, salt, etc), lo que hacen es complicar un poco el hash mezclando la contraseña con otra información (aleatoria, fija o fija+aleatoria), mezclando los datos y pasando varias veces el algoritmo de hash, de tal forma que sea mucho más difícil descifrar la contraseña sin los datos añadidos (que suelen estar almacenados en otro sitio).

¡Sitios que almacenan las contraseñas en texto plano!

Os propongo un juego. Hemos visto que cuando un sitio almacena la contraseña con un hash, este no puede ser descifrado fácilmente, por lo que cuando alguien se identifica con su nombre de usuario y contraseña, el sitio lo que hace es cifrar la clave que acaban de darnos para identificarse y comparar el dato cifrado obtenido con el dato cifrado que ya teníamos del usuario. Si coinciden, ¡perfecto! el usuario entra, si no… la contraseña no era correcta.
Hasta aquí bien, hay sitios en Internet que permiten recordar la contraseña, en ellos, introduces tu correo y te envían la contraseña. Sabemos que es muy cómodo que te digan cuál era tu clave y listo, pero eso quiere decir que sí que almacenan tu contraseña en texto plano y, por tanto, no utilizan un método seguro para gestionarla. Por ejemplo, un empleado, o alguien con acceso a la base de datos puede conocer tu clave, o si las claves de la empresa se filtran, tu clave estará directamente expuesta.

Bueno, supuestamente en el año 2016, no debe haber webs que almacenen esta contraseña en texto plano. Por lo que me gustaría hacer un listado de sitios que sí lo hacen (y podemos averiguarlo, como he dicho antes porque al recordar contraseña te envían un correo con la misma contraseña que tenías.).

  • Clickxti : Es un sitio de pago por click, te envían un correo de un patrocinador y te dan menos de un céntimo por hacer click en dicha publicidad.
  • Sumaclicks : Es un sitio parecido al anterior, la última vez que lo probé tenían este problema todavía, aunque me han quitado el usuario, será por inactividad.
  • 000webhost : Alojamiento web que hasta hace pocos meses almacenaba la clave en texto plano.

Lo dicho, si encontráis más servicios que te permitan recuperar la clave en texto plano, enviádmelos, que los meto en este pequeño Hall of Shame.

Sitios inseguros

Existen sitios, que piden contraseñas, y las almacenan bien. Internamente las gestionan de forma muy eficiente y segura, pero utilizan el protocolo HTTP para comunicarse, lo que quiere decir que el tráfico hacia y desde el servidor podría ser interceptado (incluso por un amigo al que le des la clave de tu WiFi, o si estás en un punto de acceso público ya ni te cuento), es más, el tráfico viajará en texto plano, sin seguridad ni cifrado alguno, por lo que puede resultar fatal para nosotros. Ya que, aunque el servidor gestione de la mejor forma nuestros datos, la transmisión no se produce de forma correcta y puede dar lugar a filtraciones.

Y estamos hablando de sitios web, en los que podemos ver claramente HTTP o HTTPs en la cabecera de la conexión, pero… en el terreno de las aplicaciones móviles, que todo se produce de forma transparente al usuario. Es decir, la aplicación se conecta al servicio online al que pertenece y no sabemos exactamente si es HTTP o HTTPS, o cualquier otra vía de comunicación con o sin cifrado, porque la aplicación simplemente funciona… nos sorprenderíamos al ver la cantidad de información que viaja sin cifrado. Por lo que debemos intentar hacer que nuestras comunicaciones sean seguras, y si desconfiamos de algo, dar datos falsos, irrelevantes, que no nos identifiquen directamente…

Y, ¿esto en qué me afecta?

Tal vez te has registrado en varios sitios de Internet, tengas datos en la nube y, si llevas varios años en este mundillo tal vez habrá servicios web que ya tienes olvidados, cuyos mails no lees, pero están ahí y con la misma contraseña todos, una clave que sigues utilizando hoy para algunas cosas y lleva años acompañándote en tu vida online.

Por un lado, lo malo es la fuga de datos, puede que hayas introducido tu correo personal, tu dirección y teléfono (hace unos años era muy común que cuando te registraras en un sitio te pidieran casi casi hasta el DNI, o incluso). Por otro lado, muchas páginas de concursos lo siguen haciendo para enviarte el premio (no digo que no haya concursos legítimos, pero también hay algunas de dudosa reputación y poco confiables). Bueno, y si en lugar de tu contraseña también está tu respuesta a la pregunta secreta (esa que estaba tan de moda para recuperar la contraseña y que no valía nada más que para hacer el sistema un poco más inseguro).

Así que si alguna de esas páginas no es segura, o durante estos años no se ha renovado en materia de seguridad, y se filtra la base de datos de usuarios de alguna forma, esos datos ya podrían conocerse. Por otro lado, si se filtra una contraseña, ya es otra historia, porque no sólo podrían entrar en nuestro nombre en el servicio vulnerado, que en ocasiones no tiene mucha importancia (bueno, si es el caso de Yahoo, LinkedIn, GMail, puede que nos hagan daño), pero tal vez es la clave de un foro que usábamos hace tiempo pero sigue activo. Si se descubre dicha clave, un usuario atacante, seguramente quiera intentar ver si tienes una cuenta en Facebook, LinkedIn, Amazon, eBay, etc con la misma contraseña, y cuidado con Amazon y eBay que pueden tener asociados datos de pago y nos pueden hacer mucho daño.

Por esta y algunas razones más es importante utilizar una contraseña diferente y segura para cada servicio. Y si no te da la memoria, utiliza un gestor de contraseñas, úsalo en local, porque si subes a la nube el fichero de contraseñas, se puede liar muy gorda si alguien consigue descargarlo…

Segunda parte

Se alargó mucho el post y he decidido cortarlo en dos. Por un lado está esta introducción y por otro lado mostraré algunos scripts y recursos para buscar contraseñas en filtraciones, verificar si estás, o incluso comprobar si los usuarios de tu servidor de correo o tus servicios web aparecen en alguna brecha de seguridad.

Foto principal: Yvette de Wit

The post Tus datos en Internet, ¿están realmente seguros? appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 252

September 26, 2016 06:48 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Cross-platform

Otros


Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Cuándo utilizar TDD

September 26, 2016 05:06 AM

Charlaba la semana pasada en Twitter sobre TDD y, en concreto, el concepto de triangulación a raíz de este post en el que se menciona lo siguiente:

A esta altura, ya es evidente que sería más facil escribir la implementación obvia que seguir haciendo ramas de decisión.

Antes esto, parece razonable preguntarse:

¿Tiene sentido utilizar TDD cuando existe una implementación obvia?

Y, ojo que esto es importante, hablo de utilizar TDD, no de tener tests. Hablo de la metodología de desarrolo descrita en el Test Driven Development auténtico. Si nos centramos en tests, ya he explicado varias veces lo que considero que se debe cubrir con tests y he puesto ejemplos de cómo testear determinados escenarios.

En este post quiero divagar un poco sobre cuándo tiene sentido aplicar TDD.

OJO: Si eres un fanático convencido de TDD, probablemente no te guste el post, y me temo que basarás tu argumentación en que no sé aplicar TDD. Es posible, pero lo cierto es que lo he aplicado con relativo éxito durante el tiempo suficiente como para poder formarme una opinión al respecto. Por supuesto, puedo estar equivocado y te agradecería que me explicaras por qué.

Me gustaría poder dar unas pautas universales de cuándo usar TDD y cuándo no merece la pena, pero lo cierto es que es un caso similar a elegir un lenguaje de programación e influyen tantos factores que no me siento capacitado para dar una serie de reglas categóricas sobre el tema.

Lo que sí puedo hacer, y creo que puede resultar útil, es analizar distintos aspectos de TDD y comentar mi experiencia personal con ellos. Tómatelo como lo que es, una opinión y no una verdad absoluta, y si te apetece comentar cómo te ha ido a ti con esta historia, estupendo, seguro que más de uno te lo agradecemos.

Por cierto, para los que no tienen ganas de leer más, no, no creo que merezca la pena aplicar TDD si existe una implementación obvia, aunque haya quien lo piense (y no, esta vez no ha sido Robert C. Martin, quien directamente aboga por lo contrario).

TDD como herramienta de diseño

Es uno de los argumentos más utilizados por los defensores y practicantes de TDD. De hecho, para muchos la última D de TDD no es development, sino design. Ciertamente, TDD nos puede ayudar en el diseño, pero quizá no tanto como nos gustaría.

Por una parte nos obliga a escribir código testeable, lo que se supone que es bueno (y es algo que ni siquiera voy a cuestionar ahora).

Sin embargo, también hay que recordar que lo que nos obliga a escribir es código testeable con tests unitarios, y ahí entramos en problemas semánticos sobre lo que es un test unitario. Si al final esto se va a reducir a crear un montón de header interfaces para escribir tests de interacción de esos que no validan gran cosa, no sé si realmente tenemos un diseño mejor o sólo estamos sobrecomplicando el diseño para poder escribir unos tests que no aportan valor y sólo sirven para que las métricas queden bonitas.

Por otra, es cuestionable que TDD nos lleve a diseñar un algoritmo de la mejor manera. Os recomiendo echar un vistazo a esta antiquísima discusión sobre diseñar un algoritmo para resolver sudokus usando TDD. Merece la pena ver las dos aproximaciones, con y sin TDD.

En su favor, debo decir que aplicar TDD nos ayuda a diseñar el API que tendrá nuestro componente. Al escribir primero el código cliente (los tests, en este caso) nos obliga a pensar cómo queremos utilizarlo y nos guía para diseñar un API que tenga sentido.

En ese sentido podríamos decir que TDD es una buena herramienta para diseñar APIs pero… La verdad es que no es necesario para eso y, a veces, directamente nos lleva a diseñar un API muy adecuada para los tests pero no necesariamente apta para el código de producción. Si queremos realmente diseñar correctamente el API de un componente, es mejor aplicar directamente diseño top-down y que sean los clientes reales de nuestro componente los que marquen el API (que luego podremos implementar o no con TDD).

En definitiva, creo que nunca he sido capaz de sacarle excesivo partido a TDD como herramienta de diseño. Además, hay aspectos del diseño de un componente que son complicados que surjan naturalmente aplicando TDD, como la transaccionalidad o la eficiencia.

TDD como forma de hacer testing

Los que realmente usan TDD no suelen hacer mucho enfásis en esto y consideran los tests como un producto residual (aunque útil e importante) de la técnica.

Es decir, tú no haces TDD por conseguir tests, sin por conseguir código mejor. Si eso además deja un rastro de tests que luego puede seguir usando como documentación o para que verificar que el código funciona después de futuras refactorizaciones, mejor para ti, pero insisto, no es el objetivo fundamental. Incluso hay gente que, una vez ha llegado a la solución, borra los tests, o al menos parte de ellos, porque considera que no aportan ya nada.

Reconozco que al principio cuando usaba TDD lo hacía un poco con la mentalidad de olibgarme a escribir tests. Y además con muy buena cobertura. A fin de cuentas, no escribes código de producción si no hay antes un test fallando, por lo que se supone que la cobertura debería ser muy cercana al 100%.

Eso me llevó a algunos problemas de lo que mencionaba antes, con muchos tests de dudoso valor y, lo que es peor, con código que había sido desarrollado siguiendo religiosamente TDD y estaba completamente testado, pero no sólo no tenía una buena implementación, sino que ni siquiera funcionaba en producción o lo hacía de forma deficiente.

Aquí admito sin duda mi parte de culpa, y estoy seguro de que hay gente a la que no le pasa eso, pero la verdad es que he visto bastantes casos reales de este problema. Aplicar TDD no es sencillo, y es fácil acabar con la sensación de que para que realmente funcione TDD en el fondo hay que hacer “trampas” y saber desde el principio donde vas a llegar. Si no, puedes tener todos los tests que quieras, que luego en producción ya veremos lo que pasa.

Si lo que estás buscando es conseguir tener una buena suite de tests, que cumpla con el objetivo fundamental de los tests: conseguir confianza, dudo que TDD sea la mejor forma de hacerlo.

Aunque sólo seas por un problema muy básico: TDD se limita a hablar de tests unitarios y para tener una buena suite de tests hay que jugar con todos los tipos de tests que tienes a tu disposición, incluso con los tipos de tests más exóticos.

Diseñar una estrategia de testing requiere un enfoque más integral, pensando qué quieres conseguir, qué partes son más importantes testear, en qué partes es más fácil cometer errores, y qué tipo de tests te pueden ayudar a cubrir tus objetivos. Es eso lo que debe marcar el aspecto de una suite de tests, más que aplicar TDD o no.

TDD como herramienta de exploración

Otro de los argumentos a favor de usar TDD es que te permite explorar un problema de forma incremental hasta alcanzar una solución. La idea es que al ir construyendo los tests poquito a poquito (con baby steps, si quieres sonar más guay), puedes ir conociendo cada vez más cosas del problema que intentas resolvar sin tener que intentar abarcarlo todo de golpe.

La verdad es que en ese sentido sí que me resulta útil TDD, especialmente cuando no tengo ni idea de cómo afrontar algo. Si no sabes por dónde empezar, empezar por algo, lo que sea, aunque luego lo borres todo y empieces otra vez de cero, es mejor que nada. Empezar a escribir código suele ayudar también a tener cierta sensación de avance (aunque sea fictia) que evita la parálisis por análisis en la que a veces nos sumimos.

Normalmente no suelo empezar por aplicar TDD y soy de los que prefiere pensar un rato antes, pero hay casos en los que estoy bloqueado y aplicar TDD me permite avanzar algo. No suelo dar pasos taaaaan pequeños como para saltar de implementación trivial en implementación trivial, pero si me obligo a resolver facetas concretas del problema en lugar de atacarlo todo a la vez.

Puede sonar raro, pero uno de los escenarios en los que suelo aplicar TDD es al escribir consultas SQL complejas. Probablemente porque para los que desarrollamos las típicas aplicaciones aburridas de línea de negocio sean una de las cosas más complicadas que llegamos a hacer, y además suelen ser muy costosas de testear a mano porque están llenas de casos extraños que no siempre son fáciles de simular.

Por supuesto, TDD no es la única herramienta de exploración que existe y tampoco es la única que utilizo. Muchas veces me gusta montar un proyecto de pruebas (un spike para los amantes del postureo) y empezar a jugar para investigar algo. Si el lenguaje se presta (y cada vez trato más de usar lenguajes que se presten porque me resulta muy productivo), disponer de un buen REPL es un excelente complemento a TDD como cuenta Manuel Rivero en su muy recomendable blog.

Conclusiones

Puede sonar todo un poco negativo hacia TDD, y más viniendo de alguien que hace 4 años defendía TDD y recomendaba no escribir todos los tests unitarios a la vez para seguir TDD, pero lo cierto es que todo evoluciona y no es la primera (y seguro que tampoco la última) vez que escribo posts con cierto tono contradictorio. Prefiero ser sincero que dogmático.

Estoy convencido de que me dejo muchos aspectos importantes de TDD y de que parte de los motivos por lo que no obtengo más beneficios de aplicarla es culpa mía, pero la realidad es que, simplificando mucho, para mi el principal punto a favor de usar TDD es la facilidad para explorar un problema en lenguajes en los que no es sencillo usar un REPL.

Eso no quiere decir que no le dé valor a los tests. Al contrario. Creo que es algo a lo que cada vez le he ido dado más valor, y quizá justo por eso cada vez los he alejado más de TDD. Los tests son lo bastante importantes como para diseñarlos de forma independiente y no como un subproducto de una metodología de desarrollo.

Posts relacionados:

  1. Licencias de Software, ¿cuándo puedo usar qué?

» Leer más, comentarios, etc...

Blog Bitix

Cómo instalar y probar macOS con VirtualBox en Windows o GNU/Linux

September 25, 2016 09:00 PM

¿Queres comprar un Mac, tienes dudas o deseas probar su sistema operativo antes? Aunque el rendimiento será menor que una máquina real y la experiencia de usuario será peor, usando un hackintosh mediante VirtuaBox ya sea con Windows o GNU/Linux podremos probarlo en detalle y hacernos una idea de su funcionamiento.

Apple
macOS

Estaría leyendo alguna noticia, ahora no me acuerdo que me despertaría la curiosidad pero me pregunté si es posible usar de forma virtualizada macOS con VirtualBox tanto en Windows como en GNU/Linux. Usar lo que se conoce como hackintosh, esto es hackear el sistema operativo Macinstosh de los equipos de Apple para que se ejecute en cualquier un dispositivo no soportado. En la página web hackintosh puede encontrarse información diversa sobre el tema como instrucciones, vídeos, comunidades, ….

Es política de Apple que su sistema operativo solo pueda ser ejecutado en sus equipos que los vende de forma conjunta a un notable precio, no se si alguien usa macOS en un sistema no Mac con garantías de que en alguna actualización el sistema deje de funcionar teniendo en cuenta la política de Apple para con sus productos.

Los pasos para instalar macOS en una máquina virtual con VirtualBox son los siguientes, hay que descargar un archivo con la imagen del disco duro de macOS y una vez creada la máquina virtual en VirtualBox ejecutar unos comandos para cambiar algunos parámetros del sistema de arranque EFI. Deberemos descomprimir la imagen del disco duro para obtener el archivo de extensión vmdk y proceder a crear la máquina virtual. Elegimos crear una máquina virtual de tipo macOS, cambiaremos algunas opciones, asignando unos 2 o 3 GiB de memoria, seleccionaremos el disco duro con la imagen vmdk descomprimida y cambiaremos la memoria asignada a la pantalla.

Configuración de la máquina virtual

Si usamos Windows deberemos ejecutar los siguientes comandos en modo administrador, sustituyendo macOS Sierra 10.12 por el nombre que le hayamos dado a la máquina virtual al crearla:

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/588b2cd99be69d340c79cafb55f9b334/raw/windows.cmd">windows.cmd</pre></a></noscript>

En el caso de Linux el archivo de comandos es similar e igualmente sustituiremos macOS Sierra 10.12 por el nombre que le hayamos dado a la máquina virtual al crearla:

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/588b2cd99be69d340c79cafb55f9b334/raw/linux.sh">linux.sh</pre></a></noscript>

Hecho estos dos pasos podemos proceder a iniciar la máquina virtual, veremos que empiezan a salir unos cuantos mensajes hasta que se inicia el sistema gráfico con la instalación y su asistente que constará de varios pasos.

Terminada la instalación entramos en el escritorio con el aspecto clásico y fondo de pantalla de macOS y las aplicaciones incorporadas en el propio sistema por defecto.

Como partidario del software libre y la privacidad además de los ínfimos impuestos que paga Apple usando reprobable ingeniería fiscal y su software privativo no recomiendo usar un Mac pero si alguien quiere probar este sistema operativo antes de decidirse a hacer una compra usarlo de forma virtualizado es una buena ayuda para tomar una decisión y ver si nos gusta su sistema operativo aparte del propio equipo junto con su precio que podemos ver en las tiendas. Si no nos convence ni su software ni su abultado precio podemos optar por un portátil de Slimbook mucho más económico y con características notables con los que no tendremos que pagar tampoco el impuesto Windows ya que podemos elegir entre varias la distribución GNU/Linux preinstalada que deseamos.

Deberemos tener en cuenta al probar macOS con VirtualBox que el rendimiento de la máquina virtual no será exactamente el mismo que en un equipo real por la sobrecarga impuesta por la virtualización realizada. La experiencia de usuario puede cambiar significativamente junto con el hecho de que los portátiles Mac tiene una pantalla bastante mejor y con más resolución que la mayoría de portátiles diseñados para Windows o GNU/Linux y un SSD de gran rendimiento además de la falta de su touchpad, todo esto puede marcar alguna diferencia.

» Leer más, comentarios, etc...

Blog Bitix

Autenticación con OAuth y Keycloak en un servicio REST con JAX-RS y Spring Boot

September 24, 2016 07:00 PM

Keycloak es un proveedor de OAuth que podemos usar en nuestras aplicaciones y servicios para proporcionar autenticación, autorización, SSO y también añadir seguridad a los servicios REST que desarrollemos como muestro en este artículo. OAuth tiene varias ventajas sobre usar autenticación Basic.

Keycloak
Java

Una forma de autenticar a los clientes de un servicio REST es usar autenticación Basic que se basa en añadir una cabecera en la petición en la que se incluye un usuario y contraseña. La autenticación Basic es sencilla pero para que sea segura ha de usar el protocolo seguro HTTPS.

Sin embargo, presenta otros inconvenientes y es que si al servicio van a acceder varios clientes y a uno queremos impedirle el acceso no podremos hacerlo sin cambiar el usuario y contraseña lo que obligará al resto de clientes actualizarse para usar las nuevas credenciales si las comparten, que no siempre es posible sobre todo si esos clientes están fuera de nuestro control. Para solventar el segundo problema tenemos la posibilidad de segurizar el servicio REST con el protocolo OAuth.

Teniendo un servicio web REST implementado con JAX-RS y Spring Boot añadirle seguridad con OAuth mediante el proveedor Keycloak es lo que muestro en este artículo. En el servicio REST bastará que usemos el adaptador para Spring Boot de Keycloak y añadamos en Keycloak cierta configuración que consistirá en un realm y el registro de un cliente. Para acceder al servicio REST usaremos el flujo client_credentials que nos permitirá obtener un token usando las credenciales del cliente.

Iniciado Keycloak con Docker y Docker Compose accedemos al panel de administración con el navegador, en mi caso en http://localhost:9080 con el usuario admin y contraseña admin según lo indicado en el archivo docker-compose.yml.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/docker-compose.yml">docker-compose.yml</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/docker-compose-up.sh">docker-compose-up.sh</pre></a></noscript>

Creamos un realm, en el ejemplo llamado springbootjaxrs y un cliente con id client, además crearemos un rol api y se lo asignaremos al cliente.

Una vez realizada la configuración en el servidor de OAuth/Keycloak obtendremos la configuración para el adaptador de Keycloak para el servicio REST desde la pestaña Installation que añadiremos en el fichero de configuración de Spring Boot application.yml. Además, indicaremos que el cliente solo aceptará access tokens mediante la opción bearer-only de modo que no hará redirecciones para autenticar.

Indicaremos también el rol que deberá poseer el cliente para acceder al servicio REST junto que URLs del servicio estarán autenticadas por OAuth. Añadida la configuración al archivo application.yml el servicio REST es totalmente inconsciente de la autenticación que se realizará con OAuth y Keycloak.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/application.yml">application.yml</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/MessageResource.java">MessageResource.java</pre></a></noscript>

Iniciado Keycloak y el servicio REST con el comando ./gradlew run podemos iniciar el proceso de obtención de un access token y llamar al servicio proporcionando el access token obtenido y ver que pasa si no proporcionamos token o uno modificado o inválido. Para obtener el access token podemos emplear curl accediendo al endpoint de Keycloak para obtenerlos.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/curl-token.sh">curl-token.sh</pre></a></noscript>

Obtenido el access token si no lo proporcionamos en la llamada al servicio REST observaremos que la respuesta que obtenemos es un código de estado HTTP 401 indicando que se necesitan proporcionar las credenciales que con OAuth es un token.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/curl-401.sh">curl-401.sh</pre></a></noscript>

Proporcionando el token mediante una cabecera de la petición el servicio nos devolverá los datos que proporciona. Si el token no es válido obtendremos un error HTTP 401.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/curl.sh">curl.sh</pre></a></noscript>

Para usar Keycloak en una aplicación Java con Spring Boot deberemos añadir algunas dependencias al proyecto que usando Gradle como herramienta de construcción serían las siguientes.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/d3cd61c429b60c83531b624245f77bd4/raw/build.gradle">build.gradle</pre></a></noscript>

Un buen libro sobre OAuth que he leído es Mastering OAuth 2.0 que explica detalladamente el protocolo OAuth junto con el resto de formas de obtener un token además del mostrado en este artículo usando las credenciales del cliente.

En el siguiente artículo mostraré un cliente en Java del servicio REST autenticado con OAuth que haga las mismas llamadas que con curl pero usando código Java mediante la librería HttpClient.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradle run.

» Leer más, comentarios, etc...

Una sinfonía en C#

¿Cómo verificar la integridad de los scripts usando subresource integrity?

September 21, 2016 06:51 PM

Los CDN nos permiten tomar recursos como archivos Javascript de terceros (léase frameworks o librerías) sin necesidad de hostearlos nosotros y delegando esa reponsabilidad en servidores más robustos, con replicación, mejor capacidad y con un potencial uso de cache, sin embargo esto podría ser riesgoso.

Por ejemplo si el CDN es hackeado o de alguna manera las peticiones redireccionadas podemos estar potencialmente en peligro de cargar archivos maliciosos en nuestro sitio web, por suerte hay una manera de evitarlo.

Integridad de subrecursos

La integridad de subrecursos (SRI) es una característica de seguridad que permite a los navegadores verificar que un recurso recuperado (de un CDN o cualquier otro origen) no ha sido manipulado permitiendo, para ello, espeficar un hash que el navegador utilizará.

Sencillamente podemos indicar en nuestro tag script un hash calculado con algún algorítmo conocido para que el navegador verifique la integridad del recurso que se intenta cargar, veamos el caso de jQuery por ejemplo:

Llamada “normal” al CDN de jQuery

<script src="https://code.jquery.com/jquery-3.1.0.min.js">

 

El problema acá es que no estamos verificando que el archivo jquery-3-1-0-min.js sea lo que esperamos,

Llamada verificando la integridad del recurso

La forma de agregar la verficación de integridad sería la siguiente:

<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>

Nótese que agregamos el atributo “integrity” con el valor que indica el hash para verificar la integridad del archivo.

Si intentamos carga el recurso y el hash es incorrecto pasa esto:

image

¿Cómo podemos calcular el hash?

Bien, hay varias formas,:

Y listo, basante simple, más información sobre SRI en al sitio de Mozilla.

Nos leemos.

» Leer más, comentarios, etc...

Blog Bitix

Monitorizar con eventos de Google Analytics una página web

September 19, 2016 09:00 PM

Conociendo cómo usar los eventos de Analytics podemos conocer información interesante acerca de qué forma los usuarios interactúan con nuestra propia página web. Cualquier cosa que podamos realizar con JavaScript o ante cualquier evento que podamos reaccionar podemos medirla con Analytics.

Google Analytics

No se mucho de Google Analytics únicamente lo que he aprendido aplicándolo en mi propia bitácora. Cuando cambié de herramienta para generar de forma estática la bitácora pude personalizar en mucha mayor medida que lo que podía primeramente con Blogger y después tenía con Octopress.

Google Analytics además de proporcionarnos diversa información interesante sobre las visitas que recibimos en una página web puede servirnos para analizar el comportamiento de los usuarios, como interaccionan con la página, qué acciones realizan o que funcionalidades son usadas. La forma con la que podemos agregar información propia de la aplicación o página web es mediante los eventos de Analytics. Después de instalar el script de Analytics podemos enviar eventos simplemente con la siguiente linea de código JavaScript.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/c66532a6eaab846b579ff55b902e874f/raw/ad-enter.js">ad-enter.js</pre></a></noscript>

La información del evento de compone de categoría (category), acción (action), etiqueta (opt_label), valor (opt_value) y si no supone interacción (opt_noninteraction). Deberemos proporcionar valores según queramos estructurar los eventos obligatoriamente para categoría y acción siendo el resto opcionales. En mi bitácora uso Analytics para además de visualizar la información que proporciona sobre visitas, ubicación de los usuarios, idioma, plataforma y navegador que usan, páginas más visitadas, origen de las visitas para lanzar unos cuantos eventos que me proporcionen información sobre las pulsaciones que se realizan en el menú de categorías y en los enlaces de redes sociales, en la lista de artículos recientes, artículos destacados y en el widget de ShareThis y si se hace en el del inicio del artículo o en el del final. En la sección Comportamiento > Eventos se agrega toda la información de los eventos, además podremos monitorizar en tiempo real los eventos que se estén produciendo en la sección Tiempo real > Eventos.

El parámetro _optnoninteraction afecta al porcentaje de rebote, un evento interactivo se considerará como una acción que ha realizado el usuario después de visitar la página, si ese evento lo consideramos como un objetivo podemos hacer que esa interacción no se considere en el porcentaje de rebote. Por ejemplo, si el usuario permanece en la página 30 segundos podemos lanzar un evento que indique tal circunstancia con un timeout y esa visita no se considere en el porcentaje de rebote.

Podemos medir cualquier cosa que deseemos incluso podemos conocer cuantos usuarios usan un bloqueador de anuncios como AdBlock. Este es el código JavaScript que uso para conocer cuantos usuarios lo tiene activado o no.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/c66532a6eaab846b579ff55b902e874f/raw/ad-block.js">ad-block.js</pre></a></noscript>

En la sección Seguimiento de eventos de la documetación de Google Analytics y en el resto de secciónes hay más detalles sobre esta herramienta. Para cualquier cosa que podamos reaccionar mediente un evento con JavaScript podemos medirla con Analytics, sirviéndonos para extraer información valiosa sobre los usuarios que nos permitan medir, entender y luego mejorar la experiencia de usuario de nuestra propia página web.

Como para cualquier otra cosa en la que queramos profundizar una buena forma es con algunos libros específicos dedicados al tema. Los siguientes son dos libros de los muchos libros sobre Google Analytics disponibles en Amazon.

» Leer más, comentarios, etc...

Una sinfonía en C#

¿Cómo usar Visual Studia Code como diffviewer para GIT?

September 19, 2016 06:51 PM

Con las sucesivas versiones VSCode es cada vez más potente y lo usamos para más cosas, una para la cual empecé a usarlo hace poco es para hacer diff de versiones usando Toirtoise GIT.

Básicamente cuando comparamos dos versiones de un archivo vemos algo así:

image

Como se ve tenemos la comparación a todo color y hasta una bonita barra de navegación a la derecha para ver los cambios a lo largo de todo el archivo.

¿Cómo configuramos Tortoirse GIT para usar VSCode?

Tenemos que ir a la configuración de Tortoise

image

Y en la opción de “Diff Viewer” elegimos “external” y buscamos donde tenemos instalado VSCode y agregamos el modificador “—diff” en mi caso la línea de comando queda así:

C:\Program Files (x86)\Microsoft VS Code\Code --diff

Y listo, al llamar a diff de GIT nos muestra VSCode. Nos leemos.

» Leer más, comentarios, etc...

Poesía Binaria

Crea tus propias webs dinámicas en C++ de forma fácil y usando plantillas para no compilar a cada cambio

September 19, 2016 08:10 AM

Screenshot 12-08-2016-020848
Esto forma parte de un pequeño proyecto que mantengo desde hace algo más de un año. El objetivo es crear un sistema con el que servir webs desde C++, que sea más o menos fácil de mantener y generar, flexible, que soporte enrutadores, plantillas, hosts virtuales con el fin de poder utilizarlo para diferentes tipos de aplicaciones a modo de panel de control web.

Sobre todo está pensado para aplicaciones internas y no para desarrollos web públicos, por temas de seguridad y rendimiento cuando la carga aumenta considerablemente, aunque sí que podría ser utilizado sin problemas en segundo plano por nuestras aplicaciones web por eso de que en ciertas operaciones, un programa hecho en C++ rendirá mucho mejor que cualquier Javascript, Java, PHP, etc. Será más difícil de hacer y optimizar, pero correrá con más soltura y aprovechará la memoria de manera más eficiente.

Para conseguir esto, he utilizado dos proyectos de los que ya os he hablado en el pasado: Glove, que es una envoltura para sockets en C++11 con el que podemos crear un servidor web rápidamente (GitHub) y Silicon, un sistema de plantillas que nos permite separar la salida web de nuestro código en C++ (y eso nos permite también hacer pequeños cambios en la salida sin tener que compilar de nuevo). (Github).

Ambos proyectos están juntos para poder probarlos desde un proyecto en GitHub llamado SiliconGlove, de todas formas, aquí explico un poco cómo funciona todo.

El sistema tiene poco más de 100 líneas (sin contar las plantillas, que hice basándome en el tema StartBootstrapLandingPage.

Inicialización

Lo primero que tenemos que hacer es iniciar el servidor web con esta línea:

1
GloveHttpServer serv(8080, "", 2048);

Creamos el objeto serv, que será nuestro servidor. En este caso, trabajaremos en el puerto 8080. El segundo parámetro será la IP desde la que escuchamos, con lo que podemos limitar la escucha a un dispositivo concreto (si tenemos varios dispositivos de red), y el tercer parámetro será el tamaño del buffer, podremos jugar con este parámetro para conseguir mejores resultados, pero 2048 no es un mal valor).

Luego, debemos inicializar el sistema de plantillas, en este caso, estableceremos las rutas internas de css y js (para encontrarlos fácilmente, así como establaceremos ciertos valores por defecto. Todo esto, si miramos el proyecto en GitHub, lo podremos ver dentro de la función setypSiliconGlobals():

1
2
3
4
5
6
7
8
9
10
11
  SiliconWeb::load();
  SiliconWeb::cssUrl("css");
  SiliconWeb::jsUrl("js");
  Silicon::setMaxBufferLenGlobal(65535);
  Silicon::setGlobalKeyword("TwitterLink", "https://twitter.com/gasparfm");
  Silicon::setGlobalKeyword("GithubLink", "https://github.com/gasparfm/siliConGlove");
  Silicon::setGlobalKeyword("LinkedInLink", "https://es.linkedin.com/pub/gaspar-fernández/14/563/537");
  /* Don't render JS and CSS immediately */
  Silicon::setGlobalKeyword("_renderResources", "0");
  Silicon::setGlobalKeyword("PageTitle", "glove+siliCon test");
  Silicon::setGlobalKeyword("WebAuthor", "Gaspar Fernández");

Para Silicon tenemos otro buffer de datos y, si vemos que el tamaño de nuestras plantillas aumenta mucho, debemos pensar en aumentar este valor de 65535. Esto existe para optimizar un poco en tiempo y en memoria el sistema. Casi todas las palabras clave dentro de setGlobalKeyword() serán palabras que se sustituirán directamente en la plantilla, es decir, cuando en la plantilla llamemos a TwitterLink, saldrá mi enlace de Twitter automáticamente. Aunque encontramos valores con una barra baja (_) delante que serán configuraciones del sistema de plantillas, por ejemplo _renderResources, define si un recurso se pinta nada más llamarlo o no. En este caso, como no se pintan, podemos acumular todos los JS y CSS dentro de las plantillas, y sólo se harán efectivos cuando llamemos a una orden específica para pintarlos. Lo veremos más adelante.

Enrutador

Una parte importante de un sistema web, si no queremos sufrir mientras lo implementamos es un enrutador. Ya que todas las peticiones web entrarán al mismo sitio, tenemos que definir quién procesará cada una y es este enrutador el que se encarga de ello. Debemos definir qué hacer cuando llamemos a http://host/css/xxxx , http://host/js/xxxx , http://host … para ello podemos definir qué función se llamará para procesar cada una de las llamadas, de la siguiente manera:

1
2
3
4
5
6
7
8
  serv.addRoute("/", webIndex);
  serv.addRoute("/hello/$anycon/$anything", hello);
  namespace ph = std::placeholders;
  serv.addRoute("/css/$filename", std::bind(GloveHttpServer::fileServerExt, ph::_1, ph::_2, "resources/css/"));
  serv.addRoute("/fonts/css/$filename", std::bind(GloveHttpServer::fileServerExt, ph::_1, ph::_2, "resources/fonts/css/"));
  serv.addRoute("/fonts/fonts/$filename", std::bind(GloveHttpServer::fileServerExt, ph::_1, ph::_2, "resources/fonts/fonts/"));
  serv.addRoute("/js/$filename", std::bind(GloveHttpServer::fileServerExt, ph::_1, ph::_2, "resources/js/"));
  serv.addRoute("/img/$filename", std::bind(GloveHttpServer::fileServerExt, ph::_1, ph::_2, "resources/images/"));

Así cuando llamemos a la web principal, lo procesará una función llamada webIndex (la veremos más adelante). Aunque esto no tiene gracia si las rutas fueran fijas, es decir, si definimos /css/estilos.css y tuviéramos que procesarlo de forma fija, siempre, porque si incluimos varios archivos css en la misma ruta deberíamos definirlos uno a uno. Por ello, si introducimos un símbolo de dólar ($) en la ruta, el sistema lo tomará como una palabra clave. En otras palabras, se creará un parámetro dinámico al que nos referiremos como ‘anycon’, ‘anythink’, o ‘filename’, y luego la función que procese la petición sólo tendrá que jugar con el nombre que le hemos dado a la palabra clave. Esto nos puede dar mucha flexibilidad (luego veremos lo fácil que es desde la función hello).

Por otro lado, el sistema tiene funciones predefinidas, como servir un fichero directamente. Si es un CSS/JS y no vamos a hacer nada con él, lo podemos devolver directamente, para ello tenemos la función fileServerExt(). En este caso, con bind() le pasamos un argumento extra al callback, en este caso la ruta donde de verdad se encuentra el archivo. Con esto, aunque a nuestro servidor le pidan algunos archivos desde /fonts/css/fuente.ttf , en realidad lo estaremos pidiendo a resources/fonts/css/fuente.ttf , por lo que nuestra aplicación puede tener todo mucho mejor organizado.

Sirviendo el index

Para servir el index, en este caso, sólo tenemos que cargar un archivo de plantilla base (layout), sera una plantilla general para todas las subpáginas, aunque ahora sólo tenemos una, y luego cargará una plantilla específica para la página actual. Además, definiremos palabras clave locales para nuestra plantilla (cuando ésta se procese, se juntarán las palabras clave locales y las globales). Para servir la página haremos lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void webIndex(GloveHttpRequest &request, GloveHttpResponse& response)
{
  Silicon s = Silicon::createFromFile("index.html", "templates");
  s.setKeyword("PageSection", "Home");
  s.setKeyword("SectionsBase", "");
  try
    {

      /* setLayout soon will be global too, so we will be able to
     do it just once. */

      s.setLayout("layouts/mainLayout.html");
      response << s.render();
    }
  catch (SiliconException e)
    {
      response.code(500);
      response.responseVar("errorMessage", std::string("There was a problem: ")+e.what());
    }
}

Cogiendo palabras clave del enrutador

Esto lo podemos ver en la función hello():

1
2
3
4
5
6
7
8
9
10
11
void hello(GloveHttpRequest &request, GloveHttpResponse& response)
{
  std::cout << "TESTING"<<std::endl;
  response << "You are here: "<<request.getLocation()<<"\n";
  for (auto x : request.special)
    {
      std::cout << "ARG "<<x.first<< "=>"<<x.second<<"\n";
    }
  response << "This is the response\n";
  response << "This is another tesxt" << std::endl;
}

Vemos que request, tiene una variable llamada special con la que accede a las palabras clave del enrutador. En este ejemplo, las listamos, pero podríamos poner perfectamente:

1
std::cout << request.special["anycon"] << std::endl;

Y esto nos puede ayudar a tener ordenados los argumentos de entrada, comprobar que se pasan y procesar una salida adecuada.

Plantillas

Dentro de las plantillas, podemos incluir CSS y JS donde queramos:

{!includeCss file=”bootstrap.min.css” /}
{!includeCss file=”landing-page.css” /}
{!includeCss file=”http://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic” /}
{!includeJs file=”jquery.js” /}
{!includeJs file=”bootstrap.min.js” /}

Del mismo modo, podemos hacer el render de CSS y JS donde queramos (porque _renderResources vale 0:





{!renderCss/}

Y, como también vemos, incluir variables con {{nombreDeVariable}}. Del mismo modo, si estamos en una plantilla base o layout, podemos incluir la información procesada de la plantilla de sección si incluimos {{contents}} , el texto se puede configurar si desde nuestro programa en C llamamos a setContentsKeyword().
Incluso incluir otras plantillas:

{!block template=”blocks/nav.tpl”/}

Sólo queda compilar, en el proyecto en GitHub, tenéis un ejemplo de Makefile que podéis utilizar para hacer pruebas rápidas.

Cosas que se pueden hacer

Aunque en el ejemplo sólo se demuestran enrutadores y plantillas, en Glove, se pueden utilizar conexiones seguras HTTPS (sólo hay que introducir los certificados), siliCon soporta la creación de funciones para procesar contenidos, condiciones, colecciones y muchas más cosas que nos harán el desarrollo mucho más fácil. Sólo tenemos que ver los ejemplos incluidos en los dos proyectos.

Si queréis un panel de control para vuestros proyectos, os recomiendo echarle un ojo a la plantilla AdminLTE. Tiene muchas características interesantes y podemos integrarla perfectamente dentro de Glove+Silicon para nuestros sistemas de control.

Un extra más

Si queremos incluir dentro de nuestro proyecto web una llamada a Glove. Por ejemplo, desde una web de producción, o desde un subdominio. Una forma muy recomendable de hacerlo es, por ejemplo, a través de Apache. De esta forma, Apache se encargará de la seguridad en las peticiones, y de pasarnos sólo lo que debe (sin que el usuario final interactúe directamente con nuestro programa), además, podemos tener varios servicios corriendo y acceder a ellos desde una misma dirección web (sin necesidad de cambiar puertos).

Para ello tenemos que activar en Apache los módulos proxy y proxy_http:

sudo a2enmod proxy
sudo a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Enabling module proxy_http.
To activate the new configuration, you need to run:
service apache2 restart

Y dentro de nuestro VirtualHost añadir la línea que comienza por ProxyPassMatch:

ServerAdmin webmaster@localhost
DocumentRoot /home/gaspy/www
ProxyPassMatch ^/glove/(.*)?$ http://127.0.0.1:8080/$1

De esta forma, nosotros, desde fuera, accederemos a http://localhost/glove/ y Apache, internamente, accederá a http://localhost:8080. Así, podemos cerrar el puerto 8080 para prevenir ataque externos.

The post Crea tus propias webs dinámicas en C++ de forma fácil y usando plantillas para no compilar a cada cambio appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 251

September 19, 2016 06:45 AM

Enlaces interesantesPues sí, como comentaba el amigo Gustavo en el post de despedida preveraniego, ya iba siendo hora de volver al frente de batalla. Y si he tardado no es porque haya estado desde entonces tumbado en una hamaca (¡más quisiera!), sino más bien por lo contrario. En breve os contaré más sobre el proyecto en el que ando metido, porque seguro que a muchos os va a interesar :)

Pero bueno, retomando las buenas costumbres, ahí lleváis los enlaces recopilados durante la semana pasada. Como siempre, espero que os resulten interesantes ;-)

.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Y con esto, ¡queda inaugurada oficialmente la temporada 2016-2017 de Variable Not Found!

Publicado en Variable not found

» Leer más, comentarios, etc...

Blog Bitix

Ejemplo de API REST en Java con JAX-RS y Spring Boot

September 17, 2016 10:00 AM

Java
Spring Framework

En Java a través de JAX-RS, una de entre las varias especificaciones de JavaEE, podemos desarrollar servicios web basados en REST y JSON. Estos servicios web al usar la infraestructura de la web y el protocolo HTTP podemos hacer uso de facilidades que proporciona como cacheo, protocolo seguro, HTTP/2, compresión o autenticación. Usando Spring Boot podemos desarrollar servicios web autocontenidos al igual que podemos hacer con las aplicaciones web tradicionales.

Para facilitar el inicio de los proyectos podemos usar Spring Initializr seleccionando los módulos web y JAX-RS con la implementación de referencia Jersey. Al proyecto creado deberemos añadir los servicios que queramos proporcionar. En el ejemplo añadiré uno muy sencillo que devuelva un nuevo mensaje creado en un servicio inyectado en la clase del recurso del servicio REST.

Esta es la definición del bean del servicio que creará el mensaje para el contenedor de inversión de control, también definimos el recurso del servicio REST para Jersey.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/Main.java">Main.java</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/JerseyConfig.java">JerseyConfig.java</pre></a></noscript>

El servicio lo definimos en una interfaz y una clase que la implementa.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/MessageService.java">MessageService.java</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/DefaultMessageService.java">DefaultMessageService.java</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/Message.java">Message.java</pre></a></noscript>

Es habitual que los servicios REST produzca como resultado un JSON como formato para devolver los datos. No necesitaremos hacer nada especial para convertir el Java Bean de la clase Message a JSON, de ello se encargará automáticamente JAX-RS. Con anotaciones como @QueryParam podemos obtener los parámetros del query string, de la URL o cabeceras enviadas.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/MessageResource.java">MessageResource.java</pre></a></noscript>

Iniciada la aplicación con ./gradlew run y con la siguiente comando de curl y URL obtendremos el mensaje en formato JSON en la salida.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/curl.sh">curl.sh</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/76862386194b211fc775b5fb36732bc9/raw/out.txt">out.txt</pre></a></noscript>

Al diseñar APIs REST más complejas que este sencillo ejemplo conviene conocer el término HATEOAS. Deberemos definir como organizar la información devuelta por los diferentes que los libros RESTful Web APIs y REST in Practice además de artículos con consejos sobre como diseñar APIs RESTful.

Una vez que disponemos del servicio REST podemos añadir autenticación y autorización con Keycloak como proveedor de OAuth.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew run.

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Práctica fundamentos de la programación

September 15, 2016 08:51 AM

Por esas cosas de la vida, hace unos meses me vi implicado en un cuestionable favor, pero justificado por motivos de fuerza mayor. Se trata de esas prácticas universitarias, en este caso la correspondiente a la asignatura de fundamentos de la programación en la UPF (Universitat Pompeu Fabra) del curso 2015-2016 para la recuperación del […]

La entrada Práctica fundamentos de la programación aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

CRM | Microsoft Dynamics CRM

September 14, 2016 11:45 AM

Microsoft's big win over Salesforce: HP signs up to six-year cloud CRM deal http://flip.it/Kih4c3

» Leer más, comentarios, etc...

Una sinfonía en C#

Javascript:¿Qué pasa cuando se mezclan el tipado débil y la concatenación?

September 13, 2016 01:34 PM

Todos sabemos que Javascript es debilmente tipado, es decir, existen tipos de datos pero podemos hacer cosas como cambiar el tipo de una variable:

var a = "hola";
console.log(a);
a = 1;
console.log(a)

Y no pasa nada, también podemos comparar diferentes tipos sin mucho problema:

if("hola" == 1){
 //hacer algo
}

Y tampoco pasa nada, de hecho en este caso la comparación resulta ser false, pero podría ser true por la conversión de tipos:

if("1"==1){
//hacer algo
}

Esto último da como resultado true.

El tema del que quiero hablar es una curiosidad que es consecuencia de esto mismo; en el último if lo que hace Javascript es convertir comparar sin importar el tipo, es decir, hace una conversión para saber la equivalencia entre los dos valores, algo similiar pasa cuando concatenamos strings

"hola " + 1

El resultado es "hola 1", ya que Javascript convierte el 1 en un string, hasta acá todo bien, veamos otro ejemplo:

"123"+45

da como resultado "12345", es decir un string concatenado, pero...si hacemos:

"123"-45

Da como resultado 78, porque el signo - no sirve para concatenar strings, pero sí para restar, entonces en el caso de la suma Javascript convierte el 45 en un string y los concatena, pero en el caso de la resta convierte el "123" en un número y los resta, awesome.

Nos leemos pronto.

» Leer más, comentarios, etc...

Poesía Binaria

Cómo empotrar datos dentro de un ejecutable hecho en C

September 12, 2016 08:36 AM

photo-1453179592584-e2587867cfff

En nuestras andanzas como programadores, seguro que nos hemos encontrado alguna vez en esta situación. Tenemos un programa que vamos a distribuir, pero que tiene ciertos archivos asociados (imágenes, texto, scripts, etc) que deben ir junto con el programa.
En un primer momento podemos distribuir los archivos junto con el programa, y es una buena solución hasta que a alguien le da por cambiar esos archivos y consiguen que nuestro programa haga cosas diferentes a aquellas para las que ha sido pensado originalmente.

Esto se ha hecho durante años para almacenar este tipo de recursos, incluso algunos IDEs y compiladores lo hacen sin que nosotros hagamos nada. Pero somos valientes, y lo haremos con GCC.

Un poco más de contexto

Tal vez para imágenes no sea demasiado crítico, pero sí para código. Es decir, muchas veces, aunque hagamos un programa en C, éste a su vez tendrá fragmentos programados en LUA, Python, AngelScript, o incluso SQL. Y claro, si incluimos estos scripts en el código estamos forzando a recompilar el programa cuando hay un cambio en estos scripts, cosa que puede tardar mucho, y no es necesaria (lo mismo pasa con iconos, imágenes, etc).
Con recompilar el programa, me refiero a compilar un archivo .c o lo que es peor, realizar un cambio en un .h que se incluya en varias partes. Si habéis trabajado con algún programa grande, sabréis a lo que me refiero, un pequeño cambio puede suponer tener parado el ordenador varios minutos.

Lo que podemos hacer, es que en modo depuración, los recursos se lean desde los archivos externos, pero cuando el programa sea definitivo se lea de lo que tenemos almacenado en el ejecutable.

Un primer ejemplo

Vamos a empezar empotrando un pequeño texto dentro de un archivo ejecutable. Para ello, nos serviremos tanto de GCC como de objcopy. Es importante saber que este método sólo funcionará con GCC/G++, con otro compilador, debemos hacer las cosas de otra manera.
Lo primero será hacerlo con archivos de texto, para ello, crearemos un archivo llamado (pruebas.txt) y escribiremos dentro un texto.
Luego haremos este programa en C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

extern char _binary_pruebas_txt_start;
extern char _binary_pruebas_txt_end;

int main(int argc, char* argv[])
{
    char* c = &_binary_pruebas_txt_start;

    printf ("------------- Datos empotrados en mi ejecutable ----------\n");
    while (c != &_binary_pruebas_txt_end)
        printf("%c", *c++);
    printf ("--------- Fin de datos empotrados en mi ejecutable --------\n");
   
    return 0;
}

Ahora vamos a compilar el archivo pruebas.txt y el ejecutable:

objcopy --input binary --output elf64-x86-64 --binary-architecture i386 pruebas.txt pruebas.o
gcc -c main.c
gcc -o main main.o pruebas.o

Y listo, cuando lancemos ./main nos escribirá en pantalla el mensaje que tenemos configurado.

Eso sí, tenemos que tener especial cuidado con la arquitectura. Este ejemplo es para x86-64, si quisiéramos una salida para x86 en 32bit pondríamos elf32-i386.

Otro pequeño ejemplo con idea

Contamos con que no manipulen nuestro archivo ejecutable cambiando los datos que contiene, aunque podríamos introducir mecanismos como hacer que los primeros bytes sean un hash y cuando arranque nuestro programa comprobar que todo está bien. Pero este tipo de cosas puede servirnos para rellenar información en un struct, por ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

extern char _binary_struct_data_start;
extern char _binary_struct_data_end;

struct TDatos
{
    uint32_t id;
    char url[100];
    char nombre[100];
};

int main(int argc, char* argv[])
{
    struct TDatos datos;
   
    char* c = &_binary_struct_data_start;
    memcpy(&datos, c, sizeof(struct TDatos));

    printf ("ID: %d\n", datos.id);
    printf ("URL: %s\n", datos.url);
    printf ("Nombre: %s\n", datos.nombre);
   
    return 0;
}

Eso sí, ahora tenemos que hacer un archivo binario en el que incluyamos:

  • 4 bytes (ID, un número, que tal vez en texto sea ilegible).
  • 100 bytes de texto (url, hay que tener cuidado y meter un terminador, 0x00 cuando termine el texto).
  • 100 bytes de texto (nombre, incluyendo un terminador como antes).

Podemos generar el fichero de datos de varias maneras: una de ellas sería creando otro programa en C que escriba los datos en un archivo binario, otra forma puede ser utilizar un editor hexadecimal, como el pantallazo que muestro a continuación (Sí, es Emacs como editor hexadecimal, que Emacs vale para todo):
Screenshot 12-09-2016-020913.
Luego llamamos a este archivo struct.data, creamos el objeto con objcopy y compilamos el programa enlazando el objeto. El resultado será algo como:

objcopy --input binary --output elf64-x86-64 --binary-architecture i386 struct.data struct.o
gcc -c main.c
gcc -o main main.o struct.o
./main
ID: 65
URL: http://totaki.com/poesiabinaria
Nombre: Poesía Binaria

Alternativa para depuración

Si queremos hacer, como dije al principio que el dato se coja de un archivo sólo si estamos en modo depuración y si no, se coja del ejecutable, debemos hacer algo como esto (es una idea, nada más, no está optimizado ni nada):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define DEBUG 1
#define FREE_RESOURCE(res) if (DEBUG) free(res)
#define GET_RESOURCE(res, tam, resource_name)                                                       \
    {                                                                                                                                           \
        if ( (DEBUG) && (file_exists(# resource_name ".data")) )                        \
            tam = get_resource(&res, # resource_name ".data");                              \
        else                                                                                                                                \
            {                                                                                                                                   \
                res = & _binary_ ## resource_name ## _data_start;                               \
                tam = (& _binary_ ## resource_name ## _data_end) -                          \
                    (& _binary_ ## resource_name ## _data_start);                                   \
            }                                                                                                                                   \
    }


extern char _binary_text_data_start;
extern char _binary_text_data_end;

/* Existe el archivo ? */
short file_exists(char *filename)
{
    FILE* fd = fopen(filename, "r");
    if (fd)
        {
            fclose(fd);
            return 1;
        }
    else
        return 0;
}

size_t get_resource(char** res, char* filename)
{
    FILE *f = fopen(filename, "rb");
    printf ("%p\n", f);
    fseek(f, 0, SEEK_END);
    size_t fsize = ftell(f);
    fseek(f, 0, SEEK_SET);  //same as rewind(f);

    *res = malloc(fsize + 1);
    fread(*res, fsize, 1, f);
    fclose(f);

    (*res)[fsize] = 0;
    return fsize;
}

int main(int argc, char* argv[])
{
    char* data;
    long tam;
    GET_RESOURCE(data, tam, text);
    printf ("El recurso ocupa: %ld\n", tam);
    printf ("Datos: %s\n", data);
    FREE_RESOURCE(data);                    /* Sólo libera memoria cuando estamos en depuración */
   
    return 0;
}

Y el fichero texto.data podrá contener lo que queráis. En este caso veremos que cuando compilamos y DEBUG es 0, SIEMPRE cogeremos la información empotrada en el ejecutable, pero cuando DEBUG vale 1 y además el fichero texto.data existe, leeremos el fichero y cogeremos de ahí la información. Si cuando dejamos de utilizar el recurso llamamos a FREE_RESOURCE, liberaremos el puntero que se reserva en modo depuración, pero en real no hace nada.

Nota de la foto: ¿Por qué frutas? Considero trozos de datos o información a las frutas, y cada una de ellas debe ser empotrada en un ejecutable sin perder sus propiedades.

Foto: Roman Davayposmotrim

The post Cómo empotrar datos dentro de un ejecutable hecho en C appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Koalite

Por qué no utilizo métricas

September 12, 2016 05:06 AM

Sería el año 2006 más o menos cuando leí Pragmatic Programmer, el libro que más me ha influido como desarrollador. Por su culpa decidí montar un servidor de integración continua que a día de hoy sigue siéndome de extrema utilidad lanzando vetustos scripts de msbuild que conviven con los mil sistemas de compilación de Javascript.

Lo que se ha caído de ese servidor, o mejor dicho, de los scripts varios que ejecuta, es el cálculo de métricas varias sobre el código.

Al principio me molestaba en calcular métricas sobre el código fuente (utilizaba cosas como Source Monitor para ello), que me indicaran número de líneas de código, complejidad ciclomática, nivel máximo de anidamiento, profundidad de jerarquías…., en fin todo tipo de datos para disfrutar con un poco de porno de estadísticas. Además, analizaba la cobertura de código que alcanzaban mis tests (con NCover, si no recuerdo mal), y tenía configurados mis avisos si no llegaban a determinados niveles.

Nunca les hice excesivo caso, pero era bonito tenerlas y consultarlas de vez en cuando, e incluso a veces me servían para ver áreas que podía mejorar refactorizando el código o añadiendo más tests.

Hoy en día no uso este tipo de indicadores y no los echo en absoluto de menos, pero antes de ver por qué yo no consigo sacarles mucho partido, vamos a ver qué razonamientos hay detrás del uso de métricas y por qué, a lo mejor a ti, sí que te resultan útiles.

Si no lo mides, no lo puedes mejorar

Es algo aceptado generalmente. Para poder mejorar algo, necesitas poder medirlo, porque es la única manera de saber si estás mejorando o no.

La idea de las métricas es crear una serie de valores que actúen como proxies de lo que realmente se quiere medir. Normalmente, lo que se quiere medir son cosas como la facilidad para mantener el código, la propensión a contener errores o la fiabilidad.

Para ello, se parte de características del código fácilmente medibles y se asume cierta relación entre ellas y la cualidad que realmente queremos medir. Por ejemplo, en general el código que tiene más complejidad ciclomática es más difícil de mantener. El código con un ratio de comentarios adecuado es más fácil de mantener. Las clases con más líneas de código son más propensas a contener errores. El código cubierto por tests suele tener menos fallos.

Desde un punto de vista puramente estadístico, las métricas pueden llegar a ser muy fiables. Sobre todo si tenemos una muestra lo suficientemente grande y representativa de código que nos permita afinar los valores a partir de los cuales debemos preocuparnos.

Ayuda bastante en ese sentido aplicar técnicas de análisis forense del código que nos ayuden a identificar áreas especialmente problemáticas. Lo bueno de estas técnicas es que trabajan sobre hechos reales, porque están analizando la historia del código, y no se limitan a establecer hipótesis en base al aspecto actual del mismo.

Cuando estamos trabajando con bases de código muy grandes, o con equipos con gente con poco conocimiento desigual, o con mucha rotación de personal, las métricas son una buena forma de mantener un cierto control sobre lo que se está haciendo. Por una parte podemos marcar límites a las barbaridades que hacemos (“no puede haber contructores con más de 10 parámetros”), y por otra nos permiten señalizar potenciales problemas y nos dan una pista de dónde podemos empezar a dedicar esfuerzos para mejorar la salud de nuestro proyecto, como explica Jorge Sánchez.

Lo que mides, es lo que consigues

Es el mayor peligro de empezar a medir cosas y tratar de optimizarlas. Si lo haces bien, te arriesgas a conseguir mejorar esas métricas. Y sólo eso. Por eso es fundamental no olvidar que lo que quieres mejorar no son las métricas sino lo que ellas representan.

En un mundo ideal, estas métricas que hemos elegido como proxy reflejarían perfectamente las cualidades que buscamos en el software, pero en el mundo real, no siempre es así. Puede que ese método con 4 ifs sea más fácil de entender así. O que lleve funcionando 8 años y no haya dado ni un sólo problema. A lo mejor es código autogenerado. ¿El ratio de comentarios? Otro factor muy relativo que depende mucho del tipo de comentario.

En realidad, esto no debería ser un problema. No deberían tomarse las métricas como reglas rígidas, sino como indicadores de cosas que tal vez estén mal. Se supone que deberían servirnos para llamar la atención sobre ellas y decidir si necesitamos solucionarlas o no.

Cuando sí que se puede convertir en un problema es cuando empezamos a evaluar o valorar a los desarrolladores en base a esas métricas.

Entonces es probable que se preocupen más de conseguir un 100% de cobertura de código en los tests, que de escribir tests que realmente sean útiles. Incluso aunque sólo usemos las métricas a título informativo, es fácil que si las estás viendo continuamente te acaben condicionando a la hora de organizarte el trabajo para intentar mejorarlas. Nos gusta jugar y mejorar nuestra puntuación.

No consigo sacarles partido

Con lo que hemos estado viendo hasta ahora, parece razonable pensar que calcular métricas sobre el código, si se hace con sentido común, es una herramienta práctica para desarrollar software.

Pese a ello, no soy capaz de sacarles suficiente partido como para que me compense ralentizar la compilación obteniendo métricas y asumir el riesgo de acabar jugando contra ellas en lugar de centrado en conseguir lo que realmente considero importante.

En mi caso, trabajo en un equipo pequeño, donde todos somos muy conscientes de lo que queremos conseguir y de los valores que queremos reflejar en nuestro código, por lo que el componente de control no me resulta útil.

Trabajo con una base de código relativamente grande, en la que el número de falsos positivos es importante.

Esos casos que mencionaba antes, de clases muy grandes pero que tienen su justificación, o de código feo pero que funciona y nunca hay que modificarlo, aunque son infrecuentes, existen, y si tienes un volumen de código suficiente, son los que acaban copando todos los listados de “métodos más inmatenibles”.

Ello implica que si no quieres estar revisando una y otra vez lo mismo, necesitas mantener algún tipo de configuración en las herramientas de análisis estático para ignorar esos bloques de código, lo que complica el mantenimiento y te acaba llevando al otro extremo, el de los falsos negativos por culpa de haber marcado como “ignorables” partes de la aplicación que no deberían serlo.

Al final le acababa haciendo caso a las métricas para manteneras bonitas, pero no porque realmente me aportaran demasiado. Ya sabíamos de sobra las partes de la aplicación que eran difíciles de tocar y mantener, o dónde se solían concentrar los bugs.

De hecho, había ocasiones en que la solución que más nos gustaba podía ir en contra de las métricas de calidad que habíamos establecido, por ejemplo aumentando acoplamiento para conseguir una mayor cohesión, pero tener las métricas encima nos condicionaba, aunque fuera inconscientemente, a usar soluciones menos atractivas pero con mejor puntuación.

El problema para mi, en definitiva, es que las métricas analizan el código, y el código importa, pero el contexto más.

Cuanto menos contexto tienes, más valiosas se vuelven las métricas, porque al menos te aportan alguna información. Si puedes permitirte estar encima de las cosas y confiar en el sentido común de los que trabajan contigo, la utilidad de las métricas disminuye bastante porque puedes observar directamente la realidad sin necesidad de proxy.

No hay posts relacionados.

» Leer más, comentarios, etc...

Blog Bitix

Artículo #2 de Yo apoyo al software libre

September 09, 2016 09:30 PM

Recibidas nuevas transferencias de Google y Amazon por la publicidad AdSense y los enlaces de afiliado respectivamente que incluyo en esta bitácora he realizado unas pequeñas nuevas donaciones económicas a varios proyectos de software libre que uso habitualmente.

Firefox
Wikipedia

En diciembre de 2015 escribía un artículo sobre la primera donación económica que hacía un proyecto de software libre. En esa primera donación compré un par de camisetas a la Free Software Foundation Europe o FSFE. Pasados ocho nuevos meses desde entonces me llegó una nueva transferencia de Google por la publicidad AdSense que incluyo en esta bitácora de alrededor de 80€, hace unos meses recibí otra por los enlaces de afiliado de Amazon que en este caso fue de alrededor de 25€. Como la bitácora no me genera ningún tipo de gasto ni para el hospedaje ni para el dominio (salvo buena parte de mi tiempo, que no es poco) me planteo hacer una nueva donación a algún proyecto o algunos proyectos.

Pensando que proyectos serían los siguientes y que cantidad me he decidido por los siguientes Arch Linux, Arch Linux ARM, Firefox y Wikipedia con 10€ cada uno para un total de 40€, que al final solo han sido 20€ porque el medio para hacer el pago utilizando de Software in the Public Interest tanto en Arch Linux como en Arch Linux ARM por algún motivo no me acepta la tarjeta bancaria virtual, en la siguiente donación quizá lo intente de nuevo o de otra forma por ejemplo comprando una camiseta en FreeWear.

Como sistema sistema operativo uso GNU/Linux y la distribución Arch Linux tanto a modo personal en mi portátil y en el trabajo y a pesar de ser una distribición rolling release o en constante actualización raras han sido las veces que he tenido algún problema desde hace ya más de 6 años. Esta es la distribución con la que al final personalmente he acabado más contento después de pasar por Fedora, Debian y Ubuntu. Arch Linux ARM lo utilizo en una Raspberry Pi 1 modelo B (la que tiene 256 MiB de memoria) para hacer descargas y también muy contento ya que tampoco me da problemas. Firefox es el navegador de mi preferencia después de una no muy extensa época usando Chromium, lo uso a modo personal y en el trabajo como desarrollador web. Finalmente, aunque no sea un proyecto de software libre es un proyecto colaborativo de libre acceso y desde hace tiempo una gran fuente de conocimiento acumulada de la que suelo incluir muchos enlaces en esta bitácora, es la Wikipedia.

Las cantidades que he donado no son muy elevadas pero espero que ayuden a estos proyectos a continuar su desarrollo y seguir mejorando. Esta de las pocas veces que «pago» algo por el software que utilizo exceptuando las veces en las que lo he hecho por el impuesto Windows.

Hubo una época que usaba el sistema operativo de Microsoft sin licencia de Windows XP. Hoy en día Windows 10 y Office 2016 siguen siendo fáciles de usar sin licencia un buen porcentaje de usuarios tampoco pagará por el software que usa lo que en realidad afecta negativamente al software libre ya que le impide ganar cuota de uso. El software libre no es sinónimo de gratis, aunque en la mayoría de los casos lo es, sino que proporciona a sus usuarios las 4 libertades explicadas en ¿Qué es el software libre?.

Estas son las pruebas fehacientes que muestran las donaciones que he hecho a los dos proyectos anteriores.

Donación Mozilla
Donación Wikipedia

Probablemente dentro de alrededor de otros 8 meses cuando reciba nuevas transferencias de Google y Amazon haré una nueva donación a otra serie de proyectos que uso quizá en ese caso a LibreOffice, VLC, GNOME, GIMP, … o lo intente de nuevo con Arch Linux. Y estos serán proyectos muy conocidos que no necesiten tanta colaboración económica seguro que hay muchos proyectos menos conocidos pero muy importantes que también necesitan financiación.

Puede que ni siquiera uses GNU/Linux o software libre pero al visitar esta bitácora puedes considerar que tú también has colaborado con el software libre ;) y simplemente usarlo o promocionarlo ya es una buena forma de apoyarlo. Si lo hicieses, ¿a que proyectos harías tú una donación?

Yo apoyo al software libre

» Leer más, comentarios, etc...

HardBit

Ejecutando Node.js en una maquina virtual de Windows Azure extra small

September 05, 2016 05:25 PM

A principio de año lei un articulo (how to) de como instalar node.js en una maquina virtual en Amazon, esta maquina virtual es una micro la mas pequeña del IaaS de Amazon, con la llegada de los nuevos servicios de Windows Azure voy a replicar la idea es replicar exactamente lo mismo pero usando Windows Azure IaaS.

1.- Nos autenticamos en Windows Azure y vamos a la opción de nueva maquina virtual como lo muestra la siguiente imagen.

2.- Una vez realizado esto vamos a escoger el SO en este caso usare un openSUSE y el tamaño de la maquina virtual sera extra small.

3.- Le asignamos un DNS name y entonces creamos la maquina virtual.

4.- Añadiremos un endpoint con el puerto 80 para poder ver nuestro demo de node.js como muestra la siguiente imagen.

5.- El siguiente paso es conectarnos por medio de SSH para realizar las instalaciones de las herramientas necesarias para compilar node.js para eso obtendremos los datos del servidor SSH.

6.- Una vez con los datos del servidor SSH nos conectamos con las credenciales que otorgamos al crear nuestra maquina virtual.

7.- Una vez realizado este paso, vamos ahora si a instalar las herramientas con el gestor de paquetes zypper.

sudo zypper install gcc-c++ make
sudo zypper install openssl-devel
sudo zypper install git
git clone git://github.com/joyent/node.git
cd node
git checkout v0.8.8
./configure
make
sudo make install

8.- Una vez instalado node.js vamos a agregar la siguiente linea que contiene las rutas de bin al archivo sudoers en el apartado Defaults Specifications

Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

Para realizar este paso ejecutamos lo siguientes comandos, en este caso uso vi para realizar la modificación

sudo su
vi /etc/sudoers

 

9.- El siguiente paso es crear nuestro ejemplo de nodejs por lo que nos salimos de su con el comando exit y vamos a nuestro directorio raiz

cd ~/mk

dir site

cd site

vi server.js

Lo siguiente es agregar el código al archivo server.js

var sys = require( “sys” );
var http = require( “http” );

// Create our HTTP server.
var server = http.createServer(
function( request, response ){

// Create a SUPER SIMPLE response.
response.writeHead( 200, {“content-type”: “text/plain”} );
response.write( “Hellow world from Windows Azure!\n” );
response.end();

}
);

// Point the HTTP server to port 80.
server.listen( 80 );

// For logging….
sys.puts( “Server is running on 80” );

10 .- Una vez realizado este paso abriremos el puerto mediante iptables con el siguiente comando

sudo /usr/sbin/iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to 80

11.- El siguiente paso es instalar el paquete forever para que siempre este en linea nuestro servidor node.js para por lo que ejecutamos el siguiente comando

sudo npm install forever

12.- Una vez realizado este proceso vamos a crear un archivo de nombre start que nos servira para iniciar node.js y donde pondremos el siguiente codigo

#!/bin/bash

# Invoke the Forever module (to START our Node.js server).
./node_modules/forever/bin/forever \
start \
-al forever.log \
-ao out.log \
-ae err.log \
server.js

Le damos permisos de ejecución al archivo con chmod +x ./start

13.- Y por ultimo ejecutamos nuestro servicio con privilegios elevados.

sudo ./start

Y con esto nuestro servidor node.js ya se estará ejecutando en mi caso en la url http://vmnodejs.cloudapp.net

Es importante mencionar que Windows Azure cuenta en sus Cloud Services (Web Roles) con un ambiente de Node.js y libs para usar el blob storage y demás, pero este es un ejemplo de como poder personalizar nuestro servidor Linux en el IaaS de Windows Azure 😉

» Leer más, comentarios, etc...

Poesía Binaria

Creando un plugin epara WordPress: localizar el plugin e insertar traducciones (cuarta parte)

September 05, 2016 08:11 AM

simterm
Estoy haciendo un pequeño tutorial de cómo me lo he montado para crear un plugin de WordPress: simterm. Podéis echar un vistazo al plugin desde la página anterior, y probarlo si queréis :)

Esta es la cuarta parte, enfocada a la localización de plugins. Podéis acceder desde aquí a:

  • Primera parte. Introducción y conceptos básicos de plugins de WordPress y algunas manías personales.
  • Segunda parte. Enfocada a la pantalla de configuración de nuestro plugin.
  • Tercera parte. Enfocada a la inclusión de recursos CSS y JS y a los shortcodes.

El proceso de localización (l10n) de WordPress está basado en los principios de gettext. Si quieres, puedes ver otros posts de traducciones con gettext aquí: Traducciones Gettext para nuestros proyectos en PHP y 5 consejos para internacionalizar nuestros programas con gettext en PHP). De todas formas, WordPress tiene sus propias herramientas, parecidas, pero propias.

El proceso de localización de un plugin

La localización se basa en archivos .po y .mo que podemos editar con poedit (ver los posts enlazados un poco más arriba). En estos ficheros habrá una asociación entre el mensaje en un idioma neutral (yo suelo utilizarlo en inglés) y los mismos mensajes en un idioma de destino. Esto nos facilitará la vida a la hora de crear el código, puesto que sólo tenemos que escribir en un idioma, olvidándonos de establecer convenciones, ni crear variables específicas ni nada, sólo añadiendo una función. Lo más importante que tenemos que tener en cuenta es el dominio de las traducciones. Este dominio será algo así como nuestro módulo (plugin, tema, parte en la que utilizamos la traducción), y luego el idioma, en mi caso es_ES (que será español-España, como también tendremos es_MX (para español Mexico), es_AR (español Argentina), etc.

Para ordenar un poco nuestros archivos, dentro del directorio o carpeta del plugin crearemos otro directorio llamado langs/ (o languages/, l10n/, etc), el objetivo de esto es separar los archivos de nuestro plugin de las traducciones. Los archivos de las traducciones, si por ejemplo nuestro dominio (que podemos darle el mismo nombre que al plugin), se llama myplugin, los archivos de traducción se llamarían:

Para español España
langs/myplugin-es_ES.po
langs/myplugin-es_ES.mo
Para francés de Francia
langs/myplugin-fr_FR.po
langs/myplugin-fr_FR.mo
Para chino de Singapur
langs/myplugin-zh_SG.po
langs/myplugin-zh_SG.mo

Algo muy bueno que tiene este sistema es que si alguien quiere traducir el plugin, no tiene por qué saber PHP, ni tiene que pelearse con los archivos del plugin. Sólo tiene que generar los archivos .po y .mo

Lo que tenemos que hacer en el código

En nuestro plugin, tenemos que decir de alguna forma que es traducible, y decirle el dominio de traducciones del que hemos hablado antes. Además, en WordPress hay que decírselo dos veces (tiene su lógica).

La primera vez que hay que hablarle a WordPress sobre traducciones es para que cuando un plugin no esté instalado, sepa de dónde sacar sus mensajes. Sobre todo para la descripción del plugin, para que ésta pueda escribirse en el idioma que debe, que esto queda muy bien. Para ello tenemos que escribir esto en el archivo principal de nuestro plugin (donde están las cabeceras), fijémonos sólo en Text Domain y Domain Path:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
/**
 * Plugin Name: SimTerm
 * Plugin URI:  http://gaspar.totaki.com/en/php-project/simterm/
 * Description: Simulates terminal input/output for tutorials
 * Version: 0.1.0
 * Author: Gaspar Fernández
 * Author URI: http://totaki.com/poesiabinaria/
 * License: GPL3
 * Text Domain: simterm
 * Domain Path: /languages/
 */

Text Domain especifica el dominio, y se llama casi igual que el plugin, pero todo en minúsculas. Podría tener el nombre que quisiéramos, pero debe ser único para todo WordPress si no queremos que éste se confunda buscando las traducciones.
Domain Path especifica el directorio dentro del plugin donde están los archivos de traducciones.

La segunda vez que le hablamos a WordPress sobre traducciones, debe ser nada más cargado el plugin, escribiendo algo como esto:

1
2
<?php
  load_plugin_textdomain( 'simterm', false, dirname( plugin_basename( __FILE__ ) ).'/languages/' );

Con esta línea hacemos que se cargue el dominio de traducciones, en la ruta especificada para nuestro plugin, cuando éste ya está cargado. Es decir, esto es lo más importante.

Aunque el dominio puede que no siempre nos interese cargarlo. Si nuestro plugin, sólo es accesible desde administración (o los mensajes traducibles los escribe en la zona de administración podemos cargarlo de la siguiente forma:

1
2
3
4
5
6
7
<?php
add_action( 'admin_init', 'load_textdomain' );

function load_textdomain()
{
  load_plugin_textdomain( 'simterm', FALSE, dirname( plugin_basename( __FILE__ ) ).'/languages/' );
}

Por lo que sólo se cargará cuando se inicialice la zona de administración. Si, por ejemplo en add_action() sólo ponemos ‘init’, se cargará siempre.

Cuando quiero que un texto se traduzca…

Tenemos que escribir algo más que el propio texto. WordPress utiliza entre otros, la función __() que tiene dos argumentos. El primero es el texto a traducir, y el segundo el dominio. Por lo que cada cosa que queramos traducir quedaría:

1
2
<?php
echo __('Plugin options', 'simterm');

Y se representará en el idioma del WordPress en que se ejecute (si dicho idioma está disponible en nuestro plugin), o en el idioma original (si el idioma no se encuentra).

Encontramos varias funciones de WordPress para representar traducciones, además de __() que presenta una traducción simple, es decir, un texto en un idioma original por un texto traducido. Tenemos:

  • _e($texto, $dominio) : que es lo mismo que echo __($texto, $dominio);
  • _n($singular, $plural, $numero, $dominio) : presentará una traducción en función de $numero ya sea 1 o superior, para especificar plurales.
  • _x($texto, $contexto, $dominio) : Selecciona la mejor traducción en función del contexto, porque una misma palabra puede significar varias cosas y eso hace las traducciones muy duras.
  • Hay muchoss más, incluso existen esc_html__(), esc_html_x() para devolver cadenas escapadas, y mucho más.

Cuando queremos traducir un texto con variables dentro…

Un texto con variables puede ser. “Tu IP real es: xxx.xxx.xxx.xxx” por lo que, dentro del mensaje traducido debemos escribir algo que de paso a la variable. Esto lo podemos hacer con sprintf() de la siguiente forma:

1
2
<?php
echo sprintf(__('Tu IP real es %s', 'dominio'), $ip);

El problema aquí viene cuando hay varias variables. Como “Tu IP real es xxx.xxx.xxx.xxx y conectas desde: España”, en algunos idiomas puede tener más sentido decir: “Conectas desde España con esta IP: xxx.xxx.xxx.xxx” y con el uso habitual de sprintf podemos tener un problema, ya que depende de la posición donde se encuentre la variable. Aunque podríamos hacer lo siguiente:

1
2
<?php
echo sprintf(__('Tu IP real es %s$2 y conectas desde: %s$1', 'dominio'), $pais, $ip);

Es recomendable, si utilizamos programas que automáticamente recorran los textos traducibles (como poedit) hacer una llamada a __($texto, $dominio) siendo $texto la descripción de nuestro plugin, tal y como aparece en el comentario principal. Así el programa nos detectará la traducción.

Una pequeña advertencia

Si en tu plugin, vas a poner URLs, como URL de donación, de la página de tu plugin, tu e-mail (no es recomendable, pero quién sabe), nombre de la licencia, tu nombre, etc. Utiliza variables para ello y no las incluyas en la traducción. Puede que un traductor a un idioma extraño del que no tengas ni idea cambie algún dato.

Hasta aquí una breve introducción…

Si queréis más documentación, podéis visitar la página de internacionalización de WordPress.

The post Creando un plugin epara WordPress: localizar el plugin e insertar traducciones (cuarta parte) appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Koalite

Conviviendo con la Ley de Conway

September 05, 2016 05:06 AM

Según la Wikipedia, la Ley de Conway dice que las organizaciones que diseñan sistemas sólo pueden producir diseños que repliquen las estructuras de comunicación de la propia organización.

Quizá la forma más gráfica de verlo es este ejemplo de Eric S. Raymond:

Si tienes cuatro equipos de trabajando desarrollando un compilador, lo que conseguirás es un compilador de 4 fases.

Es razonable. Para hacer que un sistema funcione, todos los que participan en su desarrollo deben comunicarse para poder colaborar y los canales de comunicación marcarán mucho lo que se puede hacer y lo que no. Si quieres poner tres equipos separados a trabajar en el proyecto, no te quedarán muchas más opciones que dividirlo en, al menos, tres bloques independientes en los que puedan trabajar esos equipos, desacoplando al máximo esos bloques y estableciendo unos interfaces rígidos entre ellos.

No hace falta pensar en empresas muy grandes para que ocurra esto. Cualquiera que haya tenido que integrar su software con el de otras empresas lo habrá vivido. Acabas colaborando con distintos departamentos de desarrollo y eso te lleva a diseños que permitan acotar muy bien la responsabilidad de cada uno. Es mucho más fácil coordinarse entre varias empresas para desarrollar un sistema distribuido que para hacer una aplicación monolítica, incluso aunque la solución más simple al problema fuese hacer una única aplicación monolítica.

Todo esto además se manifiesta en los distintos niveles del diseño, desde la arquitectura general el sistema, hasta la separación del código en módulos, clases, métodos o funciones. Si estás programando por parejas con un compañero en la implementación de un módulo y decidís que es mejor poder avanzar en paralelo, acabaréis acordando alguna estructura (por ejemplo, clases) con un interfaz fijo que os permita separaros y seguir programando cada uno por vuestro lado. Si os hubieseis mantenido juntos, tal vez no hubiera sido necesaria ese interfaz y el diseño podría haber sido diferente.

Las consecuencias negativas

En ocasiones se percibe la Lay de Conway como algo negativo, y lo cierto es que puede llegar a serlo.

Un caso claro es el que comentábamos antes de la coordinación de varias empresas, donde llegar a una colaboración muy estrecha a nivel de código es sumamente complejo y la única opción viable muchas veces es partir el sistema en tantos subsistemas como empresas estén colaborando, independientemente de que sea la mejor opción.

Otro caso frecuente se produce cuando tenemos equipos muy especializados. Por ejemplo, muchas veces la gente encargada del diseño gráfico no es la misma que la encargada del desarrollo, y si analizas el código casi puedes ver una línea clarísima que separa las partes hechas por cada uno. Esto hace que cuando hay que realizar cambios sea todo mucho menos ágil y que la experiencia de usuario se resienta porque hace falta separar muy bien la parte de diseño de la parte de implementación para que ambos equipos puedan trabajar por separado.

Pero el caso más paradigmático es, sin duda, el de las empresas formadas por “expertos” en determinadas tecnologías, que además suelen son “Golden Enterpise Partner” de los fabricantes de turno. Si una empresa tiene un equipo de SharePoint Ninjas, otro de Dynamics Samurais y algunos Azure Rockstars, puedes estar seguro de cuál será la solución que darán a cualquier problema. Ley de Conway en su máxima expresión.

Asumir lo inevitable

Tampoco hay que ver la Ley de Conway como algo necesariamente negativo. Más bien hay que verlo como algo inevitable. Algo que no es ni bueno ni malo, simplemente, es, y hay que aprender a vivir con ello.

En un mundo ideal, cada vez que afrontásemos un desarrollo podríamos reconfigurar la organización que lo lleva a cabo para alinearla con los requisitos del desarrollo y alcanzar la solución óptima de la manera más eficiente posible.

Pero claro, eso es en un mundo ideal.

En el mundo real, trabajamos en estructuras ya creadas que no podemos cambiar de la noche a la mañana, y es mejor ser consciente de los puntos fuertes y débiles de estas estructuras para intentar aprovecharlos a nuestro favor, o al menos intentar que nos frenen lo menos posible.

Eso no quiere decir que no puedas o no debas intentar mejorar la estructura de la organización para adecuarla al tipo de productos o proyectos que desarrollas, pero igual que reescribir una aplicación desde cero suele ser una mala salida y es mejor ir haciendo mejoras incrementales, en este caso suele ser más fácil realizar cambios graduales que montar una revolución.

En función de cómo esté organizada la empresa, hay arquitecturas que pueden resultar más adecuadas que otras. Por ejemplo, una arquitectura basada en microservicios puede ser muy práctica cuando necesitamos repartir el trabajo entre muchos equipos casi independientes. Sin embargo, si se trata de un equipo pequeño, que mantiene una comunicación muy estrecha, apostar por un monolito majestuoso puede suponer un sistema más sencillo de comprender y desplegar.

Es similar a lo que ocurre con lenguajes de programación. Puede que tu proyecto se preste especialmente a desarrollarlo sobre Erlang, pero si tienes un equipo de 20 personas para hacerlo y ninguno tiene ni idea de Erlang, tal vez sea preferible buscar otra alternativa antes que despedir a todo el equipo y contratar un grupo de expertos en Erlang.

Por otra parte, ir ajustando la estructura de la empresa al tipo de desarrollos que suele realizar permite mejorar la eficiencia. Por ejemplo, si nuestros desarrollos implican el desarrollo de backends y aplicaciones para dispositivos móviles, parece razonable poder trabajar en paralelo en ambas y tener equipos preparados para ello. O si desarrollamos 4 productos diferentes, poder avanzar en todos ellos simultáneamente.

Ello no tiene por qué acabar en una especialización excesiva de los miembros del equipo (de la que no soy muy partidario, por aquello de tener equipos tolerantes a fallos). Es posible que las mismas personas asuman (o compartan) distintos roles en función del proyecto.

Conclusiones

La estructura del sitio en que trabajamos va a afectar a la forma en que desarrollamos. Eso es algo inevitable y que debemos tener en cuenta a la hora de tomar decisiones sobre el diseño de una aplicación.

No podemos pretender cambiar por completo la estructura y la forma de trabajar de un sitio sólo porque se haya puesto de moda una arquitectura o metodología de trabajo determinado, pero tampoco debemos ser excesivamente conformistas y, si la entorno existente no permite resolver los problemas de manera eficiente, habrá que buscar la forma de cambiarlo.

Al final, como siempre, se trata de buscar un compromiso que nos permita sacar partido a lo que ya tenemos mientras lo vamos mejorando. Nadar y guardar la ropa, que diría mi abuelo.

No hay posts relacionados.

» Leer más, comentarios, etc...

Navegapolis

Scrum Level: Evaluación y mejora de la agilidad

September 04, 2016 08:52 AM

scrum level portadaCon el nombre de Scrum Level hemos reunido y estructurado el conocimiento para la gestión ágil de proyectos, equipos y organizaciones sintetizado durante estos años en Scrum Manager, y empleado en proyectos reales de asesoría y mejora a empresas, por el equipo de profesores y colaboradores.

Hemos preparado con ilusión el material para difundirlo y compartirlo de forma abierta con todos los profesionales a los que os pueda resultar útil para conocer el nivel de agilidad en una organización, y cómo mejorarlo.
Está ya disponible en versión 1.0 en scrumlevel.com.

Como promotor y parte del equipo que lo ha hecho posible, espero que sea útil :-)

 

» Leer más, comentarios, etc...

Blog Bitix

Sobre los ínfimos impuestos que paga Apple

September 02, 2016 09:30 PM

Apple

El 30 de agosto de 2016 la Comisión Europea anunciaba que Apple debía devolver a Irlanda la cantidad correspondiente obtenida por las ventajas fiscales que considera irregulares, una cantidad astronómica de unos 13000 millones de euros mas los intereses desde 2003. Si ya Irlanda ofrece una fiscalidad ventajosa al tener un tipo impositivo del 12,5% de los beneficios, Apple con acuerdos conseguía pagar un 1% y un 0,005%. Acuerdos que la comisión Europea considera irregulares porque solo se aplica a algunas empresas como Apple siendo una desventaja y trato de favor respecto a otras empresas establecidas en Irlanda. Esta fiscalidad ventajosa es el motivo de que otras muchas empresas tecnológicas de EEUU tengan su sede europea en Irlanda, en España por ejemplo debería haber pagado un 25%.

Algunos medios informaban así de la noticia:

Horas después Apple en su web publicaba una carta firmada por Tim Cook indicando lo mucho que contribuye en empleos e inversiones en Europa que se verán amenazadas además de afirmar que no ha recibido ninguna ventaja fiscal de la que se le acusa.

Carta de Apple a su comunidad en Europa

Hasta aquí los hechos.

Lo primero que hay que destacar es que en realidad la Comisión Europea no le pone una multa a Apple ni a Irlanda por cometer una irregularidad sino que simplemente le obliga a devolver lo que debería haber pagado y no durante todo el tiempo que cometió la irregularidad sino simplemente desde el 2003, las ventajas fiscales se remontan a 1991. Pagar menos impuestos de los que debe le sale barato a Apple, si no le obligan esos miles de millones que no paga en impuestos, si le obligan solo tiene que devolver lo que debería haber pagado igual que si no hubiera hecho la trampa y solo a partir de una fecha en que la situación no ha prescrito. Toda una oportunidad para obtener máximos beneficios.

La carta de Tim Cook demuestra el tono con el que actúa y por el medio en el que la publica, en su propio sitio web, parece más bien dirigida a salvar su imagen entre sus usuarios y clientes que a la Comisión Europea. «la dirección de Apple supo ver un lugar rico en talento» a lo que seguidamente se atribuye también ser ejemplo para otras multinacionales, ya sería más bien por las ventajas fiscales del lugar. Un buena parte de la carta está dirigida a expresar la cantidad de empleos e inversión que según Apple genera ya sea directamente, que solo son unos paupérrimos 6000 para su volumen de negocio, y un millón y medio según ellos entre desarrolladores de aplicaciones y pequeñas y medianas empresas que dependen de Apple. Por este mensaje parece que Apple se debe consentir su irregularidad en aras de mantener esta actividad que alardea de generar. En la carta por supuesto dice que su ingeniería fiscal está de acuerdo a la legalidad y que no ha recibido las ventajas fiscales de las que le acusa la Comisión Europea. Comisión Europea que no debe estar de acuerdo después de años de observación e investigación.

Apple junto con Estados Unidos e Irlanda recurrirán la resolución. Irlanda con su tipo impositivo reducido y prácticamente inexistente para Apple en 2010 fué rescatada por importe de 45000 millones de euros. Estados Unidos interviniendo en un asunto para proteger los intereses de una de sus empresas más grandes. Y todo esto sin el infame acuerdo de inversiones y libre comercio TTIP que el estado norteamericano quiere acordar con la Unión Europea con el que esta disputa se resolvería en un tribunal supranacional que reduciría la soberanía de la Unión Europea y sus estados miembro. Parece que son los EEUU los que más intereses tienen y rápido en aprobar el TTIP ya que con seguridad les sea muy y más ventajoso para ellos y sus empresas. En época de paz una forma de dominio y nueva forma de guerra fría es la económica. Si EEUU es capaz de espiar a ciudadanos y presidentes de gobiernos aliados no sería de extrañar que espiase también a empresas extranjeras para proteger a la suyas y darles ventajas competitivas o su economía capitalista.

En este caso la elegida ha sido Apple siendo la empresa de referencia pero otras empresas tecnológicas norteamericanas emplean la misma ingeniería fiscal para reducir a la mínima expresión los impuestos que pagan en sus actividades en todo el continente europeo. ¿Habrá alguna siguiente obligada a pagar los impuestos que le correpondían?. Ingeniería fiscal que no está al alcance de las pequeñas y medianas empresas ni de los ciudadanos y por ello es injusta. No es casualidad y tampoco es porque los irlandeses sean especialmente listos, talentosos o más trabajadores que otras empresas como Microsoft, Google, Amazon o Facebook entre otras grandes también tengan su sede europea en Irlanda.

Hay otras disputas como en el caso de Google acusada de monopolio en Europa que puede acarrearle en este caso sí alguna cuantiosa sanción económica. O la privacidad de los ciudadanos europeos por parte de Facebook.

Es tu decisión y responsabilidad también sabiendo esta información de que empresas y productos consumes. Si esta es la legalidad no se a que esperan los políticos honestos, con coraje y determinación para cambiarla y hacerla justa.

» Leer más, comentarios, etc...

Adrianistán

Phaser.js Hispano, aprende a hacer videojuegos en HTML5

September 01, 2016 09:00 AM

Phaser.js Hispano es un sitio web, de mi propia creación, donde escribo tutoriales para aprender a usar Phaser, una de las librerías más populares para crear juegos 2D con JavaScript.

Phaser

Su éxito se basa en su simplicidad. No trata de reinventar la rueda con conceptos extraños e innovadores. Simplemente hace lo que muchas otras librerías hacen, de un modo claro, sin complicaciones. Fue creado por Richard Davey, alias photonstorm. Comenzó como una librería privada suya, pues él realiza juegos de navegador como trabajo. Con el tiempo fue mejorando, se hizo opensource y ahora cuenta con muchos usuarios aunque gran parte del desarrollo lo sigue realizando Richard. El motor ha sido usado con éxito en infinidad de juegos y a día de hoy me parece la opción más madura y efectiva de realizar un juego HTML5 con JavaScript.

Phaser usa Pixi.js como motor de renderizado, lo que permite a los juegos usar WebGL o Canvas 2D indistintamente. Además si manejas Pixi verás que algunas partes de la API de Phaser son similares. Los juegos funcionan en cualquier dispositivo que soporte HTML5, desde ordenadores de mesa (Windows/Mac/Linux) hasta televisores y consolas (WiiU, Xbox One, Chromecast,…) pasando por los omnipresentes móviles y tablets, que a día de hoy son las plataformas que prefieren los jugadores para jugar a juegos sencillos, de poca profundidad.

¿Estas listo para probar Phaser? He realizado una lista con, al menos, los elementos de los que me gustaría tratar en la web Phaser.js Hispano. La Gran Guía de Phaser en Español, úsalo como índice para tus consultas. Si tienes alguna duda no dudes en expresarla. ¿Quiéres tratar algún tema en particular? ¿Conocías la librería antes?

La entrada Phaser.js Hispano, aprende a hacer videojuegos en HTML5 aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Jesús Perales

Zte volumen bajo

August 30, 2016 08:35 PM

Zte volumen bajo

Un problema en mi celular ZTE Blade A475 es que no se escucha al conectarlo a el auxiliar de mi auto.

Para solucionarlo es necesario ir al modo ingeniero (Enginner Mode) a el cual se llega ya sea tecleando *#*#3646633*#*#* en la aplicación del teléfono o bajando una aplicación en Google Play.

Zte volumen bajo

Si utilizamos la aplicación para acceder al modo ingeniero debemos seleccionar la opción MTK Settings.

Zte volumen bajo

Vamos a el apartado de Hardware Testing y seleccionamos Audio.

Zte volumen bajo

Ahora seleccionamos la opción Headset Mode

Zte volumen bajo

El campo de Max Vol. 0~160 lo podemos poner con el valor de 104 o 105, cualquiera de los 2 funciona, y presionar SET.

Zte volumen bajo

Listo ya se debería escuchar el celular al conectarlo por auxiliares, esto fue probado en un ZTE Blade A475.

Fuente

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin