Lorawan-stack: Introducir una nueva aplicación de cuenta (para reemplazar la aplicación oauth)

Creado en 4 oct. 2019  ·  32Comentarios  ·  Fuente: TheThingsNetwork/lorawan-stack

Resumen

Actualmente tenemos muchos problemas que giran en torno a nuestro flujo de OAuth, el cambio de cuenta, la gestión de tokens, la marca respectiva, etc. Este es un intento de hacer que todos estos sean más procesables bajo una nueva aplicación account que se encargará de todas estas preocupaciones.

¿Porqué necesitamos esto?

  • Falta la función de cambio de cuenta ⟶ #488
  • Falta la marca y el contexto para el usuario ⟶ #730
  • Gestión de sesión faltante ⟶ #1217
  • Confusión del usuario sobre el flujo de autenticación de OAuth ⟶ #265

¿Qué ya hay? ¿Qué ves ahora?

  • Aplicación OAuth con interfaz de usuario limitada

¿Lo que falta? ¿Qué quieres ver?

Una aplicación que actúa como proveedor de OAuth y una interfaz de usuario de configuración de marca y con todas las funciones en torno a todas las preocupaciones de cuenta y autenticación.

Ambiente

Web

¿Cómo propone implementar esto?

Creo que un gran problema con la implementación actual es la falta de claridad y contexto para el usuario. Es difícil reconocer la aplicación OAuth como una entidad de autenticación independiente. Las razones son:

  • falta de marca y contexto
  • interfaz de usuario muy reducida y poco informativa
  • la consola actúa como si manejara la autenticación en sí misma (mensaje "Iniciar sesión" en lugar de "Iniciar sesión con su cuenta de {nombre del servicio del proveedor de OAuth}", omitiendo la autorización)
    Para mejorar la claridad, debemos hacer que la aplicación sea más visible, distinguible y útil:
  • Agregar marca configurable
  • Completar la funcionalidad

    • Cambio de cuenta

    • Gestión de sesiones

    • Gestión de autorizaciones

    • Configuración del perfil (cambiar/olvidé la contraseña, correo electrónico, foto de perfil)

Creé tres esquemas que dan una idea de cómo imagino la aplicación de la cuenta:

Ver esquemas

account_login
account_overview
account_profile_settings
(Observe el conmutador de cuenta integrado en el menú desplegable del usuario en la parte superior derecha)

¿Puedes hacerlo tú mismo y enviar una solicitud de extracción?

Si. @johanstokking @htdvisser , hágame saber si cree que es bueno continuar.

identity server uweb umbrella

Todos 32 comentarios

Con respecto a todo el problema de confusión de inicio/cierre de sesión entre la consola y el proveedor de autenticación, este es mi plan:

  • Usamos un logotipo Account separado para la aplicación de la cuenta (en lugar del logotipo TTS) y usamos el mismo componente de encabezado que también usamos para la consola (cc @pierreph)
  • En lugar de tener dos pantallas de inicio de sesión separadas para la consola y la aplicación de la cuenta, deberíamos vincular la experiencia más estrechamente, lo que significa

    • Eliminaremos la pantalla de inicio de sesión de la consola /console/login

    • La consola redirigirá automáticamente a la página de inicio de sesión de la aplicación de la cuenta /account/login , cuando no tenga un token de acceso (válido)

    • Como ya lo hacemos con el botón de inicio de sesión de la consola, usaremos un parámetro de consulta de redireccionamiento para enviar al usuario de vuelta a la consola después de iniciar sesión correctamente.

    • Cerrar sesión desde la interfaz de usuario de la consola dará como resultado la eliminación del token de acceso almacenado, así como el cierre de sesión de la aplicación de la cuenta. De esta manera, los usuarios siempre tendrán que volver a ingresar sus credenciales para volver a iniciar sesión en la consola.



      • Para poder hacer esto, necesitamos una forma de activar los cierres de sesión de las solicitudes de origen cruzado (ya que no se garantiza que la aplicación de la consola y la cuenta estén en el mismo origen)


      • En v2, estamos usando una ruta simple /users/logout que activará un cierre de sesión al que se puede hacer referencia desde cualquier lugar


      • Sería bueno buscar formas de lograr lo mismo mientras se mantiene seguro CSRF



    • El nuevo flujo se parecerá bastante al flujo de la consola v2; básicamente sacrificaremos la separación del cliente de la consola y el servidor de autorización para mejorar la UX, lo cual está bien ya que la consola es una especie de cliente de caso especial

    • Es posible que tengamos que revisar este flujo si permitimos diferentes procedimientos de inicio de sesión en el futuro

Si no escucho ninguna queja sobre este plan, comenzaré a implementarlo.

Suena como un gran plan. Acepto que no necesitamos un cierre de sesión explícito de la consola y permanecer conectado a través de OAuth en el UX, aunque funcionará de esa manera en la parte inferior.

¿Qué necesita para el cierre de sesión de origen cruzado? ¿No sería un simple enfoque de dos pasos; Cerrar sesión en la "página" para eliminar el token de acceso almacenado en la Consola, luego redirigir a la página de cierre de sesión genérica donde la aplicación de la cuenta cierra la sesión. ¿O desea esto sin redirección pero publicar en un punto final de cierre de sesión?

Para el cierre de sesión, podemos inspirarnos en el cierre de sesión de OpenID Connect. Puede encontrar un buen resumen aquí: https://medium.com/@robert.broeckelmann/openid -connect-logout-eccc73df758f

Suena como un gran plan. Acepto que no necesitamos un cierre de sesión explícito de la consola y permanecer conectado a través de OAuth en el UX, aunque funcionará de esa manera en la parte inferior.

¿Qué necesita para el cierre de sesión de origen cruzado? ¿No sería un simple enfoque de dos pasos; Cerrar sesión en la "página" para eliminar el token de acceso almacenado en la Consola, luego redirigir a la página de cierre de sesión genérica donde la aplicación de la cuenta cierra la sesión. ¿O desea esto sin redirección pero publicar en un punto final de cierre de sesión?

El enfoque de dos pasos está bien. Mi preocupación era que el cierre de sesión de la aplicación de la cuenta debe estar deshabilitado CSRF, lo que significa que cualquier persona con un enlace de cierre de sesión podría atraer a alguien para que cierre sesión en su cuenta. Actualmente, esto también es posible con la pila v2 (al hacer clic aquí se cerrará la sesión ).
Creo que por ahora esto es aceptable pero no exactamente la mejor práctica.

He hecho bastante trabajo ahora para la nueva aplicación de cuenta:

  • Componentes y contenedores refactorizados que pueden ser utilizados por la consola y la aplicación de cuenta
  • Nuevos diseños implementados (incluida la capacidad de respuesta)
  • Configuración de perfil implementada, incluida la imagen de perfil
  • Gestión de autorizaciones implementadas (ver y revocar)
  • Gestión de sesiones implementada (ver y revocar)
  • Resolviendo un problema que resultó en representaciones en blanco al usar dependencias de módulos css compartidos

Hice esto codificando un token de acceso para poder usar la API de pila. Actualmente no puedo avanzar con una implementación adecuada, ya que no sé cuál sería la mejor manera de obtener un token de acceso para la aplicación de la cuenta.
En este momento, la "aplicación de autenticación" es solo un SPA que se conecta a los puntos finales de autenticación del servidor de autenticación (inicio de sesión, cierre de sesión y otros puntos finales relacionados con la cuenta que no necesitan un token de acceso).
@htdvisser me mencionó que nuestra idea inicial era tener la aplicación de la cuenta como un cliente de autenticación independiente, usando el tipo de concesión de contraseña. Creo que deberíamos abrir una discusión sobre esto, ya que:

  • dependiendo de la fuente, se desaconseja el tipo de concesión de contraseña, incluso para clientes "oficiales" y de confianza
  • necesitaría otra pantalla de inicio de sesión (junto a la pantalla de inicio de sesión del proveedor de autenticación)
  • Me pregunto si hay alguna forma de obtener un token de acceso directamente del proveedor de OAuth, sin tener que usar otro cliente por separado, ya que ya estamos realizando la autenticación dentro de la aplicación OAuth.
  • si usamos la concesión de contraseña para la aplicación de la cuenta, también deberíamos usarla para la consola

Ya le dije a @htdvisser que todo el aspecto de autenticación/autorización delegado de esto es algo abrumador para mí y no me siento lo suficientemente informado como para ser responsable de un asunto tan sensible a la seguridad.

Lo que debemos buscar es un flujo que haga que el flujo de autenticación de nuestros clientes oficiales se sienta como una autenticación nativa (ver también mi otro comentario ), lo que significa que los inicios y cierres de sesión son globales y no debe haber distinción entre el estado autenticado de los clientes y el proveedor de la autorización.

Por lo tanto, necesitaría ayuda e información para continuar con la aplicación de la cuenta. ¿Cómo podemos coordinar esto?

dependiendo de la fuente, se desaconseja el tipo de concesión de contraseña, incluso para clientes "oficiales" y de confianza

Sí, no se debe utilizar la concesión de contraseña, consulte la especificación y el razonamiento aquí: https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section -3.4

Actualmente bloqueado por #2148

Entonces, después de estar involucrado en esto por un tiempo, creo que necesito algo de información.

La idea original de la aplicación de la cuenta era reemplazar la aplicación Oauth actual y ampliar la funcionalidad hacia la gestión de perfiles y sesiones (ver OP). El problema con esto es que para implementar dicha funcionalidad, la aplicación necesitaría un token de acceso, lo que significa esencialmente que la aplicación de la cuenta sería tanto un proveedor como un cliente de OAuth.

Mi idea era presentar un nuevo cliente de OAuth ( account ) y la interfaz, para combinar la funcionalidad con la aplicación OAuth actual. Para el usuario, parecería que tanto el proveedor de OAuth (inicio de sesión, registro, validación de la cuenta, etc.) como el cliente de la aplicación de la cuenta (configuración del perfil, gestión de la sesión, gestión de la autorización) son la misma aplicación, mientras que en segundo plano hay es una separación técnica entre el proveedor de OAuth y el cliente. En el backend, el cliente de la cuenta se convertiría en parte del paquete oauth . En cuanto a la interfaz, también podríamos tratar ambas cosas como la misma aplicación, utilizando el mismo punto de entrada ( account.js ).
Asimismo, el enrutamiento reflejaría esta combinación, por ejemplo:

  • /account/login para el inicio de sesión de OAuth [capa de proveedor de OAuth]
  • /account/register para registro de usuario [capa de proveedor OAuth]
  • /account/forgot-password para registro de usuario [capa de proveedor OAuth]
  • /account/client/login/ttn-stack para el inicio de sesión del cliente (autorización) [capa de cliente OAuth]
  • /account/client/oauth/callback para intercambiar el código de autenticación [capa de cliente OAuth]
  • /account página de descripción general del cliente OAuth [capa de cliente OAuth]

Alternativamente, podríamos mantener ambas preocupaciones separadas, dejando el proveedor de OAuth ( /oauth través de pkg/oauth ) como está y tratando la aplicación de la cuenta ( /account través de pkg/account ) como algo completamente independiente, como hacemos con la consola. Entonces, el proveedor de OAuth solo sería responsable de los asuntos de autenticación, incluida la autorización y el registro de la cuenta de usuario, pero no tendría una vista autenticada propia como la que tiene actualmente. En cambio, después del inicio de sesión, se redirigiría a la aplicación de la cuenta de forma predeterminada, que luego recuperaría un token automáticamente.

Siento que la primera solución podría evitar parte de la confusión que actualmente tenemos en torno a la autenticación y la administración de cuentas, pero no puedo prever si podría presentar otras complicaciones. La segunda solución parece más limpia, pero la pregunta es cómo comunicar/marcar la separación. Por ejemplo, ¿ambos deberían comunicarse como "Aplicación de cuenta" todavía? ¿O deberían ser los The Things Stack Single Sign On y The Things Stack Account Application ?

Por favor, hágame saber sus opiniones.

Hmm, retrocediendo un paso, ¿cuál es el propósito de hacer que la aplicación de la cuenta sea un cliente OAuth? ¿Qué funcionalidad a través de OAuth queremos allí?

  • Configuración del perfil (nombre, correo electrónico, foto de perfil)
  • Gestión de sesiones (revisar, revocar)
  • Gestión de autorizaciones (revisar, revocar)
  • (Posiblemente otras metaconfiguraciones relacionadas con TTES en el futuro)

Todos ellos requieren un token de acceso, ya que esa es la única forma de autorizar los respectivos RPC.

Necesitamos una separación del proveedor de OAuth, que podría ser externo, por ejemplo, "The Things Network Community", y la administración de usuarios, que se trata de administrar los campos de la entidad de usuario almacenados con The Things Stack, incluidos los puntos @kschiffer. escribió en el comentario de arriba.

Nuestros terminales /api/v3/* no aceptan autenticación de cookies porque están habilitados para CORS. Solo funcionan con claves API y tokens de acceso.

  • Configuración del perfil (nombre, correo electrónico, foto de perfil)
  • Gestión de sesiones (revisar, revocar)
  • Gestión de autorizaciones (revisar, revocar)
  • (Posiblemente otras metaconfiguraciones relacionadas con TTES en el futuro)

Todos ellos requieren un token de acceso, ya que esa es la única forma de autorizar los respectivos RPC.

También podríamos hacer que estos formen parte de la consola, pero eso significaría que la consola mezclaría preocupaciones hasta cierto punto. Podría ver situaciones en las que sería mejor realizar la administración de cuentas sin la sobrecarga de todas las demás funcionalidades de la consola, pero tal vez soy yo quien está haciendo un exceso de ingeniería en esto 🤷‍♂️.

En general, la pregunta sería si queremos ver la consola solo como una herramienta para administrar asuntos relacionados con la red. Podemos abrirlo para que sea una plataforma de administración de propósito general para todos los asuntos relacionados con TTS o podemos ser más atómicos y mantener la separación y usar diferentes aplicaciones/clientes para diferentes preocupaciones. Es una cuestión estratégica. Veo casos para los dos.

No creo que la consola (todas las consolas, porque hay una consola en cada clúster) deba tener plenos derechos sobre el usuario. Las consolas no deben usarse para administrar clientes OAuth autorizados, sesiones, dirección de correo electrónico principal, información de contacto. Tener una aplicación de gestión de usuarios dedicada (la aplicación de la cuenta) es mucho mejor.

De hecho, buen punto. Entonces se vuelve a la pregunta inicial .

Mi opinión es:

Enfoque mixto:

  • Desde un punto de vista del usuario menos confuso (una ubicación para todos los asuntos relacionados con la cuenta)
  • Branding / comunicación más fácil
  • Conforme al plan original de la aplicación de la cuenta
  • En cuanto a la interfaz, no necesitamos un nuevo punto de entrada y, por lo tanto, repeticiones separadas
  • La implementación se vuelve más compleja/confusa (la aplicación de la cuenta es un proveedor de autenticación y un cliente)

Enfoque separado:

  • Implementación más limpia y convencional
  • Configuración más flexible y clara
  • Presenta una nueva aplicación junto a la aplicación oauth, que necesita una marca y una comunicación sensatas
  • Construcciones más largas (pueden ser marginales, no se han probado) y más activos

Me inclino por el enfoque mixto.

  • Configuración del perfil (nombre, correo electrónico, foto de perfil)
  • Gestión de sesiones (revisar, revocar)
  • Gestión de autorizaciones (revisar, revocar)
  • (Posiblemente otras metaconfiguraciones relacionadas con TTES en el futuro)

Esta es la aplicación de cuenta, ¿verdad? ¿No es OAuth?

  • Presenta una nueva aplicación junto a la aplicación oauth, que necesita una marca y una comunicación sensatas

¿Para qué sirve la aplicación OAuth entonces?

¿Puede enumerar las características para el usuario de lo que el cliente de OAuth agrega a la aplicación de la cuenta, que no podemos crear en la aplicación de la cuenta, posiblemente a través de nuevos puntos finales?

Esta es la aplicación de cuenta, ¿verdad? ¿No es OAuth?

Sí, esta es la aplicación de cuenta. Pero el plan era que lo que tenemos actualmente como aplicación OAuth pase a formar parte de la aplicación de la cuenta.

¿Para qué sirve la aplicación OAuth entonces?

Para autenticación (como parte del flujo OAuth), registro de usuarios, autorización de clientes, restablecimiento de contraseña. Básicamente todo lo que tiene que ver con autenticación de usuarios y autorización de clientes.

¿Puede enumerar las características para el usuario de lo que el cliente de OAuth agrega a la aplicación de la cuenta, que no podemos crear en la aplicación de la cuenta, posiblemente a través de nuevos puntos finales?

El problema es más bien al revés, no podemos simplemente extender nuestra aplicación OAuth actual con las funcionalidades que queremos para la aplicación de la cuenta, ya que necesitaríamos obtener un token de acceso. Es un poco el problema del huevo y la gallina. Si hubiera un medio diferente de autorización para las funcionalidades de la aplicación de la cuenta (sesiones, autorizaciones, etc.), por ejemplo, a través de la cookie de sesión que tiene la aplicación OAuth, entonces sería diferente. Pero por lo que veo esto es inviable.

¿La aplicación OAuth es algo independiente? ¿Está implementando los flujos de redirección para los clientes de OAuth? ¿O es un cliente de OAuth en sí mismo?


Énfasis mío:

Mi idea era presentar un nuevo cliente OAuth ( account ) y frontend, para combinar la funcionalidad con la aplicación OAuth actual . Para el usuario, parecería que tanto el proveedor de OAuth (inicio de sesión, registro, validación de la cuenta, etc.) como el cliente de la aplicación de la cuenta (configuración del perfil, gestión de la sesión, gestión de la autorización) son la misma aplicación, mientras que en segundo plano hay es una separación técnica entre el proveedor de OAuth y el cliente . En el backend , el cliente de la cuenta se convertiría en parte del paquete oauth .

veo aquí;

  • cliente OAuth
  • aplicación OAuth actual
  • proveedor de OAuth
  • el cliente de la aplicación de cuenta
  • el proveedor de OAuth
  • el cliente
  • el backend
  • el cliente de la cuenta
  • el paquete de oauth

Estoy tratando de entender la propuesta, pero todavía no entiendo completamente qué es qué.

Entonces, ¿cuáles son las características que queremos?

  1. Crear una cuenta
  2. Contraseña olvidada
  3. Acceso
  4. Cambia la contraseña
  5. Ver y editar perfil
  6. Administrar sesiones
  7. Cosas de OAuth

    1. Pantalla de consentimiento (flujo de código de autorización de OAuth)

    2. Administrar autorizaciones de OAuth

Supongo que 1-6 se puede implementar sin tocar OAuth en absoluto, si optamos por la autenticación de sesión. Eso es posible, ¿verdad?

si lo siento Tenemos una serie de términos no fijados aquí que hacen bastante difícil explicar las cosas. Al menos da una buena idea de la complejidad del problema 😅.

Así que tomemos el statu quo:

proveedor de OAuth
La entidad que proporciona la autorización (y en nuestro caso también la autenticación) según la especificación OAuth 2.0. En nuestro caso, ese es el paquete pkg/oauth , que a su vez usa la aplicación OAuth (ver más abajo) para implementar la interfaz de usuario necesaria para obtener información del usuario (renderizar inicio de sesión, registro, vistas de autorización, etc.).

aplicación OAuth
Esta es la aplicación web de reacción en la interfaz. Nuestro código de interfaz consta de diferentes aplicaciones (con diferentes puntos de entrada oauth.js / console.js ) que comparten partes comunes, como componentes de reacción y utilidades

cliente OAuth
Un cliente registrado que usa OAuth para autenticación y autorización, como la consola o la CLI.

paquete de autenticación
El paquete Go que es responsable de implementar el proveedor de OAuth. Eso es pkg/oauth .

Como puede ver, hay tres o cuatro capas diferentes en juego aquí. El problema es que si mantenemos la forma en que hacemos la autorización en este momento, necesitaríamos tener algo que desempeñe todos los roles descritos anteriormente al mismo tiempo.

Supongo que 1-6 se puede implementar sin tocar OAuth en absoluto, si optamos por la autenticación de sesión. Eso es posible, ¿verdad?

Si. 1-4 ya son posibles sin oauth/token de acceso. 5 y 6 actualmente necesitan un token de acceso. 7. ii aún no se ha implementado. Si 5 y 6 fueran posibles sin token de acceso, entonces no necesitaríamos otro cliente de autenticación para hacer esto. Aún así, debemos considerar que cada funcionalidad que queramos agregar a la aplicación de la cuenta en el futuro no debe usar el token de acceso como único medio de autorización.

Si 5 y 6 fueran posibles sin token de acceso, entonces no necesitaríamos otro cliente de autenticación para hacer esto. Aún así, debemos considerar que cada funcionalidad que queramos agregar a la aplicación de la cuenta en el futuro no debe usar el token de acceso como único medio de autorización.

Correcto. Esto tiene mucho sentido para mí. Esta es también una mejor base para el "modo sudo", donde los usuarios pueden hacer cosas _solo_ en la aplicación de la cuenta, después de volver a ingresar su contraseña, por ejemplo. Entonces, sí, puede haber cierta superposición entre lo que pueden hacer los clientes de OAuth y la aplicación de la cuenta, pero esa superposición no me parece grande. Veo valor en mantener las cosas dedicadas a la aplicación de la cuenta.

Bueno suena bien.
@htdvisser ¿Tiene alguna objeción? Y si no, ¿puede indicarme los archivos/paquetes relativos para la autorización, porque supongo que no tendrá tiempo para trabajar en esto pronto (?).

Como comenté antes, nuestros terminales /api/v3/* no aceptan la autenticación de cookies porque están habilitados para CORS. Si desea comenzar a aceptar la autenticación de cookies, debe observar detenidamente nuestros encabezados CORS, porque realmente no queremos que un atacante realice solicitudes de origen cruzado autenticadas por cookies a estos puntos finales.


Nuestra API es gRPC y la autenticación se realiza con el encabezado Authorization , que se propaga a gRPC como metadatos de solicitud. La implementación de la autenticación de sesión podría verse así:

  • Agregue un tipo SessionToken a pkg/auth/auth.go
  • Agregue una parte secreta al modelo Session , similar a lo que hacemos con las claves API y los tokens de acceso.
  • Agregue un middleware que extraiga el ID de la sesión y el secreto de la sesión de la cookie y los reenvíe al encabezado Authorization como un token de sesión.
  • Agregue SessionToken como case a los switch tokenType { en pkg/identityserver/entity_access.go

Una cosa a considerar aquí es que esto también significa que la aplicación de la cuenta y la API v3 deben servirse desde el mismo origen. De lo contrario, la autenticación de cookies no funcionaría ya que el contexto de autenticación comprende diferentes orígenes.
No estoy seguro de cuán aceptable es eso. Al menos en la práctica, parece que estamos usando los mismos orígenes en nuestras implementaciones.

Sí, estarán en el mismo origen.

@kschiffer , háganos saber cómo podemos desbloquear el progreso aquí.

OK, continuemos esa conversación aquí.

@kschiffer Después de trabajar un poco en esto:

  • La parte frontal de la aplicación oauth básicamente consistiría solo en la pantalla de autorización

  • Creo que es muy molesto tener que conservar las configuraciones de is.oauth.ui.* solo por eso
    [...]
  • También estoy un poco inseguro acerca de las restricciones exactas de cómo podemos alterar la configuración de la pila sin romper el CC
  • No tengo suerte al encontrar una solución viable aquí y realmente necesito alguna información.

No podemos romper la configuración en V3, pero podemos introducir una nueva configuración, desaprobar la configuración anterior, usar la configuración anterior como alternativa y presentar un problema TODO etiquetado como bump/major para eliminar la configuración anterior.

Entonces, mi sugerencia sería introducir una nueva configuración que sería un reemplazo completo y habilitaría la aplicación de la nueva cuenta. Para la compatibilidad con versiones anteriores, debería funcionar sin que el usuario especifique esta nueva configuración, es decir, confiar en los valores predeterminados sanos y la configuración anterior a través de is.oauth.ui.* .

@kschiffer ¿cuál es el estado aquí?

Actualmente rebasando mi trabajo en el nuevo andamio, que está en curso aquí: #3453

El siguiente paso es reorganizar, arreglar y PRing las vistas autenticadas y ajustar los diseños actuales a la nueva marca.

@kschiffer ¿cuál es el estado aquí?

La aplicación de cuenta se introdujo en 3.11. Actualmente todavía faltan:

  • Cambio de cuenta #488
  • Gestión de sesiones
  • Gestión de autorizaciones (iirc esto también incluye agregar puntos finales de API)

está bien. https://github.com/TheThingsNetwork/lorawan-stack/issues/488 ya está cerrado, parece.

Este ha sido un gran problema. ¿Puede presentar uno o dos problemas nuevos para el anterior para reemplazar este, para que pueda cerrarse?

¿Fue útil esta página
0 / 5 - 0 calificaciones