Mono repo -> Master (#22553)
Combines the following repositories into one: https://github.com/mattermost/mattermost-server https://github.com/mattermost/mattermost-webapp https://github.com/mattermost/focalboard https://github.com/mattermost/mattermost-plugin-playbooks
Этот коммит содержится в:
147
server/channels/app/platform/shared_channel_notifier.go
Обычный файл
147
server/channels/app/platform/shared_channel_notifier.go
Обычный файл
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package platform
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/services/sharedchannel"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
)
|
||||
|
||||
var sharedChannelEventsForSync model.StringArray = []string{
|
||||
model.WebsocketEventPosted,
|
||||
model.WebsocketEventPostEdited,
|
||||
model.WebsocketEventPostDeleted,
|
||||
model.WebsocketEventReactionAdded,
|
||||
model.WebsocketEventReactionRemoved,
|
||||
}
|
||||
|
||||
var sharedChannelEventsForInvitation model.StringArray = []string{
|
||||
model.WebsocketEventDirectAdded,
|
||||
}
|
||||
|
||||
// SharedChannelSyncHandler is called when a websocket event is received by a cluster node.
|
||||
// Only on the leader node it will notify the sync service to perform necessary updates to the remote for the given
|
||||
// shared channel.
|
||||
func (ps *PlatformService) SharedChannelSyncHandler(event *model.WebSocketEvent) {
|
||||
syncService := ps.sharedChannelService
|
||||
if syncService == nil {
|
||||
return
|
||||
}
|
||||
if isEligibleForEvents(syncService, event, sharedChannelEventsForSync) {
|
||||
err := handleContentSync(ps, syncService, event)
|
||||
if err != nil {
|
||||
mlog.Warn(
|
||||
err.Error(),
|
||||
mlog.String("event", event.EventType()),
|
||||
mlog.String("action", "content_sync"),
|
||||
)
|
||||
}
|
||||
} else if isEligibleForEvents(syncService, event, sharedChannelEventsForInvitation) {
|
||||
err := handleInvitation(ps, syncService, event)
|
||||
if err != nil {
|
||||
mlog.Warn(
|
||||
err.Error(),
|
||||
mlog.String("event", event.EventType()),
|
||||
mlog.String("action", "invitation"),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isEligibleForEvents(syncService SharedChannelServiceIFace, event *model.WebSocketEvent, events model.StringArray) bool {
|
||||
return syncServiceEnabled(syncService) &&
|
||||
eventHasChannel(event) &&
|
||||
events.Contains(event.EventType())
|
||||
}
|
||||
|
||||
func eventHasChannel(event *model.WebSocketEvent) bool {
|
||||
return event.GetBroadcast() != nil &&
|
||||
event.GetBroadcast().ChannelId != ""
|
||||
}
|
||||
|
||||
func syncServiceEnabled(syncService SharedChannelServiceIFace) bool {
|
||||
return syncService != nil &&
|
||||
syncService.Active()
|
||||
}
|
||||
|
||||
func handleContentSync(ps *PlatformService, syncService SharedChannelServiceIFace, event *model.WebSocketEvent) error {
|
||||
channel, err := findChannel(ps, event.GetBroadcast().ChannelId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if channel != nil && channel.IsShared() {
|
||||
syncService.NotifyChannelChanged(channel.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleInvitation(ps *PlatformService, syncService SharedChannelServiceIFace, event *model.WebSocketEvent) error {
|
||||
channel, err := findChannel(ps, event.GetBroadcast().ChannelId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if channel == nil || !channel.IsShared() {
|
||||
return nil
|
||||
}
|
||||
|
||||
creator, err := getUserFromEvent(ps, event, "creator_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// This is a termination condition, since on the other end when we are processing
|
||||
// the invite we are re-triggering a model.WEBSOCKET_EVENT_DIRECT_ADDED, which will call this handler.
|
||||
// When the creator is remote, it means that this is a DM that was not originated from the current server
|
||||
// and therefore we do not need to do anything.
|
||||
if creator == nil || creator.IsRemote() {
|
||||
return nil
|
||||
}
|
||||
|
||||
participant, err := getUserFromEvent(ps, event, "teammate_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if participant == nil || participant.RemoteId == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
rc, err := ps.Store.RemoteCluster().Get(*participant.RemoteId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("couldn't find remote cluster %s, for creating shared channel invitation for a DM", *participant.RemoteId))
|
||||
}
|
||||
|
||||
return syncService.SendChannelInvite(channel, creator.Id, rc, sharedchannel.WithDirectParticipantID(creator.Id), sharedchannel.WithDirectParticipantID(participant.Id))
|
||||
}
|
||||
|
||||
func getUserFromEvent(ps *PlatformService, event *model.WebSocketEvent, key string) (*model.User, error) {
|
||||
userID, ok := event.GetData()[key].(string)
|
||||
if !ok || userID == "" {
|
||||
return nil, fmt.Errorf("received websocket message that is eligible for sending an invitation but message does not have `%s` present", key)
|
||||
}
|
||||
|
||||
user, err := ps.Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "couldn't find user for creating shared channel invitation for a DM")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func findChannel(server *PlatformService, channelId string) (*model.Channel, error) {
|
||||
channel, err := server.Store.Channel().Get(channelId, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "received websocket message that is eligible for shared channel sync but channel does not exist")
|
||||
}
|
||||
|
||||
return channel, nil
|
||||
}
|
||||
Ссылка в новой задаче
Block a user