lunes, 7 de octubre de 2013

Introducción al JavaScript (5)


Ya vimos en su día las funciones y que estas nos permitían reutilizar bloques de código... Pero no es práctico repetir 1000 veces una función. La idea es aprender mecanismos que nos permitan repetir cosas con cabeza... bucles!

for

El bucle for se suele utilizar cuando conocemos o podemos conocer el número de veces que vamos a repetir alguna cosa...

var i;
for (i=0; i<11; i++)
{
document.write(i);
}

Eso nos daría como resultado 012345678910, que no es que sea útil...

La idea es que el bucle for indica su condición inicial, su condición de parada (o de continuidad...) y su variación en el parámetro. En el ejemplo, establecemos una variable de control i que se inicializa a 0 y que, mientras sea menor que 11 hará lo que hemos puesto entre llaves. Tras cada pasada hará i++.


NOTA: i++ es lo mismo que i=i+1 y, en algunos lenguajes, que i+=1. Esto último, lo del i+=1, es el tipo de cosas que cuando las escribo me imagino a alguien diciendo "Noooooooo! Pero que diceeeeees!". Pero bueno, no voy a comprobarlo porque tampoco es que estemos siendo muy técnicos en esta introducción. Lo probáis y si no funciona, me ponéis un comentario pidiendo que os devuelva el dinero... Oh! Wait!... (Vaya día que llevo...)


NOTA: Mua ha ha ha ha! (Thunderclap) Me acabo de dar cuenta de que estoy utilizando el verbo "inicializar" y el corrector no lo reconoce. Pero existe.



while


La otra opción que tenemos es while. Si le damos vueltas, casi todo (por no decir todo) lo que se hace con for se puede hacer con while. La filosofía es distinta. Primero inicializo, luego hago el bucle y dentro del mismo bucle realizo el incremento (o decremento... o gestión) de la variable de control

var i = 0;
while ( i < 11)
{
document.write(i);
i++;
}

Que es equivalente a lo anterior.


NOTA: ¡Aviso a los navegantes! Si no gestionamos bien la variable de control, podemos hacer lo que se llama un bucle infinito, o un bucle del que no podemos salir nunca... jamás... hasta que el ordenador se queda sin memoria o el navegador decide que pasa de nosotros... 


Mañana más... que llevo un día...

Introducción al JavaScript (4)

Las condiciones se basan en el álgebra de Boole. Esto es, en última instancia, la obtención de una respuesta binaria: verdadero o falso. Esta respuesta puede ser el resultado de una comparación o de la operación entra varias comparaciones.

Supongamos la variabla a con el valor 3...

a == 1
a != 1
a > 1
a < 1

NOTA: ¿Cómo se evalúan estos casos? La respuesta es falso, verdadero, verdadero, falso.


¿Y para que vale eso? Pues haciendo las preguntas concretas podemos obtener resultados interesantes.

Detectar el navegador

Pues resulta que en navigator.userAgent tenemos una cadena de texto que identifica el navegador.

alert(navigator.userAgent);

Luego tenemos la opción de poner esa cadena en minúsculas.

alert(navigator.userAgent.toLowerCase());

Y, si le preguntamos a esa cadena ¿en que posición pone "cacatúa"? de este modo...

alert(navigator.userAgent.toLowerCase().indexOf("cacatúa"));

El resultado será el número del carácter donde empieza a poner "cacatúa" o -1 si no existe ese elemento en nuestra cadena.

Condiciones

El tema es que sabemos que la cadena que hemos visto tiene que ser safari, chrome, firefox o msie... Podemos preguntar. La pregunta es si el resultado de la última instancia que hemos puesto es mayor que -1. Si es así, tenemos ese navegador, si no... pues tendremos otro.

Es decir...

if (navigator.userAgent.toLowerCase().indexOf("safari")> -1) document.write("Safari...");

if (navigator.userAgent.toLowerCase().indexOf("chrome")> -1) document.write("Chrome...");

if (navigator.userAgent.toLowerCase().indexOf("firefox")> -1) document.write("Firefox...");

if (navigator.userAgent.toLowerCase().indexOf("msie")> -1) document.write("Vade retro...");


NOTA: El cuadro tendría que mostrar el resultado del código anterior... Al menos a mi me sale "Safari..."

Hay formas más útiles de resolver condiciones múltiples... pero de momento nos sobra con esto. El tema es que si detectamos el tipo de navegador, podemos decidir en tiempo de representación qué archivo de CSS cargar en función del navegador.


NOTA: Si, lo se... hay otras formas... pero si realmente está pensando en eso es que estos tutoriales no son para ti...

Por cierto, antes de que se me olvide. Tras resolver una condición podemos hacer más de una cosa, poniéndolas entre {}

if (navigator.userAgent.toLowerCase().indexOf("msie")> -1)
{
document.write("D'Oh!");
alert("Perotuestassegurodeloqueestáshaciendocontuvidavayahombrepordios!!!");
}


NOTA: Lo del Internet Explorer me viene de la versión 6... si eres usuario del mismo, no te lo tomes como algo personal.


Además, podemos hacer otra cosa... es sacar una información si se cumple la condición y otra si no se cumple.


if (edad<=18)
{
document.write("Puedes pasar...");
}
else
{
document.write("NO puedes pasar...");
}


lunes, 30 de septiembre de 2013

Introducción al Javascript (3)

Los comportamientos que hemos visto ocurren en el punto donde se hace uso del script durante la carga. Lo que nos interesa es, por una parte, controlar que esas acciones ocurran bajo demanda y una vez cargada la página. Por otra parte, poder reutilizar las opciones. Para eso vamos a utilizar funciones.

Una función es un trozo de código reutilizable al que podemos llamar cuando queramos. Por ejemplo

<script>

function saluda()
{
alert("Hola");
}

saluda();

</script>

Con esto hemos definido la función saluda que no recibe ningún parámetro y que cada vez que la llamamos muestra una ventana de dialogo que dice "Hola". La llamada la hacemos con saluda();

Esto es poco útil. Si queremos que se muestre un mensaje concreto cada vez, podemos utilizar un parámetro...

<script>

function di(algo)
{
alert(algo);
}

di('Hola');

</script>

De esta forma , cuando usemos di('Hola') aparecerá una ventana de dialogo en la que pondrá Hola. Si usamos di('En un lugar de la mancha...') aparecerá una ventana de dialogo en la que pondrá En un lugar de la mancha...

También podemos utilizar varios parámetros. De esta forma:

<script>

function di(unaCosa, otraCosa)
{
alert(unaCosa+" "+otraCosa);
}

di('Hola', 'Mundo');
di('Mundo', 'Hola');


</script>

NOTA: Date cuenta de que entre las cadenas he metido otra cadena con un espacio en blanco... si no saldrían las dos cadenas pegadas. Pruébalo.

Tendrá como resultado dos ventanas, la primera dirá "Hola Mundo" y la segunda "Mundo Hola".

Ahora bien. Esto, puede ser útil para muchas cosas, pero parece más interesante si somos capaces de utilizarlo bajo demanda. Es decir, cuando se produzca un evento.

Por ejemplo, podemos utilizar el parámetro onClick en una etiqueta HTML para que se llame a una función cuando se haga click sobre el elemento.

<script>

function di(unaCosa, otraCosa)
{
alert(unaCosa+" "+otraCosa);
}


</script>

<div onClick="di('Hola','Caracola');">Dime cosas...</div>

En este ejemplo tenemos que cuando hacemos click en el DIV que contiene la frase Dime cosas... aparecerá el dialogo con la frase Hola Caracola

NOTA: Es importante tener en cuenta que cuando llamamos a una función, esta debe estar definida previamente. Eso es de vital importancia cuando tenemos que llamar a una función durante la carga. No podemos llamar a una función que no ha sido generada... PERO lo que estamos haciendo es llamar a la función cuando se hace click, esto es, después de la carga. Por lo que cualquier función del código ya habrá sido definida. En resumen, si utilizamos eventos como onClick, estos se ejecutan cuando el usuario hace click, por lo que la página ya ha sido cargada y la función ha sido definida en el código, tanto si estaba antes como si estaba después que la vinculación de la llamada al evento click.

Combinando esto con lo visto con anterioridad, podemos hacer un ejemplo en el que un bloque cambie su color de fondo cuando hacemos click sobre otros bloques...

<script>
function pintaDe(color)
{
var elemento;
elemento = document.getElementById("pizarra");
elemento.style.backgroundColor=color;
}
</script>

<div id="pizarra" style="width: 100px; height: 100px; border: 1px solid black"></div>


<span onClick="pintaDe('red')">R</span>
<span onClick="pintaDe('green')">G</span> 
<span onClick="pintaDe('blue')">B</span> 

Que si funciona aqui... tendremos:


R G B

Que vendría a ser lo mismo para el cambio de cualquier otra de las propiedades CSS. Pero que para que funcione tenemos que tener en cuenta de qué forma hay que pasar el parámetro. Es decir...

elemento.style.width espera un valor del tipo 100px
elemento.style.backgroundImage espera un valor del tipo url('imagen.jpg')
...



viernes, 27 de septiembre de 2013

Introducción al HTML 5 (1)


NOTA: Esto es introducción al HTML 5, no introducción al diseño de páginas web ni al HTML en general. Es decir, asumo un mínimo de conocimiento sobre el tema.

La estructura básica de una página web en HTML 5 se ha simplificado bastante. Ahora es algo tal que así:


<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Documento sin título</title>
  </head>

  <body>
  </body>
</html>

Grandes diferencias respecto al estructura básica de XHTML...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Documento sin título</title>
  </head>

  <body>
  </body>
</html>

Que parece un tanto más complejo ¿no?

Seguimos teniendo las dos partes claves diferenciadas HEAD, que contiene todas aquellas cosas previas a la carga de la página y que son necesarias para la correcta interpretación de la misma y BODY, que es el lienzo en el que creamos nuestra página web.


miércoles, 25 de septiembre de 2013

Seguridad en dispositivos iOS (1)

Últimamente he estado repasando conceptos de seguridad en dispositivos iOS y hay algo que me ha resultado tremendamente curioso. El sistema de cifrado de datos. La verdad es que no soy un experto en la materia y no se si realmente el sistema en si es avanzado, bueno o una castaña. Pero me parece bastante interesante.

La idea general es enrevesada, así que voy a tratar de aproximarla mediante una serie de pasos consecutivos.

Pongamos que queremos hacernos con el contenido de un archivo. ¿Qué pasos se siguen para acceder al mismo?.

Un disco duro cifrado

Lo primero es que el disco duro está cifrado por hardware gracias al uso de un sistema integrado entre la memoria y el disco duro. Esto hace que todos los archivos que se utilizan pasen por un filtro de cifrado / descifrado del que solo conocemos los resultados al realizarse con un parámetro grabado en el interior de un chip y al que no podemos acceder.

Esto hace que para ver los contenidos tengamos que pasar por ese camino, es decir, estar en el mismo teléfono. Nada de sacar el disco duro y acceder a el desde fuera.

Un cifrado por archivo

Además, cada vez que queremos guardar un archivo se genera un cifrado basado en un número aleatorio que se guarda en los metadatos del archivo. Los metadatos del archivo son cifrados por un código que se guarda en el disco duro. Este no tiene como objetivo la seguridad, sino la posibilidad de hacer un "borrado" total de datos al eliminarlo del disco. En ese caso, no es que se borren los datos, sino que no se puede descifrar.

Volviendo a los metadatos, sus contenidos son tambien cifrados mediante algo llamado clases. Esto define el nivel de seguridad del archivo y las condiciones para descrifrarlo. De esta forma, se precisará o no un código por parte del usuario.

En conclusión

Si necesitamos descifrar un archivo de bajo nivel de seguridad, prácticamente se descifrará solo, sin embargo, si es un archivo de alto nivel de seguridad precisará interacción del usuario. El proceso es utilizar un código único del dispositivo y el guardado en el disco duro para descifrar los metadatos, obtener el tipo de clase, descifrar el tipo de clase a través del código único del dispositivo y/o del código introducido por el usuario, obtendremos entonces el código de cifrado único del archivo y podremos descifrar el contenido del mismo. Todo esto, teniendo en cuenta que para pasar del disco duro a memoria, los datos deben descifrarse con el sistema hardware que lleva el teléfono y que únicamente funcionarán en el mismo teléfono

Así que...

Es complicado y no se si he sido suficientemente preciso. Pero la idea a transmitir creo que la pillaréis...

lunes, 23 de septiembre de 2013

Introducción al JavaScript (2)

Cuando vamos a trabajar con un lenguaje de programación, es normalmente imprescindible el uso de variables. Las variables son como etiquetas que hacen referencia a un contenido y que se pueden utilizar de manera indistinta en lugar del mismo.

Es una idea parecida a las incógnitas de matemáticas. Pongamos el siguiente ejemplo (tranqui, que verás como lo entiendes...)

X + 1 = 3
X = 2

Creo que eso lo pueden entender ¿no?. Pues solo hace falta darle la vuelta.

X = 2
X + 1 = 3

Lo que hacemos es asignar a X el valor de 2 y cuando operamos X + 1 es como si dijeramos 2+1 que equivaldrá a decir 3. Si seguimos por ese camino

X = 2
X + 1 = 3
X = 3
X + 1 = 4

Si no lo entiendes, juega con este script...

var x = 1;
document.write(x+1);

NOTA: No es necesario poner ; al final de cada línea, pero no es una mala práctica. Así mismo, si quieres cambiar el valor de x, verás que cambia el valor del resultado.

De momento, vamos a considerar los siguientes tipos de variables:

Tipo 1 - Variables a las que damos un valor forzado y legible por seres humanos

var nombre = "Pedro";
var nombreCompleto = "Pedro Jimenez";
var edad = 33;
var saldoEnElBanco = -10.56;

NOTA: Escribir las cosa de forma que "una frase con palabras" lo pongamos como "unaFraseConPalabras" es una técnica conocida como camel writting.

Estamos considerando cadenas de texto (entre comillas dobles), números enteros (positivos y negativos) y números de coma flotante (con decimales, positivos y negativos).

document.write(nombreCompleto+" tiene "+edad+" años.");

NOTA: Podemos concatenar (representar una cadena como la suma de otras cadenas) indistintamente variables de distintos tipos. Acuérdate de poner espacios donde toque...

Tipo 2 - Variables a las que el usuario da un valor a partir de una ventana (dialogo) del navegador

var nombre = prompt("Dime como te llamas", "Escribe aquí tu nombre");

NOTA: Lo que estamos usando es una función. Esta función toma dos valores (dos cadenas de texto). El primero es el texto que nos muestra en la ventana. El segundo es el valor con el que rellena el campo  de texto que aparece y que podemos editar. Las funciones, hacen cosas a partir de unos parámetros y devuelven un resultado. Esto significa que si ponemos una variable y le asignamos el valor de la función, lo que el usuario escriba se pondrá como valor de la función.

Tipo 3 - Variables más complejas que representan elementos HTML

<body>
  <div id="bloque">Esto es un bloque</div>
  <script>
    var elBloque = document.getElementById("bloque");
  </script>
</body>

No podemos actuar sobre un elemento HTML que no existe. Es por eso que antes de definir el valor de la variable elBloque hemos creado un DIV que tiene el id correspondiente.

Ahora podríamos mostrar su contenido...

alert(elBloque.innerHTML);

...escribir su contenido...

elBloque.innerHTML = "Este es el nuevo contenido";

...manipular su CSS...

elBloque.style.backgroundColor = "red";

NOTA: Para manipular el CSS necesitamos dos cosas fundamentales. La primera es SABER cómo se establecen los valores de CSS porque pasar un valor erróneo tendrá como resultado un comportamiento erróneo. La segunda es utilizar un software que autocomplete. De esta forma, cuando escribamos elBloque.style. recibiremos un listado de opciones con los nombres de los parámetros CSS que podemos modificar.

Bonus track...

En relación a la última nota. Un software que pinta bien (aunque está en desarrollo) es Brackets. Se trata de un editor opensource y gratuito que fue creado y es mantenido por Adobe.


Introducción al JavaScript (1)

El JavaScript es un lenguaje de programación interpretado (frente a los lenguajes compilados) que se utiliza para conseguir comportamientos dinámicos en las páginas web. A pesar de que puede ser utilizado desde le lado del servidor, de momento nos vamos a centrar en el lado del cliente.

El javascript será leido por el navegador de la misma manera que este va leyendo e interpretando el HTML de la página web. Esto implicará una serie de cosas que, de momento, nos dan igual. Es decir, como estamos introduciendo conceptos nos tomaremos la licencia de ir paso a paso aunque esto implique asumir cosas que más adelante no serán ciertas.

Lo primero que tenemos que entender es dónde escribimos el código de JavaScript. Para ello, y dado que es un lenguaje complementario del HTML de las páginas web (Quien dice HTML dice XHTML...). Por lo que es necesario tener conocimientos de HTML (y CSS, ya que estamos) para poder aprovechar todo esto en su justa medida.

Dicho esto, la estructura fundamental de una página web se forma a partir de una etiqueta HTML que contienen dos etiquetas llamadas HEAD y BODY, cada una de estas contendrá otras, etc.

NOTA: Por convenio (o como se diga), se utilizan minúsculas para escribir las TAGS.

<html>
  <head>
    <title>Título de la web</title>
  </head>
  <body>
  </body>
</html>

De momento, todo el JavaScript que vamos a utilizar se introducirá en BODY (eso significa que escribiremos el JavaScript entre <body> y </body>).

...
<body>
Aquí es donde escribiremos el JavaScript
</body>
...

Además, hemos de tener en cuenta que el navegador necesita saber que estamos escribiendo en JavaScript para interpretarlo correctamente. Para esto tendremos que hacer uso de la etiqueta SCRIPT. En HTML 5, el lenguaje por defecto para un script (trozo de código a interpretar) por defecto es JavaScript. Por eso, no será necesario indicarlo. Pero XHTML si que lo tendremos que poner.

NOTA: Asumimos que los seres humanos escribimos páginas web en XHTML 1.1 o en HTML 5

<body>
  <script type="text/javascript">
    // Aquí va el código
  </script>
</body>

NOTA: Cuando ponemos "//" al comienzo de una línea, eso es un comentario y no se interpretará como código. Se ignorará.

Lo primero que vamos a aprender es a "sacar" datos por pantalla. Para esto tenemos dos opciones. La primera es que el navegador nos muestre una ventana flotante con la información que queremos mostrar. La segunda es que esa información sea mostrada como parte de la página web (de ahí que lo hagamos todo dentro de BODY)

Opción 1

alert("Hola Mundo!");

Opción 2

document.write("Hola Mundo!");


jueves, 2 de mayo de 2013

Certificados

Una cuestión que me ha llegado al buzón sobre este tema requería esta explicación. Me ha parecido interesante compartirla.

Cuando tenemos un Server instalado en Mountain Lion (es el caso concreto del que estamos hablando pero estoy seguro de que esto es extrapolable a otras versiones o sistemas), es más que probable que vayamos a proporcionar servicios a usuarios. En el caso que contemplamos, se trataría de servicios a múltiples usuarios que no van a acceder a la máquina de manera local y servicios cuya comunicación querremos proteger.

Punto por punto

Tras instalar el servidor, tendremos que decidir qué servicios queremos proporcionar. Si vamos a trabajar con múltiples usuarios, una opción más que interesante es la de activar el servicio de Open Directory para gestionar las cuentas de usuarios. Podríamos utilizar los usuarios locales de la máquina como usuarios "de red" y trabajar con ellos. Pero dependiendo de la complejidad de la estructura de usuarios que queramos montar podría ser desaconsejable. Por ejemplo, el Open Directory me va a permitir la gestión de perfiles de configuración para máquinas o grupos de máquinas.

En general, un servicio que queramos proteger, utilizará un certificado. Este certificado, si lo generamos directamente será un certificado autofirmado. Si queremos que se use ese certificado para proteger la comunicación con un servicio, el usuario final debe confiar en el servicio. Nuevamente dependiendo del número de usuarios esto será un proceso más sencillo o más complejo. Por ejemplo, si simplemente utilizamos los servicios como algo personal (correo, compartir archivos...) en nuestros equipos, podemos configurarlos manualmente para que confíen en el certificado.

Si, por el contrario, queremos trabajar con más usuarios y, o bien no tienen el conocimiento necesario para configurar los certificados como confiables o bien son demasiados, podemos hacer dos cosas.

La primera sería hacer que nuestros certificados fueran confiables de serie. Para eso hemos de recurrir a una entidad certificadora (raiz o intermedia) que garantice la confiabilidad de nuestro certificado. Eso puede costar dinero.

La segunda sería generar un único certificado raiz propio que garantizara la procedencia del resto de nuestros certificados. Eso es gratis. Pero sigue teniendo el problema de que nuestros usuarios tienen que confiar en esa entidad certificadora propia (no confiable de serie).

Veo mucho "confiable" y "certificado" en los párrafos anteriores. Recapitulemos.

- Accedo a un servicio.
- La comunicación está protegida por un certificado.
- Si el certificado viene avalado por una entidad certificadora raíz (CA) en la que confío, la confianza es  heredada. Hay una cadena de confianza.
- Si no viene avalado por una entidad certificadora en la que confíe (puede ser autofirmado o firmado por una entidad certificadora que no conozca...) tendré que confiar en el de serie.

Ahora bien, si yo genero mi propia entidad certificadora, podré firmar tantos certificados como quiera y serán todos confiables... siempre y cuando confíe en la entidad certificadora.

¿Cómo creo mi propia entidad certificadora?

Desde OS X 10.8 Mountain Lion (no me miréis así, es lo primero que he dicho...) utilizando Acceso a Llaveros (maravillosa utilidad). Podemos utilizar Acceso a Llaveros/Asistente para Certificados/Crear una autoridad de certificación...

Para generar una CA propia.

¿Cómo creo certificados que vengan avalados por mi propio CA?

Dos pasos. Primero solicitamos un certificado de una autoridad de certificación utilizando Solicitar un certificado de una autoridad de certificación... (dos líneas más abajo en el menú que acabamos de utilizar). Guardamos la solicitud en el disco duro. Segundo, utilizamos la opción Crear un certificado para otra persona como autoridad de certificación... (justo encima de la última que hemos utilizado). Nos pedirá que arrastremos el archivo que hemos guardado en el paso anterior y que seleccionemos la CA que queremos.

EDIT: O bien, en lugar de complicarme tanto, puedo crear un certificado seleccionando Terminal como Tipo de Certificado. Aquí cabe notar que Terminal es la traducción que se ha dado a Leaf. Que significa hoja. Entiendo que esto se debe a la estructura de árbol donde el CA es el certificado raíz.

¿Cómo instalamos el certificado raíz CA para que sea confiable en el resto de máquinas?

Lo normal, en el caso del que estamos hablando, es que los dispositivos realicen un proceso de enrollmente en el MDM que proporcione las configuraciones de los servicios que estamos ofreciendo. Instalado el certificado raíz y confiando en este, el resto de certificados que utilicemos deberían ser confiables.

Conclusión

Esto no es fácil. La teoría es lo que hay, pero pueden fallar cosas. Por ejemplo, al activar el Open Directory se creará un CA automáticamente. Y si luego queremos cambiarlo puede resultar complicado.

Dudas

Después de escribir todo esto y revisar algunos conceptos me planteo algunas cosas.
- La entidad que se genera automáticamente (al menos la que veo en mi equipo) es una Intermediate CA. La que propongo es una CA Raíz.
- Se pueden crear certificados desde la aplicación de Server.