채팅 업로드 버그

안녕하세요, 채팅 DM에서 파일이나 이미지를 업로드할 때 발견한 문제를 보고합니다.

  • 사용자 A가 게시물이나 채팅에서 파일 A를 업로드하면 정상적으로 작동하며 파일이 올바르게 등록됩니다.

  • 하지만 사용자 B파일 A를 다운로드한 후 다른 채팅에서 다시 업로드하려고 하면 다음과 같은 문제가 발생합니다:

    • 사용자 B가 파일을 텍스트 없이 전송하면 다음 오류가 발생합니다:

      Message is too short, must have a minimum of 1 character.
      
      
    • 사용자 B가 파일을 텍스트와 함께 전송하면 텍스트만 전송되고 첨부 파일이 누락됩니다.

그러나 사용자 A가 동일한 파일을 다시 업로드하면 정상적으로 작동하며 파일이 메시지에 포함됩니다.

질문:
이는 원래 업로더만 업로드한 파일을 재사용할 수 있도록 설계된 의도된 동작인가요? 아니면 다른 사용자도 채팅에서 동일한 파일을 업로드하고 전송할 수 있어야 하는 건가요?

1개의 좋아요

네, 이건 좀 버그인 것 같네요. 앞으로 몇 주 안에 누군가 확인해볼 거예요. 그 사이 PR을 올려주시면 환영합니다.

1개의 좋아요

이 문제를 파헤치느라 시간이 좀 걸렸지만, 원인을 찾은 것 같습니다. 아마도 이 코드와 관련이 있을 것 같습니다:

def fetch_uploads(params:, guardian:)
  return [] if !SiteSetting.chat_allow_uploads
  guardian.user.uploads.where(id: params.upload_ids) # 특히 여기
end

새로운 채팅 메시지가 생성될 때 이 메서드가 호출되어 메시지에 첨부할 업로드를 가져옵니다. 소유권을 보장하기 위해 Guardian의 user를 통해 업로드를 가져오도록 하여 해당 사용자 소유의 업로드만 허용하는 것 같습니다.

문제는 업로드가 중복 제거(deduplication)된다는 점입니다. 여기에서 확인할 수 있습니다:

# do we already have that upload?
@upload = Upload.find_by(sha1: sha1)

# ...

# return the previous upload if any
if @upload
  add_metadata!
  UserUpload.find_or_create_by!(user_id: user_id, upload_id: @upload.id) if user_id
  return @upload
end

제 생각에는 사용자의 업로드만 고려하는 대신 UserUpload를 통해 처리하는 것이 가능한 해결책이 될 수 있습니다. UserUpload는 업로드를 여러 사용자와 연결하므로, 이것이 우리가 필요한 것 같습니다. 아직 100% 확실하지는 않지만, 시간이 늦어지므로 이제 잠자리에 들겠습니다. 다른 사람이 해결하지 않는다면 나중에 돌아와서 PR을 작업해 보겠습니다. :slightly_smiling_face:

3개의 좋아요

정말 훌륭한 지적이네요. 정확히 짚어주셨어요. :hugs:

업로드에는 user_id가 있지만, 이는 단순히 업로드를 최초로 생성한 사용자입니다.

해당 코드를 다음과 같이 변환하면 됩니다:

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

PR을 보내주실 수 있을까요!

감사합니다. 그 쿼리를 어떻게 작성해야 할지 확신이 없었거든요 (여기서는 아직 초보입니다 :slightly_smiling_face: ). PR을 만들어 보겠습니다.

3개의 좋아요

음, 드디어 PR을 완료했습니다. 지연된 점 죄송합니다. 개인적인 사정이 발생해서요.

FIX: in chat messages, filter uploads by `UserUpload`, not by `Upload.user` by clechasseur · Pull Request #34596 · discourse/discourse

일부 테스트가 실패한 것을 확인했습니다. 하지만 제가 건드린 테스트는 아닙니다. 해당 파일의 테스트를 로컬에서 실행할 때도 문제가 있었는데, 여기서 보는 것과 같은 중복 키 오류가 발생했습니다… 제가 무언가를 깨뜨린 것인지, 아니면 테스트가 간헐적으로 불안정(flaky)한 것인지는 잘 모르겠습니다…

실패한 테스트를 최소 3회 재실행하고, 세 번째 시도에서도 실패할 때만 걱정하기 시작하는 것이 좋은 규칙입니다 :winking_face_with_tongue:

그렇다고 해도 @j.jaffeux 님이 도움을 줄 수 있을지도 모르겠습니다?

1개의 좋아요

네, 이건 그냥 불안정한 테스트나 기타 랜덤 에러일 뿐이니, 당신의 변경 사항은 문제없습니다. PR 테스트를 다시 실행해 보겠습니다. 통과하거나 동일한 랜덤 시퀀스 에러로만 실패한다면 승인 후 병합하겠습니다.

1개의 좋아요

호러 영화를 너무 좋아해서 세 번 하면 어떤 일이 벌어지는지 모를 수가 없어요. :sweat_smile:

2개의 좋아요

이 PR이 병합되었습니다. 기여해 주셔서 다시 한번 감사드립니다 @clechasseur :rocket:

6개의 좋아요