Error al subir chat

Hola, quiero reportar un problema que encontré al subir archivos o imágenes en mensajes directos de chat.

  • Cuando el Usuario A sube el Archivo A en una publicación o chat, funciona bien y el archivo se registra correctamente.

  • Pero cuando el Usuario B descarga el Archivo A e intenta subirlo de nuevo en otro chat:

    • Si el Usuario B envía el archivo sin texto, recibe un error:

      El mensaje es demasiado corto, debe tener un mínimo de 1 carácter.
      
    • Si el Usuario B envía el archivo con texto, solo se envía el texto; falta el archivo adjunto.

Sin embargo, si el Usuario A vuelve a subir el mismo archivo, funciona bien y el archivo se incluye en el mensaje.

Mi pregunta:
¿Es este el comportamiento previsto, donde solo el cargador original puede reutilizar un archivo cargado? ¿O deberían otros usuarios también poder cargar y enviar el mismo archivo en el chat?

1 me gusta

Sí, esto parece ser un pequeño error, alguien lo revisará en las próximas semanas, me complace añadirle un “PR welcome” mientras tanto.

1 me gusta

Me tomó un tiempo investigar esto, pero creo que encontré la causa. Creo que tiene que ver con este código:

def fetch_uploads(params:, guardian:)
  return [] if !SiteSetting.chat_allow_uploads
  guardian.user.uploads.where(id: params.upload_ids) # Específicamente, aquí
end

Cuando se crea un nuevo mensaje de chat, se llama a esto para obtener las cargas adjuntas al mensaje. Posiblemente para garantizar la propiedad, el método recorre el usuario del Guardián para obtener las cargas, de modo que solo se permitan las cargas que pertenecen a ese usuario.

El problema es que las cargas se desduplican, como se ve aquí:

# ¿ya tenemos esa carga?
@upload = Upload.find_by(sha1: sha1)

# ...

# devuelve la carga anterior si la hay
if @upload
  add_metadata!
  UserUpload.find_or_create_by!(user_id: user_id, upload_id: @upload.id) if user_id
  return @upload
end

Creo que una posible solución sería recorrer los UserUpload en lugar de solo considerar las cargas que pertenecen al usuario. UserUpload vincula las cargas a varios usuarios, que parece ser lo que necesitamos. Aún no estoy 100% seguro de cómo hacerlo correctamente; ya es tarde, así que me iré a dormir, pero si nadie más lo soluciona, intentaré volver más tarde y trabajar en un PR. :slightly_smiling_face:

3 Me gusta

Esta es una observación fantástica y muy acertada. :hugs:

Las cargas tienen un user_id, pero ese es solo el usuario original que creó la carga.

Convertir ese código a:

Upload.where(id: params.upload_ids).joins(:user_uploads).where(user_uploads: { user_id: guardian.user.id })

hará el truco.

¿Puedes enviar una PR!

Gracias, no estaba seguro de la mejor manera de construir esa consulta (soy bastante nuevo aquí :slightly_smiling_face:). Trabajaré en una PR.

3 Me gusta

Ok, finalmente terminé el PR. Disculpa la demora, surgieron problemas personales.

FIX: en los mensajes del chat, filtrar cargas por UserUpload, no por Upload.user por clechasseur · Pull Request #34596 · discourse/discourse

Veo que algunas de las pruebas han fallado, pero no son pruebas que yo haya tocado. También he tenido problemas para ejecutar las pruebas en estos archivos localmente: he recibido los mismos errores de clave duplicada que veo aquí… No estoy seguro de si fui yo quien rompió algo o si las pruebas a veces son inestables…

Una buena regla general es volver a ejecutar las pruebas fallidas al menos tres veces y solo empezar a entrar en pánico si fallan por tercera vez :winking_face_with_tongue:

Dicho esto, ¿quizás @j.jaffeux pueda ayudar?

1 me gusta

Sí, estos son solo errores aleatorios e intermitentes, tus cambios están bien. Volveré a ejecutar las pruebas de PR, si pasa o falla con el mismo error de secuencia aleatoria, aprobaré y fusionaré.

1 me gusta

Soy demasiado fan del terror como para no saber qué pasa cuando haces algo tres veces :sweat_smile:

2 Me gusta

Esta PR ha sido fusionada, gracias de nuevo por la contribución @clechasseur :rocket:

6 Me gusta