Skip to content

Commit

Permalink
Completada api + correcciones menores + completado funcionalidad + Ag…
Browse files Browse the repository at this point in the history
…regadas ventajas de ionic sobre cordova
  • Loading branch information
tanoinc committed Sep 2, 2017
1 parent 1c08601 commit 5dc4523
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 14 deletions.
2 changes: 1 addition & 1 deletion inc/config.tex
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
% + Define el ambiente {httpcode} para sesiones HTTP
\newminted{http}{breaklines=true,breakatwhitespace=false}
% + Define el comando \httpfile{path} para sesiones HTTP desde archivos externos
\newmintedfile{http}{breaklines=true}
\newmintedfile{http}{}
% + Define el ambiente {xmlcode} para código XML
\newminted{xml}{}
% + Define el comando \xmlfile{path} para código XML desde archivos externos
Expand Down
Binary file modified pdf/tesis.pdf
Binary file not shown.
7 changes: 5 additions & 2 deletions src/02-capitulo-2/marco_teorico_backend.tex
Original file line number Diff line number Diff line change
Expand Up @@ -182,20 +182,23 @@ \subsubsection{Autorización y autenticación}
\label{apikey}
Cuando no se requiere acceder en nombre del usuario, o realizar acciones no directamente relacionadas con él, OAuth no es necesario. Sin embargo se desea controlar la identidad del sistema que está intentando acceder a la información.

Una forma de realizar esto es a través de claves de \gls{api}. Este método consta de dos de ellas: una podría ser pública e identifica a la aplicación del tercero (\gls{api} \eng{key}). La otra es secreta y no debe exponerse (\gls{api} \eng{secret}). Ambas funcionan como una suerte de \comillas{usuario y clave} que son enviadas en cada solicitud \gls{http}. Sin embargo el valor secreto nunca es viaja en ninguna comunicación realizada.
Una forma de realizar esto es a través de claves de \gls{api}. Este método consta de dos de ellas: una podría ser pública e identifica a la aplicación del tercero (\gls{api} \eng{key}). La otra es secreta y no debe exponerse (\gls{api} \eng{secret}). Ambas funcionan como una suerte de \comillas{usuario y clave} que son enviadas en cada solicitud \gls{http}. Sin embargo el valor secreto nunca viaja en ninguna comunicación realizada.

La forma de autenticación en cada pedido es la siguiente:
\begin{itemize}
\item La \gls{api} \eng{key} identifica a una aplicación y puede ser conocida por otras entidades.
\item La clave secreta sólo es conocida por la entidad emisora y la aplicación externa.
\item Se procesa la solicitud a enviar, y se adjunta en el encabezado la identificación de la aplicación (\gls{api} \eng{key}) y la firma. Esta se genera en base al resultado de procesar a través de una función de \eng{hash} (denominada \gls{hmac}) el contenido del pedido y la clave secreta. El resultado de esta función asegura que no se pueda manipular el mensaje, y permite determinar que este es originado por quien dice ser.
\item Se procesa la solicitud a enviar, y se adjunta en el encabezado la identificación de la aplicación (\gls{api} \eng{key}) y la firma. Esta se genera en base al resultado de procesar a través de una función de \eng{hash} (denominada \gls{hmac}), el contenido del pedido y la clave secreta. Al resultado de esta función se lo denomina \textit{firma}. Esta asegura que no se pueda manipular el mensaje y que sea originado por quien dice ser.
\item La solicitud es procesada por el destinatario realizando el mismo proceso: aplicando la función de \eng{hash} sobre el contenido y la clave secreta... si el resultado (firma) es el mismo, significa que la solicitud fue originada por el remitente esperado y no fue modificada.
\end{itemize}

Este método (\gls{hmac}) permite identificar al remitente que origina la solicitud y su autenticidad\cite{krawczyk1997rfc} y por ende se pueden controlar (a nivel de aplicación) sus permisos asociados. Este método es utilizado por \eng{Amazon Web Sevices}\cite{amazonApi}, \eng{Facebook}, \eng{Telegram} entre otros.

En particular se utiliza el encabezado \gls{http} \eng{Authorization} para transmitir ambos valores (API \eng{key} y firma).

Para finalizar, hay que destacar que las comunicaciones realizadas por este proceso, deben hacerse a través del protocolo \gls{https} (que es \gls{http} sobre una capa segura en donde la información viaja encriptada).
Esto nos asegura que ningún intermediario pueda leer el mensaje y además evita el \gls{replay attack}.

\subsubsection{Lenguaje y \gls{framework}}
\label{backend_lenguaje_framework}

Expand Down
10 changes: 10 additions & 0 deletions src/02-capitulo-2/marco_teorico_frontend.tex
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ \subsubsection{Aplicación móvil}

\textit{Ionic} es un \gls{framework} \gls{open source} que permite a los desarrolladores crear aplicaciones híbridas, con buena \eng{performance}, utilizando Apache Cordova y las principales tecnologías Web (\gls{javascript}, \gls{html}5, \gls{css}3, sass). En particular a partir de su versión 2, incorpora Angular (versión 2.0 y superiores) con \gls{typescript}. Una de sus fortalezas es el \eng{look and feel} de sus interfaces ya que se adaptan al diseño de las principales plataformas\cite{ionic2017concepts}. Su rapidez se debe a la utilización de animaciones y transiciones de \gls{css}3, así como también el uso de Angular, lo que hacen que se utilice la aceleración por hardware del dispositivo\cite{hartington2017animationsIonic}.

Se destacan las siguientes ventajas de Ionic frente a la utilización solamente de Cordova\cite{noupe2016ionicvscordova}:
\begin{itemize}
\item Interfaz de usuario y usabilidad: existen decenas de plantillas, más de 700 íconos, componentes de interfaz como encabezados, botones, etcétera, disponibles en varios estilos dependiendo de la plataforma y simulando su comportamiento. La codificación de la funcionalidad de estos componentes es simple y sencilla. En cambio en Cordova, se comienza desde cero con una página en blanco.
\item Proceso de desarrollo más conveniente ya que permite probar la mayoría de las modificaciones \comillas{en vivo} desde el navegador, sin la necesidad de recompilar la aplicación y ejecutarla en un emulador o dispositivo.
\item Mayor \eng{performance}: debido a una versión liviana de jQuery se reduce la manipulación de DOM. Además delega a la GPU el procesamiente de las animaciones y transiciones debido a \gls{css}3.
\item Angular (versión 2 y superiores) con \gls{typescript}.
\end{itemize}

Como segundo aspecto, posee una interfaz de línea de comandos para generar componentes, compilar la aplicación en distintas plataformas, probar el desarrollo en un navegador (con un servidor web integrado). Además permite programáticamente interactuar con los servicios de la nube que ofrece \textit{Ionic}, entre ellos la publicación de aplicaciones en las distintas tiendas de manera centralizada.

El proyecto posee una amplia comunidad de desarrolladores, con más de 31.000 estrellas en \gls{github}\footnote{\url{https://github.com/ionic-team/ionic}} y 26.000 preguntas en \gls{stackoverflow}\footnote{\url{https://stackoverflow.com/questions/tagged/ionic-framework}}. En 2015 se crearon mas de 1,3 millones de aplicaciones con \textit{Ionic}\cite{ionic2017concepts}. Además tiene una gran variedad de \eng{plugins} para acceder a funcionalidades nativas del teléfono, entre otras cuestiones.
Expand All @@ -221,6 +229,8 @@ \subsubsection{Aplicación móvil}

Debido a las característica anteriormente mencionadas, se considera a \textit{Ionic} como marco de desarrollo para la aplicación híbrida.



\paragraph{Otros \eng{frameworks} híbridos}
\label{otros_frameworks_hibridos}

Expand Down
97 changes: 91 additions & 6 deletions src/03-capitulo-3/api.tex
Original file line number Diff line number Diff line change
@@ -1,31 +1,116 @@
\subsection{API}
\label{funcionalidad_noticias_api}

Los servicios externos pueden crear novedades utilizando los métodos por la \gls{api} \gls{rest}.
Además de los atributos antes mencionados, la \gls{api} permite indicar si se desea enviar una notificación \eng{push} al celular de los destinatarios al momento de publicar la noticia.
En la siguiente sección se describen brevemente algunos aspectos de la \gls{api} \gls{restful}. La intención no es realizar una especificación completa de toda la interfaz, sino revisar el mecanismo general de su utilización. Para la especificación completa se utiliza \textit{Swagger} y está disponible en \url{https://app.swaggerhub.com/apis/tanoinc/mi-universidad/1.0.0}.

En base a lo establecido para \gls{rest} en el marco teórico (sección \ref{caracteristicas_api_restful}) el llamado a la \gls{api} está orientado al recurso \eng{newsfeed}, sobre el cual se realiza la creación a través de método \gls{http} \eng{POST}. También se indica que esta este llamado corresponde a la primer versión indicado en la \gls{uri}.
En base a lo establecido con \gls{rest} en el marco teórico (sección \ref{caracteristicas_api_restful}), el llamado a la \gls{api} está orientado a recursos. En el caso de \nombreApp{} son los \textit{puntos de integración} y otra información. Los \comillas{verbos} que representan a las acciones sobre estos, son los métodos \gls{http}. También se indica que las solicitudes corresponden a la versión 1 de la \gls{api}, por lo que esta información va en la \gls{uri}. En base esto se determina la siguiente interfaz:

\begin{itemize}
\item \textbf{POST /api/v1/newsfeed}\footnote{Esto es solo demostrativo. La especificación completa en Swagger puede consultarse en \url{https://app.swaggerhub.com/apis/tanoinc/mi-universidad/1.0.0}}: Agrega una nueva \textit{novedad} a los \eng{newsfeed} de los usuarios interesados (a nivel de: destinatario, contexto y/o servicio externo).
\item Para novedades:
\begin{itemize}
\item POST /api/v1/newsfeed: Crea una novedad
\end{itemize}
\item Para eventos del calendario:
\begin{itemize}
\item POST /api/v1/calendar\_event: Crea un evento de calendario
\end{itemize}
\item Para contenidos:
\begin{itemize}
\item POST /api/v1/content/google\_map: Crea un mapa de Google
\item POST /api/v1/content/text: Crea un contenido de texto
\item DELETE /api/v1/content/{id}: Elimina un contenido
\end{itemize}
\item Para geolocalización:
\begin{itemize}
\item GET /api/v1/geolocation/user/\{id\_usuario\}: Obtiene la ubicación geográfica de un usuario
\item POST /api/v1/geolocation/users: Obtiene la ubicación geográfica de una lista de usuarios. Se utiliza el método post para poder pasar una lista de valores que puede ser extensa. Por ello requiere que la solicitud tenga un cuerpo, no pudiéndose realizar esto con el método GET.
\end{itemize}
\end{itemize}

Las solicitudes no mantienen ningún estado entre sucesivas peticiones y la autenticación (explicada en la siguiente sección) se realiza en cada \eng{request}. La respuesta es devuelta con su código en formato \gls{json} debido a sus ventajas (sección \ref{rest}).

En el siguiente ejemplo se ve el \eng{request} \gls{http} para la creación de una novedad:
\begin{itemize}
\item \textbf{POST /api/v1/newsfeed}\footnote{Esto es solo demostrativo. La especificación completa en Swagger puede consultarse en \url{https://app.swaggerhub.com/apis/tanoinc/mi-universidad/1.0.0}}.
\begin{itemize}
\item Ejemplo del cuerpo de una solicitud \gls{http} para enviar una noticia con notificación a los usuarios con identificación id\_externo 1, 2 y 3:
\begingroup
\jsonfile{src/codigo/03-capitulo-3/post_newsfeed_solicitud.json}
\captionof{listing}{Ejemplo de cuerpo JSON en solicitud de POST /newsfeed}.\label{codigo_post_newsfeed_solicitud}
\endgroup

\item Ejemplo de respuesta:
\item Ejemplo de respuesta (con código \gls{http} 200):
\begingroup
\jsonfile{src/codigo/03-capitulo-3/post_newsfeed_respuesta.json}
\captionof{listing}{Ejemplo de respuesta JSON de POST /newsfeed}.\label{codigo_post_newsfeed_respuesta}
\endgroup
\end{itemize}
\end{itemize}

Otros posibles códigos que puede devolver son:
\begin{itemize}
\item 200:
Procesado correctamente
\item 401:
No autorizado
\item 403:
Acceso prohibido
\item 422:
Error de validación
\item 500:
Errores en el servidor. Ver detalle en respuesta
\end{itemize}

En la siguiente sección se detalla la autenticación necesaria para el llamado a estos servicios.

\subsubsection{Autenticación de servicios externos}
\label{autenticacion_servicios_externos}

Para poder integrar a los servicios externos en la aplicación, es necesario identificarlos, asegurarse que son quienes dicen ser y que su mensaje es el que han querido enviar. Para ello se utiliza el mecanismo visto en la sección \ref{apikey}. Se verá su implementación aplicada a este proyecto.

En primera instancia, la \gls{api} de \nombreApp{} correrá sobre \gls{https}. Esto evita que el mensaje pueda ser visto por terceros, y el ataque \gls{replay attack}.

En segundo lugar, el \eng{backend} conoce la identificación y clave secreta de todos sus servicios. Excede al alcance de esta tesis el mecanismo de envío de claves secretas a los administradores de los servicios externos. Estos deberán mantenerla guardada y asegurarse que no se revele. De todas formas, si alguna vez se ve comprometida, existe la posibilidad de que sea cambiada.

El servicio que envíe una solicitud a \nombreApp{} deberá firmar el pedido con su clave secreta (utilizando HMAC con sha256) y adjuntar el encabezado \gls{http} \lstinline{Authorizarion} con el valor \lstinline{APIKEY}, su identificación de servicio y la firma (separados por \comillas{dos puntos}). Por ejemplo, para enviar una nueva noticia, si:
\begin{itemize}
\item La API key es: \lstinline{0b0eedd9e23e30840fed24b8d1ab11c03913beca}

\item La clave secreta de API es: \lstinline{402082e593fee526fa64e13b47841fdbcc7a786d}

\item La \gls{url} es: \lstinline{https://localhost:8800/api/v1/newsfeed}

\item El método es: \lstinline{POST}

\item El contenido es (tipo application/x-www-form-urlencoded): \lstinline{title=Titulo de prueba&content=Texto contenido&send_notification=1&clobal=0&context=matematica}

\end{itemize}

La firma con HMAC (sha256) se deberá generar con la clave secreta (\lstinline{402082e593fee526fa64e13b47841fdbcc7a786d}) y el siguiente contenido\footnote{Para favorecer la visualización en este documento, el JSON se muestra formateado con saltos de línea y \textit{tabs}, pero en la implementación estos no existen. Esto es importante ya que una diferencia en un caracter, cambia la firma.}:

\begingroup
\jsonfile{src/codigo/03-capitulo-3/nuevo_newsfeed.json}
\captionof{listing}{JSON generado en base a una solicitud utilizando los atributos del \eng{request} HTTP.}
\endgroup

El resultado es la siguiente firma:

\lstinline{a42e995848c48f51a226b5089196d225e0635d3536be126c0331a9cde700d398}


Notar que todos los datos de la solicitud se utilizan en para generar el \eng{hash} con la firma, por lo que si alguno cambia, esta firma ya no tendría sentido.

La solicitud \gls{http} enviada quedaría de la siguiente manera\footnote{La API key y la firma se recortan para que puedan entrar en el ancho de la página}:
\begingroup
\httpfile{src/codigo/03-capitulo-3/nuevo_newsfeed.http}
\captionof{listing}{JSON generado en base a una solicitud utilizando los atributos del \eng{request} HTTP.}
\endgroup

De esta manera el servidor realiza el proceso inverso y si las firmas son iguales, entonces la solicitud es válida: es de quien dice ser y no fue alterada.

\subsubsection{Permisos}
\label{autenticacion_permisos}
\label{autenticacion_permisos}

Los permisos indican qué operaciones pueden ser utilizadas por cada servicio. Existe un permiso por cada entrada de la \gls{api} (\gls{url} y método \gls{http}).

La aplicación \nombreApp{} maneja un sistema que controla qué operaciones están habilitadas para cada servicio. Esta asociación permiso-servicio está indicada con un número de versión que luego es utilizado cuando un usuario añade un servicio. Este es aceptado en una versión, por lo que si se modifica deberá volver a aceptarse. De esta manera se informa al usuario de cada cambio en las operaciones que requieran los servicios.
8 changes: 4 additions & 4 deletions src/03-capitulo-3/funcionalidad.tex
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ \subsubsection{Suscripciones}

Siempre que se necesite hacer una referencia a un usuario (por ejemplo para enviar una novedad personal) se utilizará el \textit{identificador externo}.

Otro aspecto a destacar es que el usuario puede acceder al listado de contextos de cada servicio y realizar la suscripción a los que sean de su interés (sin necesidad de añadir el servicio). Desde esta pantalla también puede cancelarlas.
Otro aspecto a destacar es que el usuario puede acceder al listado de contextos (o temas) de cada servicio y realizar la suscripción a los que sean de su interés (sin necesidad de añadir el servicio). Desde esta pantalla también puede cancelarlas (figura \ref{app_calendario}). Esto es útil para indicar el interés sobre una temática y recibir las novedades y eventos asociados a ella.

\figura{03-capitulo-3/app_contextos.png}{Pantalla de suscripción a temas}{app_calendario}{0.5}


\subsubsection{Otras}
\label{funcionalidad_otras}
Expand All @@ -179,6 +182,3 @@ \subsubsection{Otras}

\end{itemize}




23 changes: 22 additions & 1 deletion src/03-capitulo-3/plugins.tex
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
\subsection{Plugins}
\label{desarrollo_plugins}

Como parte de este proyecto, además del desarrollo de la aplicación móvil (y su \eng{backend}), los objetivos son desarrollar extensiones para sistemas utilizados en la \unlp{}. En particular se utilizan servicios en los que tengo acceso debido a mi trabajo en el \gls{cespi}.

A continuación, se pasan a detallar cuestiones relacionadas con la integración de: SIU Guaraní y Moodle.

\subsubsection{Personalización SIU Guaraní}
\label{desarrollo_plugins_guarani}

En Guaraní se utiliza el esquema de personalizaciones de \gls{chulupi} para desarrollar la integración con \nombreApp{}.

El significado de los contextos está dado por las materias. Esto significa que un usuario de la aplicación móvil podría suscribirse a la materia que está interesado.

La personalización se denomina \comillas{mi\_universidad} e implementa (en principio) tres funcionalidades:
\begin{itemize}
\item Interconexión entre usuarios. Esta operación es utilizada cuando un usuario añade un servicio de Guaraní. Esta envía a \nombreApp{} el identificador externo del usuario \textit{logueado}.
\item Envío de mensajes. Al enviar mensajes en Guaraní, se enviarán novedades a \nombreApp{}. El alcance de las mismas estará determinado por los destinatarios del mensaje. Si este es a toda una comisión o mesa de examen, se enviará a todos los inscriptos y además tendrá la materia como contexto asociado. Esto significa que todos los interesados (más allá de los inscriptos) podrán ver en sus noticias el mensaje.
\item Fechas de parciales. Guaraní permite, desde su módulo \textit{Docente}, definir los parciales en cada comisión. La personalización envía a \nombreApp{} la fecha de los mismos, asociados al contexto de la materia y a todos sus inscriptos.
\end{itemize}

Se planifica incorporar más novedades y eventos del calendario, como por ejemplo, fechas de inscripción a cursadas, mesas de examen, horarios y aulas de materias y notificación de carga de notas, entre otras.

Esta personalización estará disponible para otras Universidades que deseen implementar \nombreApp{}.

\subsubsection{Plugin Moodle}
\label{desarrollo_plugins_moodle}
\label{desarrollo_plugins_moodle}


7 changes: 7 additions & 0 deletions src/bibliografia/lucianoc.bib
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,10 @@ @misc{nativescript2017basics
}


@misc{noupe2016ionicvscordova,
author = {Noupe Editorial Team},
title = {{\eng{Ionic vs. Pure Cordova: Three Reasons Ionic Wins}}},
howpublished = "\url{https://www.noupe.com/development/ionic-vs-pure-cordova-97503.html}",
note = "[Online; accedido 27-01-2017]"
}

8 changes: 8 additions & 0 deletions src/codigo/03-capitulo-3/nuevo_newsfeed.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
POST /api/v1/newsfeed HTTP/1.1
HOST: localhost:8800
authorization: APIKEY 0b0eedd9e23e3...:a42e995848c48f51...
content-length: 94
content-type: application/x-www-form-urlencoded

title=Titulo de prueba&content=Texto contenido
&send_notification=1&clobal=0&context=matematica
11 changes: 11 additions & 0 deletions src/codigo/03-capitulo-3/nuevo_newsfeed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"full_url":"http:\/\/localhost:8800\/api\/v1\/newsfeed",
"method":"POST",
"input":{
"title":"Titulo de prueba",
"content":"Texto contenido",
"send_notification":"1",
"clobal":"0",
"context":"matematica"
}
}
Loading

0 comments on commit 5dc4523

Please sign in to comment.