Bug no Upload de Chat

Olá, quero relatar um problema que encontrei ao carregar arquivos ou imagens em DMs de chat.

  • Quando o Usuário A carrega o Arquivo A em uma postagem ou chat, funciona bem e o arquivo é registrado corretamente.

  • Mas quando o Usuário B baixa o Arquivo A e tenta carregá-lo novamente em outro chat:

    • Se o Usuário B envia o arquivo sem texto, ele recebe um erro:

      Message is too short, must have a minimum of 1 character.
      
    • Se o Usuário B envia o arquivo com texto, apenas o texto é enviado — o anexo está faltando.

No entanto, se o Usuário A recarregar o mesmo arquivo novamente, funciona bem e o arquivo é incluído na mensagem.

Minha pergunta:
Este é o comportamento pretendido, onde apenas o remetente original pode reutilizar um arquivo carregado? Ou outros usuários também deveriam poder carregar e enviar o mesmo arquivo no chat?

1 curtida

Sim, isso parece um pequeno problema, alguém vai analisar nas próximas semanas, fico feliz em colocar um PR bem-vindo nisso no interim.

1 curtida

Demorou um pouco para eu analisar isso, mas acho que encontrei a causa. Acho que tem a ver com este código:

def fetch_uploads(params:, guardian:)
  return [] if !SiteSetting.chat_allow_uploads
  guardian.user.uploads.where(id: params.upload_ids) # Especificamente, aqui
end

Quando uma nova mensagem de chat é criada, isso é chamado para buscar os uploads a serem anexados à mensagem. Possivelmente para garantir a propriedade, o método passa pelo usuário do Guardian para buscar os uploads, de modo a permitir apenas uploads pertencentes a esse usuário.

O problema é que os uploads são deduplicados, como visto aqui:

# já temos esse upload?
@upload = Upload.find_by(sha1: sha1)

# ...

# retorna o upload anterior, se houver
if @upload
  add_metadata!
  UserUpload.find_or_create_by!(user_id: user_id, upload_id: @upload.id) if user_id
  return @upload
end

Eu acho que uma possível correção seria passar pelos UserUploads em vez de apenas considerar os uploads pertencentes ao usuário. UserUpload vincula uploads a vários usuários, o que parece ser o que precisamos. Ainda não tenho 100% de certeza de como fazer isso corretamente; está ficando tarde, então vou dormir, mas se ninguém mais corrigir, tentarei voltar mais tarde e trabalhar em um PR. :slightly_smiling_face:

3 curtidas

Esta é uma observação fantástica e muito precisa. :hugs:

Uploads têm um user_id, mas esse é apenas o usuário original que criou o upload.

Converter esse código para:

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

resolverá o problema.

Você pode enviar um PR!

Obrigado, eu não tinha certeza de como construir melhor essa consulta (sou bem novo aqui :slightly_smiling_face: ). Vou trabalhar em um PR.

3 curtidas

Ok, finalmente terminei o PR. Desculpe pelo atraso, problemas pessoais surgiram.

FIX: nas mensagens do chat, filtrar uploads por UserUpload, não por Upload.user por clechasseur · Pull Request #34596 · discourse/discourse

Vejo que alguns dos testes falharam, mas não são testes que eu mexi. Tenho tido problemas para executar os testes nesses arquivos localmente também - recebi os mesmos erros de chave duplicada que vejo aqui… Não tenho certeza se fui eu que quebrei algo ou se os testes às vezes são instáveis…

Uma boa regra é reexecutar os testes falhados pelo menos três vezes e só começar a entrar em pânico se eles falharem na terceira vez :winking_face_with_tongue:

Dito isso, @j.jaffeux talvez possa ajudar?

1 curtida

Sim, estes são apenas erros aleatórios e outros erros aleatórios, suas alterações estão boas. Reexecutando os testes do PR, se ele passar ou apenas falhar com o mesmo erro de sequência aleatória, aprovarei + mesclarei.

1 curtida

Sou fã demais de terror para não saber o que acontece quando você faz algo três vezes :sweat_smile:

2 curtidas

Este PR foi mesclado, obrigado novamente pela contribuição @clechasseur :rocket:

6 curtidas