MM-45009: Delete ThreadMemberships from "left" channels (#22559)

* MM-50550: Filter out threads from "left" channels v2

Currently leaving a channel doesn't affect the thread memberships of
that user/channel combination.
This PR aims to filter out all threads from those channels for the user.

Adds a DeleteAt column in the ThreadMemberships table, and filter out
all thread memberships that are "deleted".
Each time a user leaves a channel all thread memberships are going to be
marked as deleted, and when a user joins a channel again all those
existing thread memberships will be re-instantiated.

Adds a migration to mark all existing thread memberships as deleted
depending on whether there exists a channel membership for that
channel/user.

* Added migration files into list

* Fixes tests

* Fixes case where DeleteAt would be null

* Guard thread API endpoints with appropriate perms

* Deletes ThreadMembership rows upon leaving channel

* Minor style changes

* Use NoTranslation error

* Refactors tests

* Adds API tests to assert permissions on Team

* Adds tests, and fixes migrations

* Fixes test description

* Fix test

* Removes check on DM/GMs

* Change the MySQL query in the migration

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Kyriakos Z
2023-04-19 15:20:34 +03:00
коммит произвёл GitHub
родитель c34a50a6c7
Коммит a24111f9bd
16 изменённых файлов: 426 добавлений и 38 удалений

Просмотреть файл

@@ -688,6 +688,28 @@ func (s *SqlThreadStore) UpdateMembership(membership *model.ThreadMembership) (*
return s.updateMembership(s.GetMasterX(), membership)
}
func (s *SqlThreadStore) DeleteMembershipsForChannel(userID, channelID string) error {
subQuery := s.getSubQueryBuilder().
Select("1").
From("Threads").
Where(sq.And{
sq.Expr("Threads.PostId = ThreadMemberships.PostId"),
sq.Eq{"Threads.ChannelId": channelID},
})
query := s.getQueryBuilder().
Delete("ThreadMemberships").
Where(sq.Eq{"UserId": userID}).
Where(sq.Expr("EXISTS (?)", subQuery))
_, err := s.GetMasterX().ExecBuilder(query)
if err != nil {
return errors.Wrapf(err, "failed to remove thread memberships with userid=%s channelid=%s", userID, channelID)
}
return nil
}
func (s *SqlThreadStore) updateMembership(ex sqlxExecutor, membership *model.ThreadMembership) (*model.ThreadMembership, error) {
query := s.getQueryBuilder().
Update("ThreadMemberships").
@@ -712,7 +734,14 @@ func (s *SqlThreadStore) GetMembershipsForUser(userId, teamId string) ([]*model.
memberships := []*model.ThreadMembership{}
query := s.getQueryBuilder().
Select("ThreadMemberships.*").
Select(
"ThreadMemberships.PostId",
"ThreadMemberships.UserId",
"ThreadMemberships.Following",
"ThreadMemberships.LastUpdated",
"ThreadMemberships.LastViewed",
"ThreadMemberships.UnreadMentions",
).
Join("Threads ON Threads.PostId = ThreadMemberships.PostId").
From("ThreadMemberships").
Where(sq.Or{sq.Eq{"Threads.ThreadTeamId": teamId}, sq.Eq{"Threads.ThreadTeamId": ""}}).
@@ -732,7 +761,14 @@ func (s *SqlThreadStore) GetMembershipForUser(userId, postId string) (*model.Thr
func (s *SqlThreadStore) getMembershipForUser(ex sqlxExecutor, userId, postId string) (*model.ThreadMembership, error) {
var membership model.ThreadMembership
query := s.getQueryBuilder().
Select("*").
Select(
"PostId",
"UserId",
"Following",
"LastUpdated",
"LastViewed",
"UnreadMentions",
).
From("ThreadMemberships").
Where(sq.And{
sq.Eq{"PostId": postId},