-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathexa-saro-2019-05.tex
299 lines (200 loc) · 13.1 KB
/
exa-saro-2019-05.tex
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
%%--------------------------------------------------------------------------
%%--------------------------------------------------------------------------
\subsection{Examen de ITT-SARO, 14 de mayo de 2019}
Se quiere construir un sitio web, ElTiempecito, donde se puedan compartir comentarios sobre el tiempo en diversas localidades. La funcionalidad básica del sitio es la siguiente:
\begin{enumerate}
\item El sitio sólo permite acceso a usuarios registrados (registrados previamente, mediante un sistema no considerado en este enunciado, y que no es parte de ElTiempecito), mediante autenticación.
\item Si un visitante sin autenticar visita el sitio, cualquier página que visite le redirigirá a la página principal. Y en esta página principal verá un formulario para poder autenticarse mediante usuario y contraseña (que será lo que se ha registrado previamente). Una vez autenticado, el visitante podrá acceder los servicios del sitio, que se describen a continuación.
\item La página principal mostrará las 20 poblaciones con más comentarios durante las últimas 24 horas, ordenadas por número de comentarios durante ese periodo. Para cada población, se mostrará la previsión de temperatura, y un enlace a la página de la población.
\item La página principal del sitio tendrá también un banner (imagen en formato PNG). Este banner se mostrará también cuando el visitante no se haya autenticado.
\item Cada población tendrá una página (la ``página de la población''), con los datos meteorológicos de la población, y los 20 comentarios mas recientes que se han puesto sobre ella, ordenados de más moderno a más antiguo.
\item La página de cada población tendrá también un formulario para poner comentarios. Este formulario constará sólo de una caja de texto, donde se escribirá el comentario, y un botón, para enviarlo. Tras enviar el comentario, se volverá a ver la misma página de la población, ya con el comentario, y sin que para ello se haya hecho ninguna redirección.
\item La página de cada población mostrará también un icono (una nube o un sol), en formato PNG, que resumirá la previsión del tiempo.
\item Todas las imágenes (iconos de nube o sol, banner) serán servidos por el sitio.
\item El sitio ofrecerá también un canal XML con el listado de las mismas poblaciones que aparecen en la página principal, y para cada una el dato de temperatura prevista para mañana, y un enlace a la página de la población.
\item El sitio obtendrá todos sus datos meteorológicos de su propia base de datos. Este enunciado no describe cómo se actualizan esos datos, ni es eso relevante para lo que se pregunta.
\end{enumerate}
Teniendo en cuenta los requisitos anteriores, se pide:
\begin{enumerate}
\item Diseña un esquema REST para proporcionar el servicio descrito. Se habrán de especificar los nombres de recurso empleados, y cómo reaccionará la aplicación cuando reciba los métodos POST o GET sobre esas urls (no se usarán los métodos PUT o DELETE). Coloca la información en una tabla, con las urls en una columna, los métodos en otra, y la descripción de lo que realizará la aplicación al recibirlos en la tercera. Escribe también un fichero similar al fichero urls.py de Django (aunque no es importante que se respete la sintaxis mientras se entienda y la estructura sea similar a la de Django), que refleje el esquema REST anterior (1 punto).
\item Describe el modelo de datos que necesitará esta aplicación. Define las tablas necesarias y los campos necesarios para la funcionalidad descrita. Asegúrate de que incluyes en el modelo de datos la tabla o tablas necesarias para saber el número de páginas vistas por cada navegador, gracias al uso de la imagen transparente que se describe en en enunciado. Hazlo de forma lo más similar posible a lo que tendrías que escribir en el fichero models.py en Django (aunque no es importante que se respete la sintaxis mientras se entienda el modelo de datos que propones) (1 punto).
\item Describe las interacciones HTTP que ocurrirán entre el navegador y cualquier servidor web en el siguiente escenario. El escenario comienza cuando un visitante que accede por primera vez al sitio pone en el navegador la url de una página del sitio que no es la principal. Al no estar autenticado, es redirigido a la página principal donde, después de verla, rellena el formulario de autenticación con un nombre de usuario y contraseña validos (previamente registrados), y ve de nuevo la página principal. El escenario termina cuando el visitante está viendo de nuevo la página principal de nuevo, tal y como se ofrece ya a usuarios autenticados. (1 punto).
\item Describe las interacciones HTTP que ocurrirán entre el navegador y cualquier servidor web en el siguiente escenario. El escenario comienza con un visitante autenticado que está que viendo en su navegador la página de una población. El visitante rellena al caja de comentario, y pulsa el botón para enviarlo. El escenario termina cuando el visitante vuelve a ver la página de la población, ya con el nuevo comentario en ella.
\item El enunciado indicaba que el banner que se muestra en la página principal, se haya autenticado el visitante o no, es servido por el propio sitio. En caso de que fuera servido por un sitio tercero, ¿podría este sitio tercero aprovechar esto de alguna manera para saber cuańtos visitantes únicos (navegadores únicos) visitan la página principal del sitio, lleguen estos a autenticarse, o no? ¿Cómo?
\end{enumerate}
En todos los escenarios, ten en cuenta que tu respuesta debe considerar toda la funcionalidad que ofrece el servicio, y permitir que ésta pueda proporcionarse. Diseña la aplicación de forma que envíe cookies al navegador sólo cuando sea necesario.
En las respuestas donde describas interacciones HTTP indica para cada una de ellas claramente y en este orden:
\begin{itemize}
\item La primera línea de la petición HTTP
\item Si lo hay, el contenido de la petición
\item La primera línea de la respuesta HTTP
\item Si lo hay, el contenido de la respuesta
\item Una brevísima explicación de para qué se usa la interacción
\item Tanto en la petición como en la respuesta, las cabeceras con cookies, si es que fueran necesarias para la funcionalidad del escenario que se está describiendo (incluyendo el aspecto que han de tener esas cabeceras). Si la cabecera con cookie va o no dependiendo de algún factor ajeno a tu aplicación, explica cuando irá y cuándo no, y cuál es ese factor.
\item Si hubiera envío de datos de formulario, recuerda indicar de forma explícita dónde van esos datos, y si es posible, en qué formato.
\end{itemize}
Además, asegúrate de que describes las interacciones HTTP en el orden en que ocurrirían en el escenario.
En general, para todas las interacciones descritas, considérese que la cache del navegador no se está usando.
\subsubsection{Soluciones}
Hay muchas soluciones posibles. A continuación, una de ellas.
\textbf{Esquema REST}
Este podría ser el esquema REST:
\begin{tabular}{|l|l|l|}
\hline
Recurso & Método & Comentario \\ \hline \hline
/ & GET & Página principal (HTML) \\ \hline
/ & POST & Autenticación, devuelve página principal (HTML) \\ \hline
/\{id\_poblacion\} & GET & Página de población (HTML) \\ \hline
/\{id\_poblacion\} & POST & Comentario, devuelve página de población (HTML) \\ \hline
/img/nube & GET & Icono de ``nube'' \\ \hline
/img/sol & GET & Icono de ``sol'' \\ \hline
/img/banner & GET & Banner del sitio \\ \hline
/xml & GET & Canal XML \\ \hline
\end{tabular}
Todos los recursos del sitio devolverán una redirección 303 (See Other) al recurso ``/'' cuando no se reciba cookie de autenticación válida (el visitante no se ha autenticado).
\paragraph{urls.py}
\begin{verbatim}
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('xml', views.xml, name='xml'),
path('img/nube', views.image, {'file': 'nube'}, name='image'),
path('img/sol', views.image, {'file': 'sol'}, name='image'),
path('img/banner', views.image, {'file': 'banner'}, name='image'),
path('<id_poblacion>', views.poblacion, name='poblacion')
]
\end{verbatim}
Los recursos que sirven imágenes podrían servirse también configurando
adecuadamente los mecanismos de Django para servir ficheros estáticos.
\paragraph{models.py}
Versión simplificada, que cumple el enunciado, aunque podría optimizarse:
\begin{verbatim}
from django.db import models
class Usuario(models.Model):
nombre: models.CharField(max_length=20)
contrasena: models.CharField(max_length=20)
class Sesion(models.Model):
cookie = models.CharField(max_length=20)
user = models.ForeignKey('Usuario', null==True)
class Poblacion(models.Model):
id = models.IntegerField()
nombre = models.TextField()
temperatura = models.FloatField()
soleado = models.BooleanField()
class Comentario(models.Model):
poblacion = models.ForeignKey('Poblacion')
comentario = models.TextField()
fecha = models.DateTimeField()
\end{verbatim}
No se incluyen los campos identificador único para cada tabla.
\paragraph{Primer escenario}
Todas las interacciones son entre el navegador y el sitio.
\begin{itemize}
\item Petición GET a una página distinta de la principal.
Suponemos que se accede a una población, cuyo identificador es ``43''.
\begin{verbatim}
GET /43 HTTP/1.1
...
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 303 See Other
...
Location: /
\end{verbatim}
\item Petición GET de la página principal, fruto de la redirección anterior.
\begin{verbatim}
GET / HTTP/1.1
...
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
[Página con el formulario para autenticarse, HTML]
\end{verbatim}
\item Petición GET para el banner, originada debido a que está referenciado
en la página HTML anterior.
\begin{verbatim}
GET /img/banner HTTP/1.1
...
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
[Imagen de banner, PNG]
\end{verbatim}
\item Petición POST para enviar datos del formulario de autenticación.
\begin{verbatim}
POST / HTTP/1.1
...
usuario=Maria&contrasena=PalabraDePaso
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
Set-Cookie: sesion=323ddfd3323243hhhh323
[Página principal con toda la funcionalidad, HTML]
\end{verbatim}
\item Petición GET para el banner, originada debido a que está referenciado
en la página HTML anterior (se considera que no se usa la cache).
\begin{verbatim}
GET /img/banner HTTP/1.1
...
Cookie: sesion=323ddfd3323243hhhh323
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
[Imagen de banner, PNG]
\end{verbatim}
\end{itemize}
\paragraph{Segundo escenario}
A continuación, las interacciones son entre el navegador y el sitio. Como el visitante se ha autenticado ya, se le habrá enviado (con una cabecera ``Set--Cookie'') una cookie, como se indica en el apartado anterior. Suponemos que el identificador de la población cuya página está viendo el usuario al comenzar el escenario es ``34''.
\begin{itemize}
\item Petición POST /34 (para subir un comentario):
\begin{verbatim}
POST /34 HTTP/1.1
...
Cookie: sesion=323ddfd3323243hhhh323
comentario="Me gusta el tiempo de esta poblacion"
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
[Página de la poblacion, con el comentario ya puesto, HTML]
\end{verbatim}
\item Petición GET para el banner, originada debido a que está referenciado
en la página HTML anterior (se considera que no se usa la cache).
\begin{verbatim}
GET /img/banner HTTP/1.1
...
Cookie: sesion=323ddfd3323243hhhh323
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
[Imagen de banner, PNG]
\end{verbatim}
\item Petición GET para el icono, originada debido a que está referenciado
en la página HTML anterior (se considera que no se usa la cache).
\begin{verbatim}
GET /img/nube HTTP/1.1
...
Cookie: sesion=323ddfd3323243hhhh323
\end{verbatim}
\item Respuesta
\begin{verbatim}
HTTP/1.1 200 OK
...
[Imagen de la nube, PNG]
\end{verbatim}
\end{itemize}
\paragraph{Trazado de navegadores únicos desde servidor de banner}
Cada vez que se sirva la página principal del sitio, el navegador que la realice hará una petición al sitio Tercero para pedirle el banner (que ya está presente incluso antes de autenticarse). De esta manera, dado que se considera que no se usa la cache del navegador, Tercero recibirá una petición por cada petición de la página principal del sitio. Para poder saber si el navegador que está realizando la visita es el mismo que ya la realizó antes, Tercero enviará junto con la imagen una cookie de sesión (usando una cabecera ``Set--Cookie''). De esta manera, cada vez que un navegador vuelva a visitar la página principal, y por tanto a pedir el banner, enviará también a Tercero, con esta petición, la cookie que recibió. Tercero la usará para saber que no tiene que considerar esta petición, pues corresponde con una cookie que ya sirvió, y por tanto con un navegador que ya visitó la página principal del sitio.