MM-22845: Added support for permalink previews. (#17796)

* MM-22845: Added support for permalink previews.

* MM-22845: Adds license to new file.

* MM-22845: Adds endpoint to retrieve multiple posts by id.

* MM-22845: Fix for deleted post.

* MM-22845: Adds config setting for permalink previews.

* MM-22845: Adds API test for new endpoint.

* MM-22845: Fix typo.

* MM-22845: Tests that post create or updated via App get the previewed_post prop.

* MM-22845: Tests for matching permalinks.

* MM-22845: Adds PreparePostForClient test for permalink previews.

* MM-22845: Embeds entire post in permalink metadata.

* MM-22845: Filter WS message payload of created and edited post based on permissions.

* MM-22845: Runs app layer generator.

* MM-22845: Lint check fix.

* MM-22845: Adds feature flag.

* MM-22845: Clones WS message.

* MM-22845: Removes knowledge of permalink from LinkMetadata table. Removes knowledge of user id from post embedding methods in favour of a 'sanitize' method/step.

* MM-22845: Handle nil post metadata.

* MM-22845: Switch to cloning post.

* MM-22845: Removes unused code.

* MM-22845: Refactor.

* MM-22845: Reverts whitespace change.

* MM-22845: Removes unnecessary code.

* MM-22845: Removes unnecessary function.

* MM-22845: Warn but don't error if permalinked referenced post or channel is not found.

* MM-22845: Fix for clone method.

* MM-22845: Fix for clone method.

* MM-22845: Updates translations.

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Martin Kraft
2021-08-09 11:33:21 -04:00
коммит произвёл GitHub
родитель 56be6b539c
Коммит 21639f9c87
28 изменённых файлов: 645 добавлений и 115 удалений

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

@@ -303,6 +303,7 @@ type ServiceSettings struct {
GoogleDeveloperKey *string `access:"site_posts,write_restrictable,cloud_restrictable"`
DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations *bool `json:"EnableOnlyAdminIntegrations" mapstructure:"EnableOnlyAdminIntegrations"` // Deprecated: do not use
EnableLinkPreviews *bool `access:"site_posts"`
EnablePermalinkPreviews *bool `access:"site_posts"`
RestrictLinkPreviews *string `access:"site_posts"`
EnableTesting *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
EnableDeveloper *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
@@ -413,6 +414,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
s.EnableLinkPreviews = NewBool(true)
}
if s.EnablePermalinkPreviews == nil {
s.EnablePermalinkPreviews = NewBool(true)
}
if s.RestrictLinkPreviews == nil {
s.RestrictLinkPreviews = NewString("")
}

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

@@ -36,6 +36,8 @@ type FeatureFlags struct {
// Enable timed dnd support for user status
TimedDND bool
PermalinkPreviews bool
// Enable the Global Header
GlobalHeader bool
@@ -54,6 +56,7 @@ func (f *FeatureFlags) SetDefaults() {
f.PluginApps = ""
f.PluginFocalboard = ""
f.TimedDND = false
f.PermalinkPreviews = true
f.GlobalHeader = false
f.InviteMembersButton = "none"
}

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

@@ -3,6 +3,8 @@
package model
import "encoding/json"
type MessageExport struct {
TeamId *string
TeamName *string
@@ -34,3 +36,15 @@ type MessageExportCursor struct {
LastPostUpdateAt int64
LastPostId string
}
// PreviewID returns the value of the post's previewed_post prop, if present, or an empty string.
func (m *MessageExport) PreviewID() string {
var previewID string
props := map[string]interface{}{}
if m.PostProps != nil && json.Unmarshal([]byte(*m.PostProps), &props) == nil {
if val, ok := props[PostPropsPreviewedPost]; ok {
previewID = val.(string)
}
}
return previewID
}

34
model/permalink.go Обычный файл
Просмотреть файл

@@ -0,0 +1,34 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import "encoding/json"
type Permalink struct {
PreviewPost *PreviewPost `json:"preview_post"`
}
type PreviewPost struct {
PostID string `json:"post_id"`
Post *Post `json:"post"`
TeamName string `json:"team_name"`
ChannelDisplayName string `json:"channel_display_name"`
}
func NewPreviewPost(post *Post, team *Team, channel *Channel) *PreviewPost {
if post == nil {
return nil
}
return &PreviewPost{
PostID: post.Id,
Post: post,
TeamName: team.Name,
ChannelDisplayName: channel.DisplayName,
}
}
func (o *Permalink) ToJson() string {
b, _ := json.Marshal(o)
return string(b)
}

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

@@ -67,6 +67,8 @@ const (
PostPropsMentionHighlightDisabled = "mentionHighlightDisabled"
PostPropsGroupHighlightDisabled = "disable_group_highlight"
PostPropsPreviewedPost = "previewed_post"
)
type Post struct {
@@ -749,3 +751,14 @@ func (o *Post) ToNilIfInvalid() *Post {
}
return o
}
func (o *Post) GetPreviewPost() *PreviewPost {
for _, embed := range o.Metadata.Embeds {
if embed.Type == PostEmbedPermalink {
if previewPost, ok := embed.Data.(*PreviewPost); ok {
return previewPost
}
}
}
return nil
}

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

@@ -8,6 +8,7 @@ const (
PostEmbedMessageAttachment PostEmbedType = "message_attachment"
PostEmbedOpengraph PostEmbedType = "opengraph"
PostEmbedLink PostEmbedType = "link"
PostEmbedPermalink PostEmbedType = "permalink"
)
type PostEmbedType string

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

@@ -25,6 +25,23 @@ func NewPostList() *PostList {
}
}
func (o *PostList) Clone() *PostList {
orderCopy := make([]string, len(o.Order))
postsCopy := make(map[string]*Post)
for i, v := range o.Order {
orderCopy[i] = v
}
for k, v := range o.Posts {
postsCopy[k] = v.Clone()
}
return &PostList{
Order: orderCopy,
Posts: postsCopy,
NextPostId: o.NextPostId,
PrevPostId: o.PrevPostId,
}
}
func (o *PostList) ToSlice() []*Post {
var posts []*Post