mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-03 04:57:44 +00:00
Use mattermost v5 module (#1192)
This commit is contained in:
222
vendor/github.com/mattermost/mattermost-server/model/channel.go
generated
vendored
222
vendor/github.com/mattermost/mattermost-server/model/channel.go
generated
vendored
@ -1,222 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
CHANNEL_OPEN = "O"
|
||||
CHANNEL_PRIVATE = "P"
|
||||
CHANNEL_DIRECT = "D"
|
||||
CHANNEL_GROUP = "G"
|
||||
CHANNEL_GROUP_MAX_USERS = 8
|
||||
CHANNEL_GROUP_MIN_USERS = 3
|
||||
DEFAULT_CHANNEL = "town-square"
|
||||
CHANNEL_DISPLAY_NAME_MAX_RUNES = 64
|
||||
CHANNEL_NAME_MIN_LENGTH = 2
|
||||
CHANNEL_NAME_MAX_LENGTH = 64
|
||||
CHANNEL_NAME_UI_MAX_LENGTH = 22
|
||||
CHANNEL_HEADER_MAX_RUNES = 1024
|
||||
CHANNEL_PURPOSE_MAX_RUNES = 250
|
||||
CHANNEL_CACHE_SIZE = 25000
|
||||
)
|
||||
|
||||
type Channel struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
TeamId string `json:"team_id"`
|
||||
Type string `json:"type"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Header string `json:"header"`
|
||||
Purpose string `json:"purpose"`
|
||||
LastPostAt int64 `json:"last_post_at"`
|
||||
TotalMsgCount int64 `json:"total_msg_count"`
|
||||
ExtraUpdateAt int64 `json:"extra_update_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
SchemeId *string `json:"scheme_id"`
|
||||
Props map[string]interface{} `json:"props" db:"-"`
|
||||
}
|
||||
|
||||
type ChannelPatch struct {
|
||||
DisplayName *string `json:"display_name"`
|
||||
Name *string `json:"name"`
|
||||
Header *string `json:"header"`
|
||||
Purpose *string `json:"purpose"`
|
||||
}
|
||||
|
||||
type ChannelForExport struct {
|
||||
Channel
|
||||
TeamName string
|
||||
SchemeName *string
|
||||
}
|
||||
|
||||
func (o *Channel) DeepCopy() *Channel {
|
||||
copy := *o
|
||||
if copy.SchemeId != nil {
|
||||
copy.SchemeId = NewString(*o.SchemeId)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
func (o *Channel) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *ChannelPatch) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelFromJson(data io.Reader) *Channel {
|
||||
var o *Channel
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelPatchFromJson(data io.Reader) *ChannelPatch {
|
||||
var o *ChannelPatch
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Channel) Etag() string {
|
||||
return Etag(o.Id, o.UpdateAt)
|
||||
}
|
||||
|
||||
func (o *Channel) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.DisplayName) > CHANNEL_DISPLAY_NAME_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.display_name.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidChannelIdentifier(o.Name) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(o.Type == CHANNEL_OPEN || o.Type == CHANNEL_PRIVATE || o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.type.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Header) > CHANNEL_HEADER_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.header.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Purpose) > CHANNEL_PURPOSE_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.purpose.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) > 26 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.creator_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Channel) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
o.UpdateAt = o.CreateAt
|
||||
o.ExtraUpdateAt = 0
|
||||
}
|
||||
|
||||
func (o *Channel) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (o *Channel) IsGroupOrDirect() bool {
|
||||
return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP
|
||||
}
|
||||
|
||||
func (o *Channel) Patch(patch *ChannelPatch) {
|
||||
if patch.DisplayName != nil {
|
||||
o.DisplayName = *patch.DisplayName
|
||||
}
|
||||
|
||||
if patch.Name != nil {
|
||||
o.Name = *patch.Name
|
||||
}
|
||||
|
||||
if patch.Header != nil {
|
||||
o.Header = *patch.Header
|
||||
}
|
||||
|
||||
if patch.Purpose != nil {
|
||||
o.Purpose = *patch.Purpose
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Channel) MakeNonNil() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Channel) AddProp(key string, value interface{}) {
|
||||
o.MakeNonNil()
|
||||
|
||||
o.Props[key] = value
|
||||
}
|
||||
|
||||
func GetDMNameFromIds(userId1, userId2 string) string {
|
||||
if userId1 > userId2 {
|
||||
return userId2 + "__" + userId1
|
||||
} else {
|
||||
return userId1 + "__" + userId2
|
||||
}
|
||||
}
|
||||
|
||||
func GetGroupDisplayNameFromUsers(users []*User, truncate bool) string {
|
||||
usernames := make([]string, len(users))
|
||||
for index, user := range users {
|
||||
usernames[index] = user.Username
|
||||
}
|
||||
|
||||
sort.Strings(usernames)
|
||||
|
||||
name := strings.Join(usernames, ", ")
|
||||
|
||||
if truncate && len(name) > CHANNEL_NAME_MAX_LENGTH {
|
||||
name = name[:CHANNEL_NAME_MAX_LENGTH]
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func GetGroupNameFromUserIds(userIds []string) string {
|
||||
sort.Strings(userIds)
|
||||
|
||||
h := sha1.New()
|
||||
for _, id := range userIds {
|
||||
io.WriteString(h, id)
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
26
vendor/github.com/mattermost/mattermost-server/model/channel_search.go
generated
vendored
26
vendor/github.com/mattermost/mattermost-server/model/channel_search.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelSearch struct {
|
||||
Term string `json:"term"`
|
||||
}
|
||||
|
||||
// ToJson convert a Channel to a json string
|
||||
func (c *ChannelSearch) ToJson() string {
|
||||
b, _ := json.Marshal(c)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// ChannelSearchFromJson will decode the input and return a Channel
|
||||
func ChannelSearchFromJson(data io.Reader) *ChannelSearch {
|
||||
var cs *ChannelSearch
|
||||
json.NewDecoder(data).Decode(&cs)
|
||||
return cs
|
||||
}
|
3839
vendor/github.com/mattermost/mattermost-server/model/client4.go
generated
vendored
3839
vendor/github.com/mattermost/mattermost-server/model/client4.go
generated
vendored
File diff suppressed because it is too large
Load Diff
34
vendor/github.com/mattermost/mattermost-server/model/command_args.go
generated
vendored
34
vendor/github.com/mattermost/mattermost-server/model/command_args.go
generated
vendored
@ -1,34 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
goi18n "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
type CommandArgs struct {
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
RootId string `json:"root_id"`
|
||||
ParentId string `json:"parent_id"`
|
||||
Command string `json:"command"`
|
||||
SiteURL string `json:"-"`
|
||||
T goi18n.TranslateFunc `json:"-"`
|
||||
Session Session `json:"-"`
|
||||
}
|
||||
|
||||
func (o *CommandArgs) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CommandArgsFromJson(data io.Reader) *CommandArgs {
|
||||
var o *CommandArgs
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
2569
vendor/github.com/mattermost/mattermost-server/model/config.go
generated
vendored
2569
vendor/github.com/mattermost/mattermost-server/model/config.go
generated
vendored
File diff suppressed because it is too large
Load Diff
8
vendor/github.com/mattermost/mattermost-server/model/ldap.go
generated
vendored
8
vendor/github.com/mattermost/mattermost-server/model/ldap.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_LDAP = "ldap"
|
||||
)
|
8
vendor/github.com/mattermost/mattermost-server/model/migration.go
generated
vendored
8
vendor/github.com/mattermost/mattermost-server/model/migration.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2 = "migration_advanced_permissions_phase_2"
|
||||
)
|
70
vendor/github.com/mattermost/mattermost-server/model/push_notification.go
generated
vendored
70
vendor/github.com/mattermost/mattermost-server/model/push_notification.go
generated
vendored
@ -1,70 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
PUSH_NOTIFY_APPLE = "apple"
|
||||
PUSH_NOTIFY_ANDROID = "android"
|
||||
PUSH_NOTIFY_APPLE_REACT_NATIVE = "apple_rn"
|
||||
PUSH_NOTIFY_ANDROID_REACT_NATIVE = "android_rn"
|
||||
|
||||
PUSH_TYPE_MESSAGE = "message"
|
||||
PUSH_TYPE_CLEAR = "clear"
|
||||
PUSH_MESSAGE_V2 = "v2"
|
||||
|
||||
// The category is set to handle a set of interactive Actions
|
||||
// with the push notifications
|
||||
CATEGORY_CAN_REPLY = "CAN_REPLY"
|
||||
|
||||
MHPNS = "https://push.mattermost.com"
|
||||
)
|
||||
|
||||
type PushNotification struct {
|
||||
Platform string `json:"platform"`
|
||||
ServerId string `json:"server_id"`
|
||||
DeviceId string `json:"device_id"`
|
||||
Category string `json:"category"`
|
||||
Sound string `json:"sound"`
|
||||
Message string `json:"message"`
|
||||
Badge int `json:"badge"`
|
||||
ContentAvailable int `json:"cont_ava"`
|
||||
TeamId string `json:"team_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
PostId string `json:"post_id"`
|
||||
RootId string `json:"root_id"`
|
||||
ChannelName string `json:"channel_name"`
|
||||
Type string `json:"type"`
|
||||
SenderId string `json:"sender_id"`
|
||||
OverrideUsername string `json:"override_username"`
|
||||
OverrideIconUrl string `json:"override_icon_url"`
|
||||
FromWebhook string `json:"from_webhook"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func (me *PushNotification) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (me *PushNotification) SetDeviceIdAndPlatform(deviceId string) {
|
||||
|
||||
index := strings.Index(deviceId, ":")
|
||||
|
||||
if index > -1 {
|
||||
me.Platform = deviceId[:index]
|
||||
me.DeviceId = deviceId[index+1:]
|
||||
}
|
||||
}
|
||||
|
||||
func PushNotificationFromJson(data io.Reader) *PushNotification {
|
||||
var me *PushNotification
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
363
vendor/github.com/mattermost/mattermost-server/model/role.go
generated
vendored
363
vendor/github.com/mattermost/mattermost-server/model/role.go
generated
vendored
@ -1,363 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
SYSTEM_USER_ROLE_ID = "system_user"
|
||||
SYSTEM_ADMIN_ROLE_ID = "system_admin"
|
||||
SYSTEM_POST_ALL_ROLE_ID = "system_post_all"
|
||||
SYSTEM_POST_ALL_PUBLIC_ROLE_ID = "system_post_all_public"
|
||||
SYSTEM_USER_ACCESS_TOKEN_ROLE_ID = "system_user_access_token"
|
||||
|
||||
TEAM_USER_ROLE_ID = "team_user"
|
||||
TEAM_ADMIN_ROLE_ID = "team_admin"
|
||||
TEAM_POST_ALL_ROLE_ID = "team_post_all"
|
||||
TEAM_POST_ALL_PUBLIC_ROLE_ID = "team_post_all_public"
|
||||
|
||||
CHANNEL_USER_ROLE_ID = "channel_user"
|
||||
CHANNEL_ADMIN_ROLE_ID = "channel_admin"
|
||||
|
||||
ROLE_NAME_MAX_LENGTH = 64
|
||||
ROLE_DISPLAY_NAME_MAX_LENGTH = 128
|
||||
ROLE_DESCRIPTION_MAX_LENGTH = 1024
|
||||
)
|
||||
|
||||
type Role struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
Permissions []string `json:"permissions"`
|
||||
SchemeManaged bool `json:"scheme_managed"`
|
||||
BuiltIn bool `json:"built_in"`
|
||||
}
|
||||
|
||||
type RolePatch struct {
|
||||
Permissions *[]string `json:"permissions"`
|
||||
}
|
||||
|
||||
func (role *Role) ToJson() string {
|
||||
b, _ := json.Marshal(role)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func RoleFromJson(data io.Reader) *Role {
|
||||
var role *Role
|
||||
json.NewDecoder(data).Decode(&role)
|
||||
return role
|
||||
}
|
||||
|
||||
func RoleListToJson(r []*Role) string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func RoleListFromJson(data io.Reader) []*Role {
|
||||
var roles []*Role
|
||||
json.NewDecoder(data).Decode(&roles)
|
||||
return roles
|
||||
}
|
||||
|
||||
func (r *RolePatch) ToJson() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func RolePatchFromJson(data io.Reader) *RolePatch {
|
||||
var rolePatch *RolePatch
|
||||
json.NewDecoder(data).Decode(&rolePatch)
|
||||
return rolePatch
|
||||
}
|
||||
|
||||
func (o *Role) Patch(patch *RolePatch) {
|
||||
if patch.Permissions != nil {
|
||||
o.Permissions = *patch.Permissions
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an array of permissions that are in either role.Permissions
|
||||
// or patch.Permissions, but not both.
|
||||
func PermissionsChangedByPatch(role *Role, patch *RolePatch) []string {
|
||||
var result []string
|
||||
|
||||
if patch.Permissions == nil {
|
||||
return result
|
||||
}
|
||||
|
||||
roleMap := make(map[string]bool)
|
||||
patchMap := make(map[string]bool)
|
||||
|
||||
for _, permission := range role.Permissions {
|
||||
roleMap[permission] = true
|
||||
}
|
||||
|
||||
for _, permission := range *patch.Permissions {
|
||||
patchMap[permission] = true
|
||||
}
|
||||
|
||||
for _, permission := range role.Permissions {
|
||||
if !patchMap[permission] {
|
||||
result = append(result, permission)
|
||||
}
|
||||
}
|
||||
|
||||
for _, permission := range *patch.Permissions {
|
||||
if !roleMap[permission] {
|
||||
result = append(result, permission)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (role *Role) IsValid() bool {
|
||||
if len(role.Id) != 26 {
|
||||
return false
|
||||
}
|
||||
|
||||
return role.IsValidWithoutId()
|
||||
}
|
||||
|
||||
func (role *Role) IsValidWithoutId() bool {
|
||||
if !IsValidRoleName(role.Name) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(role.DisplayName) == 0 || len(role.DisplayName) > ROLE_DISPLAY_NAME_MAX_LENGTH {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(role.Description) > ROLE_DESCRIPTION_MAX_LENGTH {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, permission := range role.Permissions {
|
||||
permissionValidated := false
|
||||
for _, p := range ALL_PERMISSIONS {
|
||||
if permission == p.Id {
|
||||
permissionValidated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !permissionValidated {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func IsValidRoleName(roleName string) bool {
|
||||
if len(roleName) <= 0 || len(roleName) > ROLE_NAME_MAX_LENGTH {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.TrimLeft(roleName, "abcdefghijklmnopqrstuvwxyz0123456789_") != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func MakeDefaultRoles() map[string]*Role {
|
||||
roles := make(map[string]*Role)
|
||||
|
||||
roles[CHANNEL_USER_ROLE_ID] = &Role{
|
||||
Name: "channel_user",
|
||||
DisplayName: "authentication.roles.channel_user.name",
|
||||
Description: "authentication.roles.channel_user.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_READ_CHANNEL.Id,
|
||||
PERMISSION_ADD_REACTION.Id,
|
||||
PERMISSION_REMOVE_REACTION.Id,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
|
||||
PERMISSION_UPLOAD_FILE.Id,
|
||||
PERMISSION_GET_PUBLIC_LINK.Id,
|
||||
PERMISSION_CREATE_POST.Id,
|
||||
PERMISSION_USE_SLASH_COMMANDS.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[CHANNEL_ADMIN_ROLE_ID] = &Role{
|
||||
Name: "channel_admin",
|
||||
DisplayName: "authentication.roles.channel_admin.name",
|
||||
Description: "authentication.roles.channel_admin.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[TEAM_USER_ROLE_ID] = &Role{
|
||||
Name: "team_user",
|
||||
DisplayName: "authentication.roles.team_user.name",
|
||||
Description: "authentication.roles.team_user.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
PERMISSION_VIEW_TEAM.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[TEAM_POST_ALL_ROLE_ID] = &Role{
|
||||
Name: "team_post_all",
|
||||
DisplayName: "authentication.roles.team_post_all.name",
|
||||
Description: "authentication.roles.team_post_all.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[TEAM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
|
||||
Name: "team_post_all_public",
|
||||
DisplayName: "authentication.roles.team_post_all_public.name",
|
||||
Description: "authentication.roles.team_post_all_public.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[TEAM_ADMIN_ROLE_ID] = &Role{
|
||||
Name: "team_admin",
|
||||
DisplayName: "authentication.roles.team_admin.name",
|
||||
Description: "authentication.roles.team_admin.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_REMOVE_USER_FROM_TEAM.Id,
|
||||
PERMISSION_MANAGE_TEAM.Id,
|
||||
PERMISSION_IMPORT_TEAM.Id,
|
||||
PERMISSION_MANAGE_TEAM_ROLES.Id,
|
||||
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
|
||||
PERMISSION_MANAGE_SLASH_COMMANDS.Id,
|
||||
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
|
||||
PERMISSION_MANAGE_WEBHOOKS.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_USER_ROLE_ID] = &Role{
|
||||
Name: "system_user",
|
||||
DisplayName: "authentication.roles.global_user.name",
|
||||
Description: "authentication.roles.global_user.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
PERMISSION_PERMANENT_DELETE_USER.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_POST_ALL_ROLE_ID] = &Role{
|
||||
Name: "system_post_all",
|
||||
DisplayName: "authentication.roles.system_post_all.name",
|
||||
Description: "authentication.roles.system_post_all.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
|
||||
Name: "system_post_all_public",
|
||||
DisplayName: "authentication.roles.system_post_all_public.name",
|
||||
Description: "authentication.roles.system_post_all_public.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_USER_ACCESS_TOKEN_ROLE_ID] = &Role{
|
||||
Name: "system_user_access_token",
|
||||
DisplayName: "authentication.roles.system_user_access_token.name",
|
||||
Description: "authentication.roles.system_user_access_token.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
},
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_ADMIN_ROLE_ID] = &Role{
|
||||
Name: "system_admin",
|
||||
DisplayName: "authentication.roles.global_admin.name",
|
||||
Description: "authentication.roles.global_admin.description",
|
||||
// System admins can do anything channel and team admins can do
|
||||
// plus everything members of teams and channels can do to all teams
|
||||
// and channels on the system
|
||||
Permissions: append(
|
||||
append(
|
||||
append(
|
||||
append(
|
||||
[]string{
|
||||
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
|
||||
PERMISSION_MANAGE_SYSTEM.Id,
|
||||
PERMISSION_MANAGE_ROLES.Id,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
|
||||
PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
|
||||
PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
|
||||
PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
|
||||
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
|
||||
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
|
||||
PERMISSION_EDIT_OTHER_USERS.Id,
|
||||
PERMISSION_EDIT_OTHERS_POSTS.Id,
|
||||
PERMISSION_MANAGE_OAUTH.Id,
|
||||
PERMISSION_INVITE_USER.Id,
|
||||
PERMISSION_DELETE_POST.Id,
|
||||
PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
PERMISSION_CREATE_TEAM.Id,
|
||||
PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||
PERMISSION_LIST_USERS_WITHOUT_TEAM.Id,
|
||||
PERMISSION_MANAGE_JOBS.Id,
|
||||
PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
PERMISSION_CREATE_POST_EPHEMERAL.Id,
|
||||
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
},
|
||||
roles[TEAM_USER_ROLE_ID].Permissions...,
|
||||
),
|
||||
roles[CHANNEL_USER_ROLE_ID].Permissions...,
|
||||
),
|
||||
roles[TEAM_ADMIN_ROLE_ID].Permissions...,
|
||||
),
|
||||
roles[CHANNEL_ADMIN_ROLE_ID].Permissions...,
|
||||
),
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
return roles
|
||||
}
|
37
vendor/github.com/mattermost/mattermost-server/model/saml.go
generated
vendored
37
vendor/github.com/mattermost/mattermost-server/model/saml.go
generated
vendored
@ -1,37 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_SAML = "saml"
|
||||
USER_AUTH_SERVICE_SAML_TEXT = "With SAML"
|
||||
)
|
||||
|
||||
type SamlAuthRequest struct {
|
||||
Base64AuthRequest string
|
||||
URL string
|
||||
RelayState string
|
||||
}
|
||||
|
||||
type SamlCertificateStatus struct {
|
||||
IdpCertificateFile bool `json:"idp_certificate_file"`
|
||||
PrivateKeyFile bool `json:"private_key_file"`
|
||||
PublicCertificateFile bool `json:"public_certificate_file"`
|
||||
}
|
||||
|
||||
func (s *SamlCertificateStatus) ToJson() string {
|
||||
b, _ := json.Marshal(s)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func SamlCertificateStatusFromJson(data io.Reader) *SamlCertificateStatus {
|
||||
var status *SamlCertificateStatus
|
||||
json.NewDecoder(data).Decode(&status)
|
||||
return status
|
||||
}
|
228
vendor/github.com/mattermost/mattermost-server/model/search_params.go
generated
vendored
228
vendor/github.com/mattermost/mattermost-server/model/search_params.go
generated
vendored
@ -1,228 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var searchTermPuncStart = regexp.MustCompile(`^[^\pL\d\s#"]+`)
|
||||
var searchTermPuncEnd = regexp.MustCompile(`[^\pL\d\s*"]+$`)
|
||||
|
||||
type SearchParams struct {
|
||||
Terms string
|
||||
IsHashtag bool
|
||||
InChannels []string
|
||||
FromUsers []string
|
||||
AfterDate string
|
||||
BeforeDate string
|
||||
OnDate string
|
||||
OrTerms bool
|
||||
IncludeDeletedChannels bool
|
||||
TimeZoneOffset int
|
||||
}
|
||||
|
||||
// Returns the epoch timestamp of the start of the day specified by SearchParams.AfterDate
|
||||
func (p *SearchParams) GetAfterDateMillis() int64 {
|
||||
date, err := time.Parse("2006-01-02", PadDateStringZeros(p.AfterDate))
|
||||
if err != nil {
|
||||
date = time.Now()
|
||||
}
|
||||
|
||||
// travel forward 1 day
|
||||
oneDay := time.Hour * 24
|
||||
afterDate := date.Add(oneDay)
|
||||
return GetStartOfDayMillis(afterDate, p.TimeZoneOffset)
|
||||
}
|
||||
|
||||
// Returns the epoch timestamp of the end of the day specified by SearchParams.BeforeDate
|
||||
func (p *SearchParams) GetBeforeDateMillis() int64 {
|
||||
date, err := time.Parse("2006-01-02", PadDateStringZeros(p.BeforeDate))
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
// travel back 1 day
|
||||
oneDay := time.Hour * -24
|
||||
beforeDate := date.Add(oneDay)
|
||||
return GetEndOfDayMillis(beforeDate, p.TimeZoneOffset)
|
||||
}
|
||||
|
||||
// Returns the epoch timestamps of the start and end of the day specified by SearchParams.OnDate
|
||||
func (p *SearchParams) GetOnDateMillis() (int64, int64) {
|
||||
date, err := time.Parse("2006-01-02", PadDateStringZeros(p.OnDate))
|
||||
if err != nil {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
return GetStartOfDayMillis(date, p.TimeZoneOffset), GetEndOfDayMillis(date, p.TimeZoneOffset)
|
||||
}
|
||||
|
||||
var searchFlags = [...]string{"from", "channel", "in", "before", "after", "on"}
|
||||
|
||||
func splitWords(text string) []string {
|
||||
words := []string{}
|
||||
|
||||
foundQuote := false
|
||||
location := 0
|
||||
for i, char := range text {
|
||||
if char == '"' {
|
||||
if foundQuote {
|
||||
// Grab the quoted section
|
||||
word := text[location : i+1]
|
||||
words = append(words, word)
|
||||
foundQuote = false
|
||||
location = i + 1
|
||||
} else {
|
||||
words = append(words, strings.Fields(text[location:i])...)
|
||||
foundQuote = true
|
||||
location = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
words = append(words, strings.Fields(text[location:])...)
|
||||
|
||||
return words
|
||||
}
|
||||
|
||||
func parseSearchFlags(input []string) ([]string, [][2]string) {
|
||||
words := []string{}
|
||||
flags := [][2]string{}
|
||||
|
||||
skipNextWord := false
|
||||
for i, word := range input {
|
||||
if skipNextWord {
|
||||
skipNextWord = false
|
||||
continue
|
||||
}
|
||||
|
||||
isFlag := false
|
||||
|
||||
if colon := strings.Index(word, ":"); colon != -1 {
|
||||
flag := word[:colon]
|
||||
value := word[colon+1:]
|
||||
|
||||
for _, searchFlag := range searchFlags {
|
||||
// check for case insensitive equality
|
||||
if strings.EqualFold(flag, searchFlag) {
|
||||
if value != "" {
|
||||
flags = append(flags, [2]string{searchFlag, value})
|
||||
isFlag = true
|
||||
} else if i < len(input)-1 {
|
||||
flags = append(flags, [2]string{searchFlag, input[i+1]})
|
||||
skipNextWord = true
|
||||
isFlag = true
|
||||
}
|
||||
|
||||
if isFlag {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !isFlag {
|
||||
// trim off surrounding punctuation (note that we leave trailing asterisks to allow wildcards)
|
||||
word = searchTermPuncStart.ReplaceAllString(word, "")
|
||||
word = searchTermPuncEnd.ReplaceAllString(word, "")
|
||||
|
||||
// and remove extra pound #s
|
||||
word = hashtagStart.ReplaceAllString(word, "#")
|
||||
|
||||
if len(word) != 0 {
|
||||
words = append(words, word)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return words, flags
|
||||
}
|
||||
|
||||
func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
|
||||
words, flags := parseSearchFlags(splitWords(text))
|
||||
|
||||
hashtagTermList := []string{}
|
||||
plainTermList := []string{}
|
||||
|
||||
for _, word := range words {
|
||||
if validHashtag.MatchString(word) {
|
||||
hashtagTermList = append(hashtagTermList, word)
|
||||
} else {
|
||||
plainTermList = append(plainTermList, word)
|
||||
}
|
||||
}
|
||||
|
||||
hashtagTerms := strings.Join(hashtagTermList, " ")
|
||||
plainTerms := strings.Join(plainTermList, " ")
|
||||
|
||||
inChannels := []string{}
|
||||
fromUsers := []string{}
|
||||
afterDate := ""
|
||||
beforeDate := ""
|
||||
onDate := ""
|
||||
|
||||
for _, flagPair := range flags {
|
||||
flag := flagPair[0]
|
||||
value := flagPair[1]
|
||||
|
||||
if flag == "in" || flag == "channel" {
|
||||
inChannels = append(inChannels, value)
|
||||
} else if flag == "from" {
|
||||
fromUsers = append(fromUsers, value)
|
||||
} else if flag == "after" {
|
||||
afterDate = value
|
||||
} else if flag == "before" {
|
||||
beforeDate = value
|
||||
} else if flag == "on" {
|
||||
onDate = value
|
||||
}
|
||||
}
|
||||
|
||||
paramsList := []*SearchParams{}
|
||||
|
||||
if len(plainTerms) > 0 {
|
||||
paramsList = append(paramsList, &SearchParams{
|
||||
Terms: plainTerms,
|
||||
IsHashtag: false,
|
||||
InChannels: inChannels,
|
||||
FromUsers: fromUsers,
|
||||
AfterDate: afterDate,
|
||||
BeforeDate: beforeDate,
|
||||
OnDate: onDate,
|
||||
TimeZoneOffset: timeZoneOffset,
|
||||
})
|
||||
}
|
||||
|
||||
if len(hashtagTerms) > 0 {
|
||||
paramsList = append(paramsList, &SearchParams{
|
||||
Terms: hashtagTerms,
|
||||
IsHashtag: true,
|
||||
InChannels: inChannels,
|
||||
FromUsers: fromUsers,
|
||||
AfterDate: afterDate,
|
||||
BeforeDate: beforeDate,
|
||||
OnDate: onDate,
|
||||
TimeZoneOffset: timeZoneOffset,
|
||||
})
|
||||
}
|
||||
|
||||
// special case for when no terms are specified but we still have a filter
|
||||
if len(plainTerms) == 0 && len(hashtagTerms) == 0 && (len(inChannels) != 0 || len(fromUsers) != 0 || len(afterDate) != 0 || len(beforeDate) != 0 || len(onDate) != 0) {
|
||||
paramsList = append(paramsList, &SearchParams{
|
||||
Terms: "",
|
||||
IsHashtag: false,
|
||||
InChannels: inChannels,
|
||||
FromUsers: fromUsers,
|
||||
AfterDate: afterDate,
|
||||
BeforeDate: beforeDate,
|
||||
OnDate: onDate,
|
||||
TimeZoneOffset: timeZoneOffset,
|
||||
})
|
||||
}
|
||||
|
||||
return paramsList
|
||||
}
|
47
vendor/github.com/mattermost/mattermost-server/model/system.go
generated
vendored
47
vendor/github.com/mattermost/mattermost-server/model/system.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
const (
|
||||
SYSTEM_DIAGNOSTIC_ID = "DiagnosticId"
|
||||
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
|
||||
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
|
||||
SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId"
|
||||
SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime"
|
||||
SYSTEM_ASYMMETRIC_SIGNING_KEY = "AsymmetricSigningKey"
|
||||
SYSTEM_INSTALLATION_DATE_KEY = "InstallationDate"
|
||||
)
|
||||
|
||||
type System struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (o *System) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func SystemFromJson(data io.Reader) *System {
|
||||
var o *System
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
type SystemAsymmetricSigningKey struct {
|
||||
ECDSAKey *SystemECDSAKey `json:"ecdsa_key,omitempty"`
|
||||
}
|
||||
|
||||
type SystemECDSAKey struct {
|
||||
Curve string `json:"curve"`
|
||||
X *big.Int `json:"x"`
|
||||
Y *big.Int `json:"y"`
|
||||
D *big.Int `json:"d,omitempty"`
|
||||
}
|
102
vendor/github.com/mattermost/mattermost-server/model/team_member.go
generated
vendored
102
vendor/github.com/mattermost/mattermost-server/model/team_member.go
generated
vendored
@ -1,102 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TeamMember struct {
|
||||
TeamId string `json:"team_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Roles string `json:"roles"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
SchemeUser bool `json:"scheme_user"`
|
||||
SchemeAdmin bool `json:"scheme_admin"`
|
||||
ExplicitRoles string `json:"explicit_roles"`
|
||||
}
|
||||
|
||||
type TeamUnread struct {
|
||||
TeamId string `json:"team_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
}
|
||||
|
||||
type TeamMemberForExport struct {
|
||||
TeamMember
|
||||
TeamName string
|
||||
}
|
||||
|
||||
func (o *TeamMember) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *TeamUnread) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func TeamMemberFromJson(data io.Reader) *TeamMember {
|
||||
var o *TeamMember
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func TeamUnreadFromJson(data io.Reader) *TeamUnread {
|
||||
var o *TeamUnread
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func TeamMembersToJson(o []*TeamMember) string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TeamMembersFromJson(data io.Reader) []*TeamMember {
|
||||
var o []*TeamMember
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func TeamsUnreadToJson(o []*TeamUnread) string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TeamsUnreadFromJson(data io.Reader) []*TeamUnread {
|
||||
var o []*TeamUnread
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TeamMember) IsValid() *AppError {
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
return NewAppError("TeamMember.IsValid", "model.team_member.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
return NewAppError("TeamMember.IsValid", "model.team_member.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *TeamMember) PreUpdate() {
|
||||
}
|
||||
|
||||
func (o *TeamMember) GetRoles() []string {
|
||||
return strings.Fields(o.Roles)
|
||||
}
|
32
vendor/github.com/mattermost/mattermost-server/model/user_search.go
generated
vendored
32
vendor/github.com/mattermost/mattermost-server/model/user_search.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type UserSearch struct {
|
||||
Term string `json:"term"`
|
||||
TeamId string `json:"team_id"`
|
||||
NotInTeamId string `json:"not_in_team_id"`
|
||||
InChannelId string `json:"in_channel_id"`
|
||||
NotInChannelId string `json:"not_in_channel_id"`
|
||||
AllowInactive bool `json:"allow_inactive"`
|
||||
WithoutTeam bool `json:"without_team"`
|
||||
}
|
||||
|
||||
// ToJson convert a User to a json string
|
||||
func (u *UserSearch) ToJson() string {
|
||||
b, _ := json.Marshal(u)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// UserSearchFromJson will decode the input and return a User
|
||||
func UserSearchFromJson(data io.Reader) *UserSearch {
|
||||
var us *UserSearch
|
||||
json.NewDecoder(data).Decode(&us)
|
||||
return us
|
||||
}
|
39
vendor/github.com/mattermost/mattermost-server/model/webrtc.go
generated
vendored
39
vendor/github.com/mattermost/mattermost-server/model/webrtc.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type WebrtcInfoResponse struct {
|
||||
Token string `json:"token"`
|
||||
GatewayUrl string `json:"gateway_url"`
|
||||
StunUri string `json:"stun_uri,omitempty"`
|
||||
TurnUri string `json:"turn_uri,omitempty"`
|
||||
TurnPassword string `json:"turn_password,omitempty"`
|
||||
TurnUsername string `json:"turn_username,omitempty"`
|
||||
}
|
||||
|
||||
type GatewayResponse struct {
|
||||
Status string `json:"janus"`
|
||||
}
|
||||
|
||||
func GatewayResponseFromJson(data io.Reader) *GatewayResponse {
|
||||
var o *GatewayResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *WebrtcInfoResponse) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func WebrtcInfoResponseFromJson(data io.Reader) *WebrtcInfoResponse {
|
||||
var o *WebrtcInfoResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
195
vendor/github.com/mattermost/mattermost-server/model/websocket_client.go
generated
vendored
195
vendor/github.com/mattermost/mattermost-server/model/websocket_client.go
generated
vendored
@ -1,195 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const (
|
||||
SOCKET_MAX_MESSAGE_SIZE_KB = 8 * 1024 // 8KB
|
||||
PING_TIMEOUT_BUFFER_SECONDS = 5
|
||||
)
|
||||
|
||||
type WebSocketClient struct {
|
||||
Url string // The location of the server like "ws://localhost:8065"
|
||||
ApiUrl string // The api location of the server like "ws://localhost:8065/api/v3"
|
||||
ConnectUrl string // The websocket URL to connect to like "ws://localhost:8065/api/v3/path/to/websocket"
|
||||
Conn *websocket.Conn // The WebSocket connection
|
||||
AuthToken string // The token used to open the WebSocket
|
||||
Sequence int64 // The ever-incrementing sequence attached to each WebSocket action
|
||||
PingTimeoutChannel chan bool // The channel used to signal ping timeouts
|
||||
EventChannel chan *WebSocketEvent
|
||||
ResponseChannel chan *WebSocketResponse
|
||||
ListenError *AppError
|
||||
pingTimeoutTimer *time.Timer
|
||||
}
|
||||
|
||||
// NewWebSocketClient constructs a new WebSocket client with convenience
|
||||
// methods for talking to the server.
|
||||
func NewWebSocketClient(url, authToken string) (*WebSocketClient, *AppError) {
|
||||
return NewWebSocketClientWithDialer(websocket.DefaultDialer, url, authToken)
|
||||
}
|
||||
|
||||
// NewWebSocketClientWithDialer constructs a new WebSocket client with convenience
|
||||
// methods for talking to the server using a custom dialer.
|
||||
func NewWebSocketClientWithDialer(dialer *websocket.Dialer, url, authToken string) (*WebSocketClient, *AppError) {
|
||||
conn, _, err := dialer.Dial(url+API_URL_SUFFIX+"/websocket", nil)
|
||||
if err != nil {
|
||||
return nil, NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
client := &WebSocketClient{
|
||||
url,
|
||||
url + API_URL_SUFFIX,
|
||||
url + API_URL_SUFFIX + "/websocket",
|
||||
conn,
|
||||
authToken,
|
||||
1,
|
||||
make(chan bool, 1),
|
||||
make(chan *WebSocketEvent, 100),
|
||||
make(chan *WebSocketResponse, 100),
|
||||
nil,
|
||||
nil,
|
||||
}
|
||||
|
||||
client.configurePingHandling()
|
||||
|
||||
client.SendMessage(WEBSOCKET_AUTHENTICATION_CHALLENGE, map[string]interface{}{"token": authToken})
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NewWebSocketClient4 constructs a new WebSocket client with convenience
|
||||
// methods for talking to the server. Uses the v4 endpoint.
|
||||
func NewWebSocketClient4(url, authToken string) (*WebSocketClient, *AppError) {
|
||||
return NewWebSocketClient4WithDialer(websocket.DefaultDialer, url, authToken)
|
||||
}
|
||||
|
||||
// NewWebSocketClient4WithDialer constructs a new WebSocket client with convenience
|
||||
// methods for talking to the server using a custom dialer. Uses the v4 endpoint.
|
||||
func NewWebSocketClient4WithDialer(dialer *websocket.Dialer, url, authToken string) (*WebSocketClient, *AppError) {
|
||||
return NewWebSocketClientWithDialer(dialer, url, authToken)
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) Connect() *AppError {
|
||||
return wsc.ConnectWithDialer(websocket.DefaultDialer)
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) ConnectWithDialer(dialer *websocket.Dialer) *AppError {
|
||||
var err error
|
||||
wsc.Conn, _, err = dialer.Dial(wsc.ConnectUrl, nil)
|
||||
if err != nil {
|
||||
return NewAppError("Connect", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
wsc.configurePingHandling()
|
||||
|
||||
wsc.EventChannel = make(chan *WebSocketEvent, 100)
|
||||
wsc.ResponseChannel = make(chan *WebSocketResponse, 100)
|
||||
|
||||
wsc.SendMessage(WEBSOCKET_AUTHENTICATION_CHALLENGE, map[string]interface{}{"token": wsc.AuthToken})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) Close() {
|
||||
wsc.Conn.Close()
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) Listen() {
|
||||
go func() {
|
||||
defer func() {
|
||||
wsc.Conn.Close()
|
||||
close(wsc.EventChannel)
|
||||
close(wsc.ResponseChannel)
|
||||
}()
|
||||
|
||||
for {
|
||||
var rawMsg json.RawMessage
|
||||
var err error
|
||||
if _, rawMsg, err = wsc.Conn.ReadMessage(); err != nil {
|
||||
if !websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
|
||||
wsc.ListenError = NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var event WebSocketEvent
|
||||
if err := json.Unmarshal(rawMsg, &event); err == nil && event.IsValid() {
|
||||
wsc.EventChannel <- &event
|
||||
continue
|
||||
}
|
||||
|
||||
var response WebSocketResponse
|
||||
if err := json.Unmarshal(rawMsg, &response); err == nil && response.IsValid() {
|
||||
wsc.ResponseChannel <- &response
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) SendMessage(action string, data map[string]interface{}) {
|
||||
req := &WebSocketRequest{}
|
||||
req.Seq = wsc.Sequence
|
||||
req.Action = action
|
||||
req.Data = data
|
||||
|
||||
wsc.Sequence++
|
||||
|
||||
wsc.Conn.WriteJSON(req)
|
||||
}
|
||||
|
||||
// UserTyping will push a user_typing event out to all connected users
|
||||
// who are in the specified channel
|
||||
func (wsc *WebSocketClient) UserTyping(channelId, parentId string) {
|
||||
data := map[string]interface{}{
|
||||
"channel_id": channelId,
|
||||
"parent_id": parentId,
|
||||
}
|
||||
|
||||
wsc.SendMessage("user_typing", data)
|
||||
}
|
||||
|
||||
// GetStatuses will return a map of string statuses using user id as the key
|
||||
func (wsc *WebSocketClient) GetStatuses() {
|
||||
wsc.SendMessage("get_statuses", nil)
|
||||
}
|
||||
|
||||
// GetStatusesByIds will fetch certain user statuses based on ids and return
|
||||
// a map of string statuses using user id as the key
|
||||
func (wsc *WebSocketClient) GetStatusesByIds(userIds []string) {
|
||||
data := map[string]interface{}{
|
||||
"user_ids": userIds,
|
||||
}
|
||||
wsc.SendMessage("get_statuses_by_ids", data)
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) configurePingHandling() {
|
||||
wsc.Conn.SetPingHandler(wsc.pingHandler)
|
||||
wsc.pingTimeoutTimer = time.NewTimer(time.Second * (60 + PING_TIMEOUT_BUFFER_SECONDS))
|
||||
go wsc.pingWatchdog()
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) pingHandler(appData string) error {
|
||||
if !wsc.pingTimeoutTimer.Stop() {
|
||||
<-wsc.pingTimeoutTimer.C
|
||||
}
|
||||
|
||||
wsc.pingTimeoutTimer.Reset(time.Second * (60 + PING_TIMEOUT_BUFFER_SECONDS))
|
||||
wsc.Conn.WriteMessage(websocket.PongMessage, []byte{})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) pingWatchdog() {
|
||||
<-wsc.pingTimeoutTimer.C
|
||||
wsc.PingTimeoutChannel <- true
|
||||
}
|
165
vendor/github.com/mattermost/mattermost-server/model/websocket_message.go
generated
vendored
165
vendor/github.com/mattermost/mattermost-server/model/websocket_message.go
generated
vendored
@ -1,165 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
WEBSOCKET_EVENT_TYPING = "typing"
|
||||
WEBSOCKET_EVENT_POSTED = "posted"
|
||||
WEBSOCKET_EVENT_POST_EDITED = "post_edited"
|
||||
WEBSOCKET_EVENT_POST_DELETED = "post_deleted"
|
||||
WEBSOCKET_EVENT_CHANNEL_CONVERTED = "channel_converted"
|
||||
WEBSOCKET_EVENT_CHANNEL_CREATED = "channel_created"
|
||||
WEBSOCKET_EVENT_CHANNEL_DELETED = "channel_deleted"
|
||||
WEBSOCKET_EVENT_CHANNEL_UPDATED = "channel_updated"
|
||||
WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED = "channel_member_updated"
|
||||
WEBSOCKET_EVENT_DIRECT_ADDED = "direct_added"
|
||||
WEBSOCKET_EVENT_GROUP_ADDED = "group_added"
|
||||
WEBSOCKET_EVENT_NEW_USER = "new_user"
|
||||
WEBSOCKET_EVENT_ADDED_TO_TEAM = "added_to_team"
|
||||
WEBSOCKET_EVENT_LEAVE_TEAM = "leave_team"
|
||||
WEBSOCKET_EVENT_UPDATE_TEAM = "update_team"
|
||||
WEBSOCKET_EVENT_DELETE_TEAM = "delete_team"
|
||||
WEBSOCKET_EVENT_USER_ADDED = "user_added"
|
||||
WEBSOCKET_EVENT_USER_UPDATED = "user_updated"
|
||||
WEBSOCKET_EVENT_USER_ROLE_UPDATED = "user_role_updated"
|
||||
WEBSOCKET_EVENT_MEMBERROLE_UPDATED = "memberrole_updated"
|
||||
WEBSOCKET_EVENT_USER_REMOVED = "user_removed"
|
||||
WEBSOCKET_EVENT_PREFERENCE_CHANGED = "preference_changed"
|
||||
WEBSOCKET_EVENT_PREFERENCES_CHANGED = "preferences_changed"
|
||||
WEBSOCKET_EVENT_PREFERENCES_DELETED = "preferences_deleted"
|
||||
WEBSOCKET_EVENT_EPHEMERAL_MESSAGE = "ephemeral_message"
|
||||
WEBSOCKET_EVENT_STATUS_CHANGE = "status_change"
|
||||
WEBSOCKET_EVENT_HELLO = "hello"
|
||||
WEBSOCKET_EVENT_WEBRTC = "webrtc"
|
||||
WEBSOCKET_AUTHENTICATION_CHALLENGE = "authentication_challenge"
|
||||
WEBSOCKET_EVENT_REACTION_ADDED = "reaction_added"
|
||||
WEBSOCKET_EVENT_REACTION_REMOVED = "reaction_removed"
|
||||
WEBSOCKET_EVENT_RESPONSE = "response"
|
||||
WEBSOCKET_EVENT_EMOJI_ADDED = "emoji_added"
|
||||
WEBSOCKET_EVENT_CHANNEL_VIEWED = "channel_viewed"
|
||||
WEBSOCKET_EVENT_PLUGIN_STATUSES_CHANGED = "plugin_statuses_changed"
|
||||
WEBSOCKET_EVENT_PLUGIN_ENABLED = "plugin_enabled"
|
||||
WEBSOCKET_EVENT_PLUGIN_DISABLED = "plugin_disabled"
|
||||
WEBSOCKET_EVENT_ROLE_UPDATED = "role_updated"
|
||||
WEBSOCKET_EVENT_LICENSE_CHANGED = "license_changed"
|
||||
WEBSOCKET_EVENT_CONFIG_CHANGED = "config_changed"
|
||||
)
|
||||
|
||||
type WebSocketMessage interface {
|
||||
ToJson() string
|
||||
IsValid() bool
|
||||
EventType() string
|
||||
}
|
||||
|
||||
type WebsocketBroadcast struct {
|
||||
OmitUsers map[string]bool `json:"omit_users"` // broadcast is omitted for users listed here
|
||||
UserId string `json:"user_id"` // broadcast only occurs for this user
|
||||
ChannelId string `json:"channel_id"` // broadcast only occurs for users in this channel
|
||||
TeamId string `json:"team_id"` // broadcast only occurs for users in this team
|
||||
ContainsSanitizedData bool `json:"-"`
|
||||
ContainsSensitiveData bool `json:"-"`
|
||||
}
|
||||
|
||||
type precomputedWebSocketEventJSON struct {
|
||||
Event json.RawMessage
|
||||
Data json.RawMessage
|
||||
Broadcast json.RawMessage
|
||||
}
|
||||
|
||||
type WebSocketEvent struct {
|
||||
Event string `json:"event"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Broadcast *WebsocketBroadcast `json:"broadcast"`
|
||||
Sequence int64 `json:"seq"`
|
||||
|
||||
precomputedJSON *precomputedWebSocketEventJSON
|
||||
}
|
||||
|
||||
// PrecomputeJSON precomputes and stores the serialized JSON for all fields other than Sequence.
|
||||
// This makes ToJson much more efficient when sending the same event to multiple connections.
|
||||
func (m *WebSocketEvent) PrecomputeJSON() {
|
||||
event, _ := json.Marshal(m.Event)
|
||||
data, _ := json.Marshal(m.Data)
|
||||
broadcast, _ := json.Marshal(m.Broadcast)
|
||||
m.precomputedJSON = &precomputedWebSocketEventJSON{
|
||||
Event: json.RawMessage(event),
|
||||
Data: json.RawMessage(data),
|
||||
Broadcast: json.RawMessage(broadcast),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *WebSocketEvent) Add(key string, value interface{}) {
|
||||
m.Data[key] = value
|
||||
}
|
||||
|
||||
func NewWebSocketEvent(event, teamId, channelId, userId string, omitUsers map[string]bool) *WebSocketEvent {
|
||||
return &WebSocketEvent{Event: event, Data: make(map[string]interface{}),
|
||||
Broadcast: &WebsocketBroadcast{TeamId: teamId, ChannelId: channelId, UserId: userId, OmitUsers: omitUsers}}
|
||||
}
|
||||
|
||||
func (o *WebSocketEvent) IsValid() bool {
|
||||
return o.Event != ""
|
||||
}
|
||||
|
||||
func (o *WebSocketEvent) EventType() string {
|
||||
return o.Event
|
||||
}
|
||||
|
||||
func (o *WebSocketEvent) ToJson() string {
|
||||
if o.precomputedJSON != nil {
|
||||
return fmt.Sprintf(`{"event": %s, "data": %s, "broadcast": %s, "seq": %d}`, o.precomputedJSON.Event, o.precomputedJSON.Data, o.precomputedJSON.Broadcast, o.Sequence)
|
||||
}
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func WebSocketEventFromJson(data io.Reader) *WebSocketEvent {
|
||||
var o *WebSocketEvent
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
type WebSocketResponse struct {
|
||||
Status string `json:"status"`
|
||||
SeqReply int64 `json:"seq_reply,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
Error *AppError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (m *WebSocketResponse) Add(key string, value interface{}) {
|
||||
m.Data[key] = value
|
||||
}
|
||||
|
||||
func NewWebSocketResponse(status string, seqReply int64, data map[string]interface{}) *WebSocketResponse {
|
||||
return &WebSocketResponse{Status: status, SeqReply: seqReply, Data: data}
|
||||
}
|
||||
|
||||
func NewWebSocketError(seqReply int64, err *AppError) *WebSocketResponse {
|
||||
return &WebSocketResponse{Status: STATUS_FAIL, SeqReply: seqReply, Error: err}
|
||||
}
|
||||
|
||||
func (o *WebSocketResponse) IsValid() bool {
|
||||
return o.Status != ""
|
||||
}
|
||||
|
||||
func (o *WebSocketResponse) EventType() string {
|
||||
return WEBSOCKET_EVENT_RESPONSE
|
||||
}
|
||||
|
||||
func (o *WebSocketResponse) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func WebSocketResponseFromJson(data io.Reader) *WebSocketResponse {
|
||||
var o *WebSocketResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
34
vendor/github.com/mattermost/mattermost-server/model/websocket_request.go
generated
vendored
34
vendor/github.com/mattermost/mattermost-server/model/websocket_request.go
generated
vendored
@ -1,34 +0,0 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
goi18n "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
type WebSocketRequest struct {
|
||||
// Client-provided fields
|
||||
Seq int64 `json:"seq"`
|
||||
Action string `json:"action"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
|
||||
// Server-provided fields
|
||||
Session Session `json:"-"`
|
||||
T goi18n.TranslateFunc `json:"-"`
|
||||
Locale string `json:"-"`
|
||||
}
|
||||
|
||||
func (o *WebSocketRequest) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func WebSocketRequestFromJson(data io.Reader) *WebSocketRequest {
|
||||
var o *WebSocketRequest
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
@ -11,7 +11,7 @@ You may be licensed to use source code to create compiled versions not produced
|
||||
1. Under the Free Software Foundation’s GNU AGPL v.3.0, subject to the exceptions outlined in this policy; or
|
||||
2. Under a commercial license available from Mattermost, Inc. by contacting commercial@mattermost.com
|
||||
|
||||
You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/, model/,
|
||||
You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/default.json, model/,
|
||||
plugin/ and all subdirectories thereof) under the Apache License v2.0.
|
||||
|
||||
We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does not
|
@ -6,13 +6,89 @@ NOTICES:
|
||||
|
||||
This document includes a list of open source components used in Mattermost Server, including those that have been modified.
|
||||
|
||||
-----
|
||||
|
||||
## Go
|
||||
|
||||
This product uses the Go programming language by the Go authors.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://golang.org
|
||||
|
||||
* LICENSE: BSD-style
|
||||
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---
|
||||
|
||||
## Masterminds/squirrel
|
||||
|
||||
This product contains 'squirrel' by GitHub user "Masterminds".
|
||||
|
||||
Fluent SQL generation for golang
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/Masterminds/squirrel
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
Squirrel
|
||||
The Masterminds
|
||||
Copyright (C) 2014-2015, Lann Martin
|
||||
Copyright (C) 2015-2016, Google
|
||||
Copyright (C) 2015, Matt Farina and Matt Butcher
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## NYTimes/gziphandler
|
||||
|
||||
This product contains 'gziphandler' by The New York Times.
|
||||
|
||||
Golang middleware to gzip HTTP responses
|
||||
Go middleware to gzip HTTP responses
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/NYTimes/gziphandler
|
||||
@ -429,6 +505,41 @@ Go package for fast and reliable abstraction of browser user agent strings.
|
||||
|
||||
---
|
||||
|
||||
## blang/semver
|
||||
|
||||
This product contains 'semver' by Benedikt Lang.
|
||||
|
||||
Semantic Versioning (semver) library written in golang
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/blang/semver
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## dgryski/dgoogauth
|
||||
|
||||
This product contains 'dgoogauth' by Damian Gryski.
|
||||
@ -502,7 +613,7 @@ APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||
|
||||
Copyright 2018 Damian Gryski
|
||||
Copyright 2019 Damian Gryski
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -531,7 +642,7 @@ Imaging is a simple image processing package for Go
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2018 Grigory Dryapak
|
||||
Copyright (c) 2012 Grigory Dryapak
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -2282,9 +2393,9 @@ SOFTWARE.
|
||||
|
||||
## minio/minio-go
|
||||
|
||||
This product contains 'minio-go' by Minio Cloud Storage.
|
||||
This product contains 'minio-go' by Object Storage for AI.
|
||||
|
||||
Minio Client SDK for Go
|
||||
MinIO Client SDK for Go
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/minio/minio-go
|
||||
@ -2497,18 +2608,18 @@ Minio Client SDK for Go
|
||||
* This package includes the following NOTICE:
|
||||
|
||||
minio-go
|
||||
Copyright 2015-2017 Minio, Inc.
|
||||
Copyright 2015-2017 MinIO, Inc.
|
||||
|
||||
---
|
||||
|
||||
## nicksnyder/go-i18n
|
||||
|
||||
This product contains 'go-i18n' by Nick Snyder.
|
||||
This product contains 'go-i18n' by Mattermost, modified (forked) from original GitHub repo 'nicksnyder/go-i18n' owned by Nick Snyder.
|
||||
|
||||
Translate your Go program into multiple languages.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/nicksnyder/go-i18n
|
||||
* https://github.com/mattermost/go-i18n
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
@ -2947,6 +3058,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
---
|
||||
|
||||
## sirupsen/logrus
|
||||
|
||||
This product contains 'logrus' by Simon Eskildsen.
|
||||
|
||||
Structured, pluggable logging for Go.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/sirupsen/logrus
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## spf13/cobra
|
||||
|
||||
This product contains 'cobra' by Steve Francia.
|
||||
@ -3135,6 +3281,42 @@ A Commander for modern Go CLI interactions
|
||||
|
||||
---
|
||||
|
||||
## jmoiron/sqlx
|
||||
|
||||
This product contains 'sqlx' by Jason Moiron.
|
||||
|
||||
general purpose extensions to golang's database/sql
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/jmoiron/sqlx
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
Copyright (c) 2013, Jason Moiron
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## stretchr/testify
|
||||
|
||||
This product contains 'testify' by Stretchr, Inc..
|
||||
@ -3146,28 +3328,27 @@ A toolkit with common assertions and mocks that plays nicely with the standard l
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
|
||||
MIT License
|
||||
|
||||
Please consider promoting this project if you find it useful.
|
||||
Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
@ -3388,14 +3569,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---
|
||||
|
||||
## go-gomail/gomail
|
||||
## x/text
|
||||
|
||||
This product contains 'gomail' by Gomail.
|
||||
This product contains 'text' by The Go Authors.
|
||||
|
||||
The best way to send emails in Go.
|
||||
[mirror] Go text processing support
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/go-gomail/gomail
|
||||
* https://github.com/golang/text
|
||||
|
||||
* LICENSE: BSD-3-Clause
|
||||
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---
|
||||
|
||||
## mail
|
||||
|
||||
This product contains 'mail' by GitHub user "go-mail", modified (forked) from original GitHub repo 'go-gomail/gomail' owned by Gomail.
|
||||
|
||||
Actively maintained fork of gomail. The best way to send emails in Go.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/go-mail/mail
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
@ -3719,3 +3941,194 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
---
|
||||
|
||||
## go/imageproxy
|
||||
|
||||
This product contains 'imageproxy' by Will Norris.
|
||||
|
||||
A caching, resizing image proxy written in Go
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/willnorris/imageproxy
|
||||
|
||||
* LICENSE: Apache-2.0
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
@ -1,14 +1,15 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// defaultLog manually encodes the log to STDOUT, providing a basic, default logging implementation
|
||||
// defaultLog manually encodes the log to STDERR, providing a basic, default logging implementation
|
||||
// before mlog is fully configured.
|
||||
func defaultLog(level, msg string, fields ...Field) {
|
||||
log := struct {
|
||||
@ -22,9 +23,9 @@ func defaultLog(level, msg string, fields ...Field) {
|
||||
}
|
||||
|
||||
if b, err := json.Marshal(log); err != nil {
|
||||
fmt.Printf(`{"level":"error","msg":"failed to encode log message"}%s`, "\n")
|
||||
fmt.Fprintf(os.Stderr, `{"level":"error","msg":"failed to encode log message"}%s`, "\n")
|
||||
} else {
|
||||
fmt.Printf("%s\n", b)
|
||||
fmt.Fprintf(os.Stderr, "%s\n", b)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
@ -28,12 +28,15 @@ const (
|
||||
type Field = zapcore.Field
|
||||
|
||||
var Int64 = zap.Int64
|
||||
var Int32 = zap.Int32
|
||||
var Int = zap.Int
|
||||
var Uint32 = zap.Uint32
|
||||
var String = zap.String
|
||||
var Any = zap.Any
|
||||
var Err = zap.Error
|
||||
var NamedErr = zap.NamedError
|
||||
var Bool = zap.Bool
|
||||
var Duration = zap.Duration
|
||||
|
||||
type LoggerConfiguration struct {
|
||||
EnableConsole bool
|
||||
@ -84,7 +87,7 @@ func NewLogger(config *LoggerConfiguration) *Logger {
|
||||
}
|
||||
|
||||
if config.EnableConsole {
|
||||
writer := zapcore.Lock(os.Stdout)
|
||||
writer := zapcore.Lock(os.Stderr)
|
||||
core := zapcore.NewCore(makeEncoder(config.ConsoleJson), writer, logger.consoleLevel)
|
||||
cores = append(cores, core)
|
||||
}
|
||||
@ -102,7 +105,6 @@ func NewLogger(config *LoggerConfiguration) *Logger {
|
||||
combinedCore := zapcore.NewTee(cores...)
|
||||
|
||||
logger.zap = zap.New(combinedCore,
|
||||
zap.AddCallerSkip(1),
|
||||
zap.AddCaller(),
|
||||
)
|
||||
|
||||
@ -128,6 +130,11 @@ func (l *Logger) StdLog(fields ...Field) *log.Logger {
|
||||
return zap.NewStdLog(l.With(fields...).zap.WithOptions(getStdLogOption()))
|
||||
}
|
||||
|
||||
// StdLogAt returns *log.Logger which writes to supplied zap logger at required level.
|
||||
func (l *Logger) StdLogAt(level string, fields ...Field) (*log.Logger, error) {
|
||||
return zap.NewStdLogAt(l.With(fields...).zap.WithOptions(getStdLogOption()), getZapLevel(level))
|
||||
}
|
||||
|
||||
// StdLogWriter returns a writer that can be hooked up to the output of a golang standard logger
|
||||
// anything written will be interpreted as log entries accordingly
|
||||
func (l *Logger) StdLogWriter() io.Writer {
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
@ -81,7 +81,7 @@ type loggerWriter struct {
|
||||
func (l *loggerWriter) Write(p []byte) (int, error) {
|
||||
trimmed := string(bytes.TrimSpace(p))
|
||||
for _, line := range strings.Split(trimmed, "\n") {
|
||||
l.logFunc(string(line))
|
||||
l.logFunc(line)
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
43
vendor/github.com/mattermost/mattermost-server/v5/mlog/testing.go
generated
vendored
Normal file
43
vendor/github.com/mattermost/mattermost-server/v5/mlog/testing.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// testingWriter is an io.Writer that writes through t.Log
|
||||
type testingWriter struct {
|
||||
tb testing.TB
|
||||
}
|
||||
|
||||
func (tw *testingWriter) Write(b []byte) (int, error) {
|
||||
tw.tb.Log(strings.TrimSpace(string(b)))
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// NewTestingLogger creates a Logger that proxies logs through a testing interface.
|
||||
// This allows tests that spin up App instances to avoid spewing logs unless the test fails or -verbose is specified.
|
||||
func NewTestingLogger(tb testing.TB, writer io.Writer) *Logger {
|
||||
logWriter := &testingWriter{tb}
|
||||
multiWriter := io.MultiWriter(logWriter, writer)
|
||||
logWriterSync := zapcore.AddSync(multiWriter)
|
||||
|
||||
testingLogger := &Logger{
|
||||
consoleLevel: zap.NewAtomicLevelAt(getZapLevel("debug")),
|
||||
fileLevel: zap.NewAtomicLevelAt(getZapLevel("info")),
|
||||
}
|
||||
|
||||
logWriterCore := zapcore.NewCore(makeEncoder(true), logWriterSync, testingLogger.consoleLevel)
|
||||
|
||||
testingLogger.zap = zap.New(logWriterCore,
|
||||
zap.AddCaller(),
|
||||
)
|
||||
return testingLogger
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -60,13 +60,13 @@ func (ad *AccessData) IsValid() *AppError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (me *AccessData) IsExpired() bool {
|
||||
func (ad *AccessData) IsExpired() bool {
|
||||
|
||||
if me.ExpiresAt <= 0 {
|
||||
if ad.ExpiresAt <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if GetMillis() > me.ExpiresAt {
|
||||
if GetMillis() > ad.ExpiresAt {
|
||||
return true
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
47
vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go
generated
vendored
Normal file
47
vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var atMentionRegexp = regexp.MustCompile(`\B@[[:alnum:]][[:alnum:]\.\-_]*`)
|
||||
|
||||
const usernameSpecialChars = ".-_"
|
||||
|
||||
// PossibleAtMentions returns all substrings in message that look like valid @
|
||||
// mentions.
|
||||
func PossibleAtMentions(message string) []string {
|
||||
var names []string
|
||||
|
||||
if !strings.Contains(message, "@") {
|
||||
return names
|
||||
}
|
||||
|
||||
alreadyMentioned := make(map[string]bool)
|
||||
for _, match := range atMentionRegexp.FindAllString(message, -1) {
|
||||
name := NormalizeUsername(match[1:])
|
||||
if !alreadyMentioned[name] && IsValidUsername(name) {
|
||||
names = append(names, name)
|
||||
alreadyMentioned[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
// TrimUsernameSpecialChar tries to remove the last character from word if it
|
||||
// is a special character for usernames (dot, dash or underscore). If not, it
|
||||
// returns the same string.
|
||||
func TrimUsernameSpecialChar(word string) (string, bool) {
|
||||
len := len(word)
|
||||
|
||||
if len > 0 && strings.LastIndexAny(word, usernameSpecialChars) == (len-1) {
|
||||
return word[:len-1], true
|
||||
}
|
||||
|
||||
return word, false
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
667
vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go
generated
vendored
Normal file
667
vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go
generated
vendored
Normal file
@ -0,0 +1,667 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import "github.com/francoispqt/gojay"
|
||||
|
||||
// AuditModelTypeConv converts key model types to something better suited for audit output.
|
||||
func AuditModelTypeConv(val interface{}) (newVal interface{}, converted bool) {
|
||||
if val == nil {
|
||||
return nil, false
|
||||
}
|
||||
switch v := val.(type) {
|
||||
case *Channel:
|
||||
return newAuditChannel(v), true
|
||||
case *Team:
|
||||
return newAuditTeam(v), true
|
||||
case *User:
|
||||
return newAuditUser(v), true
|
||||
case *Command:
|
||||
return newAuditCommand(v), true
|
||||
case *CommandArgs:
|
||||
return newAuditCommandArgs(v), true
|
||||
case *Bot:
|
||||
return newAuditBot(v), true
|
||||
case *ChannelModerationPatch:
|
||||
return newAuditChannelModerationPatch(v), true
|
||||
case *Emoji:
|
||||
return newAuditEmoji(v), true
|
||||
case *FileInfo:
|
||||
return newAuditFileInfo(v), true
|
||||
case *Group:
|
||||
return newAuditGroup(v), true
|
||||
case *Job:
|
||||
return newAuditJob(v), true
|
||||
case *OAuthApp:
|
||||
return newAuditOAuthApp(v), true
|
||||
case *Post:
|
||||
return newAuditPost(v), true
|
||||
case *Role:
|
||||
return newAuditRole(v), true
|
||||
case *Scheme:
|
||||
return newAuditScheme(v), true
|
||||
case *SchemeRoles:
|
||||
return newAuditSchemeRoles(v), true
|
||||
case *Session:
|
||||
return newAuditSession(v), true
|
||||
case *IncomingWebhook:
|
||||
return newAuditIncomingWebhook(v), true
|
||||
case *OutgoingWebhook:
|
||||
return newAuditOutgoingWebhook(v), true
|
||||
}
|
||||
return val, false
|
||||
}
|
||||
|
||||
type auditChannel struct {
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
// newAuditChannel creates a simplified representation of Channel for output to audit log.
|
||||
func newAuditChannel(c *Channel) auditChannel {
|
||||
var channel auditChannel
|
||||
if c != nil {
|
||||
channel.ID = c.Id
|
||||
channel.Name = c.Name
|
||||
channel.Type = c.Type
|
||||
}
|
||||
return channel
|
||||
}
|
||||
|
||||
func (c auditChannel) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", c.ID)
|
||||
enc.StringKey("name", c.Name)
|
||||
enc.StringKey("type", c.Type)
|
||||
}
|
||||
|
||||
func (c auditChannel) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditTeam struct {
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
// newAuditTeam creates a simplified representation of Team for output to audit log.
|
||||
func newAuditTeam(t *Team) auditTeam {
|
||||
var team auditTeam
|
||||
if t != nil {
|
||||
team.ID = t.Id
|
||||
team.Name = t.Name
|
||||
team.Type = t.Type
|
||||
}
|
||||
return team
|
||||
}
|
||||
|
||||
func (t auditTeam) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", t.ID)
|
||||
enc.StringKey("name", t.Name)
|
||||
enc.StringKey("type", t.Type)
|
||||
}
|
||||
|
||||
func (t auditTeam) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditUser struct {
|
||||
ID string
|
||||
Name string
|
||||
Roles string
|
||||
}
|
||||
|
||||
// newAuditUser creates a simplified representation of User for output to audit log.
|
||||
func newAuditUser(u *User) auditUser {
|
||||
var user auditUser
|
||||
if u != nil {
|
||||
user.ID = u.Id
|
||||
user.Name = u.Username
|
||||
user.Roles = u.Roles
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
func (u auditUser) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", u.ID)
|
||||
enc.StringKey("name", u.Name)
|
||||
enc.StringKey("roles", u.Roles)
|
||||
}
|
||||
|
||||
func (u auditUser) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditCommand struct {
|
||||
ID string
|
||||
CreatorID string
|
||||
TeamID string
|
||||
Trigger string
|
||||
Method string
|
||||
Username string
|
||||
IconURL string
|
||||
AutoComplete bool
|
||||
AutoCompleteDesc string
|
||||
AutoCompleteHint string
|
||||
DisplayName string
|
||||
Description string
|
||||
URL string
|
||||
}
|
||||
|
||||
// newAuditCommand creates a simplified representation of Command for output to audit log.
|
||||
func newAuditCommand(c *Command) auditCommand {
|
||||
var cmd auditCommand
|
||||
if c != nil {
|
||||
cmd.ID = c.Id
|
||||
cmd.CreatorID = c.CreatorId
|
||||
cmd.TeamID = c.TeamId
|
||||
cmd.Trigger = c.Trigger
|
||||
cmd.Method = c.Method
|
||||
cmd.Username = c.Username
|
||||
cmd.IconURL = c.IconURL
|
||||
cmd.AutoComplete = c.AutoComplete
|
||||
cmd.AutoCompleteDesc = c.AutoCompleteDesc
|
||||
cmd.AutoCompleteHint = c.AutoCompleteHint
|
||||
cmd.DisplayName = c.DisplayName
|
||||
cmd.Description = c.Description
|
||||
cmd.URL = c.URL
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (cmd auditCommand) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", cmd.ID)
|
||||
enc.StringKey("creator_id", cmd.CreatorID)
|
||||
enc.StringKey("team_id", cmd.TeamID)
|
||||
enc.StringKey("trigger", cmd.Trigger)
|
||||
enc.StringKey("method", cmd.Method)
|
||||
enc.StringKey("username", cmd.Username)
|
||||
enc.StringKey("icon_url", cmd.IconURL)
|
||||
enc.BoolKey("auto_complete", cmd.AutoComplete)
|
||||
enc.StringKey("auto_complete_desc", cmd.AutoCompleteDesc)
|
||||
enc.StringKey("auto_complete_hint", cmd.AutoCompleteHint)
|
||||
enc.StringKey("display", cmd.DisplayName)
|
||||
enc.StringKey("desc", cmd.Description)
|
||||
enc.StringKey("url", cmd.URL)
|
||||
}
|
||||
|
||||
func (cmd auditCommand) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditCommandArgs struct {
|
||||
ChannelID string
|
||||
TeamID string
|
||||
TriggerID string
|
||||
Command string
|
||||
}
|
||||
|
||||
// newAuditCommandArgs creates a simplified representation of CommandArgs for output to audit log.
|
||||
func newAuditCommandArgs(ca *CommandArgs) auditCommandArgs {
|
||||
var cmdargs auditCommandArgs
|
||||
if ca != nil {
|
||||
cmdargs.ChannelID = ca.ChannelId
|
||||
cmdargs.TeamID = ca.TeamId
|
||||
cmdargs.TriggerID = ca.TriggerId
|
||||
cmdargs.Command = ca.Command
|
||||
}
|
||||
return cmdargs
|
||||
}
|
||||
|
||||
func (ca auditCommandArgs) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("channel_id", ca.ChannelID)
|
||||
enc.StringKey("team_id", ca.TriggerID)
|
||||
enc.StringKey("trigger_id", ca.TeamID)
|
||||
enc.StringKey("command", ca.Command)
|
||||
}
|
||||
|
||||
func (ca auditCommandArgs) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditBot struct {
|
||||
UserID string
|
||||
Username string
|
||||
Displayname string
|
||||
}
|
||||
|
||||
// newAuditBot creates a simplified representation of Bot for output to audit log.
|
||||
func newAuditBot(b *Bot) auditBot {
|
||||
var bot auditBot
|
||||
if b != nil {
|
||||
bot.UserID = b.UserId
|
||||
bot.Username = b.Username
|
||||
bot.Displayname = b.DisplayName
|
||||
}
|
||||
return bot
|
||||
}
|
||||
|
||||
func (b auditBot) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("user_id", b.UserID)
|
||||
enc.StringKey("username", b.Username)
|
||||
enc.StringKey("display", b.Displayname)
|
||||
}
|
||||
|
||||
func (b auditBot) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditChannelModerationPatch struct {
|
||||
Name string
|
||||
RoleGuests bool
|
||||
RoleMembers bool
|
||||
}
|
||||
|
||||
// newAuditChannelModerationPatch creates a simplified representation of ChannelModerationPatch for output to audit log.
|
||||
func newAuditChannelModerationPatch(p *ChannelModerationPatch) auditChannelModerationPatch {
|
||||
var patch auditChannelModerationPatch
|
||||
if p != nil {
|
||||
if p.Name != nil {
|
||||
patch.Name = *p.Name
|
||||
}
|
||||
if p.Roles.Guests != nil {
|
||||
patch.RoleGuests = *p.Roles.Guests
|
||||
}
|
||||
if p.Roles.Members != nil {
|
||||
patch.RoleMembers = *p.Roles.Members
|
||||
}
|
||||
}
|
||||
return patch
|
||||
}
|
||||
|
||||
func (p auditChannelModerationPatch) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("name", p.Name)
|
||||
enc.BoolKey("role_guests", p.RoleGuests)
|
||||
enc.BoolKey("role_members", p.RoleMembers)
|
||||
}
|
||||
|
||||
func (p auditChannelModerationPatch) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditEmoji struct {
|
||||
ID string
|
||||
Name string
|
||||
}
|
||||
|
||||
// newAuditEmoji creates a simplified representation of Emoji for output to audit log.
|
||||
func newAuditEmoji(e *Emoji) auditEmoji {
|
||||
var emoji auditEmoji
|
||||
if e != nil {
|
||||
emoji.ID = e.Id
|
||||
emoji.Name = e.Name
|
||||
}
|
||||
return emoji
|
||||
}
|
||||
|
||||
func (e auditEmoji) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", e.ID)
|
||||
enc.StringKey("name", e.Name)
|
||||
}
|
||||
|
||||
func (e auditEmoji) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditFileInfo struct {
|
||||
ID string
|
||||
PostID string
|
||||
Path string
|
||||
Name string
|
||||
Extension string
|
||||
Size int64
|
||||
}
|
||||
|
||||
// newAuditFileInfo creates a simplified representation of FileInfo for output to audit log.
|
||||
func newAuditFileInfo(f *FileInfo) auditFileInfo {
|
||||
var fi auditFileInfo
|
||||
if f != nil {
|
||||
fi.ID = f.Id
|
||||
fi.PostID = f.PostId
|
||||
fi.Path = f.Path
|
||||
fi.Name = f.Name
|
||||
fi.Extension = f.Extension
|
||||
fi.Size = f.Size
|
||||
}
|
||||
return fi
|
||||
}
|
||||
|
||||
func (fi auditFileInfo) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", fi.ID)
|
||||
enc.StringKey("post_id", fi.PostID)
|
||||
enc.StringKey("path", fi.Path)
|
||||
enc.StringKey("name", fi.Name)
|
||||
enc.StringKey("ext", fi.Extension)
|
||||
enc.Int64Key("size", fi.Size)
|
||||
}
|
||||
|
||||
func (fi auditFileInfo) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditGroup struct {
|
||||
ID string
|
||||
Name string
|
||||
DisplayName string
|
||||
Description string
|
||||
}
|
||||
|
||||
// newAuditGroup creates a simplified representation of Group for output to audit log.
|
||||
func newAuditGroup(g *Group) auditGroup {
|
||||
var group auditGroup
|
||||
if g != nil {
|
||||
group.ID = g.Id
|
||||
if g.Name == nil {
|
||||
group.Name = ""
|
||||
} else {
|
||||
group.Name = *g.Name
|
||||
}
|
||||
group.DisplayName = g.DisplayName
|
||||
group.Description = g.Description
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
func (g auditGroup) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", g.ID)
|
||||
enc.StringKey("name", g.Name)
|
||||
enc.StringKey("display", g.DisplayName)
|
||||
enc.StringKey("desc", g.Description)
|
||||
}
|
||||
|
||||
func (g auditGroup) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditJob struct {
|
||||
ID string
|
||||
Type string
|
||||
Priority int64
|
||||
StartAt int64
|
||||
}
|
||||
|
||||
// newAuditJob creates a simplified representation of Job for output to audit log.
|
||||
func newAuditJob(j *Job) auditJob {
|
||||
var job auditJob
|
||||
if j != nil {
|
||||
job.ID = j.Id
|
||||
job.Type = j.Type
|
||||
job.Priority = j.Priority
|
||||
job.StartAt = j.StartAt
|
||||
}
|
||||
return job
|
||||
}
|
||||
|
||||
func (j auditJob) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", j.ID)
|
||||
enc.StringKey("type", j.Type)
|
||||
enc.Int64Key("priority", j.Priority)
|
||||
enc.Int64Key("start_at", j.StartAt)
|
||||
}
|
||||
|
||||
func (j auditJob) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditOAuthApp struct {
|
||||
ID string
|
||||
CreatorID string
|
||||
Name string
|
||||
Description string
|
||||
IsTrusted bool
|
||||
}
|
||||
|
||||
// newAuditOAuthApp creates a simplified representation of OAuthApp for output to audit log.
|
||||
func newAuditOAuthApp(o *OAuthApp) auditOAuthApp {
|
||||
var oauth auditOAuthApp
|
||||
if o != nil {
|
||||
oauth.ID = o.Id
|
||||
oauth.CreatorID = o.CreatorId
|
||||
oauth.Name = o.Name
|
||||
oauth.Description = o.Description
|
||||
oauth.IsTrusted = o.IsTrusted
|
||||
}
|
||||
return oauth
|
||||
}
|
||||
|
||||
func (o auditOAuthApp) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", o.ID)
|
||||
enc.StringKey("creator_id", o.CreatorID)
|
||||
enc.StringKey("name", o.Name)
|
||||
enc.StringKey("desc", o.Description)
|
||||
enc.BoolKey("trusted", o.IsTrusted)
|
||||
}
|
||||
|
||||
func (o auditOAuthApp) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditPost struct {
|
||||
ID string
|
||||
ChannelID string
|
||||
Type string
|
||||
IsPinned bool
|
||||
}
|
||||
|
||||
// newAuditPost creates a simplified representation of Post for output to audit log.
|
||||
func newAuditPost(p *Post) auditPost {
|
||||
var post auditPost
|
||||
if p != nil {
|
||||
post.ID = p.Id
|
||||
post.ChannelID = p.ChannelId
|
||||
post.Type = p.Type
|
||||
post.IsPinned = p.IsPinned
|
||||
}
|
||||
return post
|
||||
}
|
||||
|
||||
func (p auditPost) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", p.ID)
|
||||
enc.StringKey("channel_id", p.ChannelID)
|
||||
enc.StringKey("type", p.Type)
|
||||
enc.BoolKey("pinned", p.IsPinned)
|
||||
}
|
||||
|
||||
func (p auditPost) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditRole struct {
|
||||
ID string
|
||||
Name string
|
||||
DisplayName string
|
||||
Permissions []string
|
||||
SchemeManaged bool
|
||||
BuiltIn bool
|
||||
}
|
||||
|
||||
// newAuditRole creates a simplified representation of Role for output to audit log.
|
||||
func newAuditRole(r *Role) auditRole {
|
||||
var role auditRole
|
||||
if r != nil {
|
||||
role.ID = r.Id
|
||||
role.Name = r.Name
|
||||
role.DisplayName = r.DisplayName
|
||||
role.Permissions = append(role.Permissions, r.Permissions...)
|
||||
role.SchemeManaged = r.SchemeManaged
|
||||
role.BuiltIn = r.BuiltIn
|
||||
}
|
||||
return role
|
||||
}
|
||||
|
||||
func (r auditRole) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", r.ID)
|
||||
enc.StringKey("name", r.Name)
|
||||
enc.StringKey("display", r.DisplayName)
|
||||
enc.SliceStringKey("perms", r.Permissions)
|
||||
enc.BoolKey("schemeManaged", r.SchemeManaged)
|
||||
enc.BoolKey("builtin", r.BuiltIn)
|
||||
}
|
||||
|
||||
func (r auditRole) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditScheme struct {
|
||||
ID string
|
||||
Name string
|
||||
DisplayName string
|
||||
Scope string
|
||||
}
|
||||
|
||||
// newAuditScheme creates a simplified representation of Scheme for output to audit log.
|
||||
func newAuditScheme(s *Scheme) auditScheme {
|
||||
var scheme auditScheme
|
||||
if s != nil {
|
||||
scheme.ID = s.Id
|
||||
scheme.Name = s.Name
|
||||
scheme.DisplayName = s.DisplayName
|
||||
scheme.Scope = s.Scope
|
||||
}
|
||||
return scheme
|
||||
}
|
||||
|
||||
func (s auditScheme) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", s.ID)
|
||||
enc.StringKey("name", s.Name)
|
||||
enc.StringKey("display", s.DisplayName)
|
||||
enc.StringKey("scope", s.Scope)
|
||||
}
|
||||
|
||||
func (s auditScheme) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditSchemeRoles struct {
|
||||
SchemeAdmin bool
|
||||
SchemeUser bool
|
||||
SchemeGuest bool
|
||||
}
|
||||
|
||||
// newAuditSchemeRoles creates a simplified representation of SchemeRoles for output to audit log.
|
||||
func newAuditSchemeRoles(s *SchemeRoles) auditSchemeRoles {
|
||||
var roles auditSchemeRoles
|
||||
if s != nil {
|
||||
roles.SchemeAdmin = s.SchemeAdmin
|
||||
roles.SchemeUser = s.SchemeUser
|
||||
roles.SchemeGuest = s.SchemeGuest
|
||||
}
|
||||
return roles
|
||||
}
|
||||
|
||||
func (s auditSchemeRoles) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.BoolKey("admin", s.SchemeAdmin)
|
||||
enc.BoolKey("user", s.SchemeUser)
|
||||
enc.BoolKey("guest", s.SchemeGuest)
|
||||
}
|
||||
|
||||
func (s auditSchemeRoles) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditSession struct {
|
||||
ID string
|
||||
UserId string
|
||||
DeviceId string
|
||||
}
|
||||
|
||||
// newAuditSession creates a simplified representation of Session for output to audit log.
|
||||
func newAuditSession(s *Session) auditSession {
|
||||
var session auditSession
|
||||
if s != nil {
|
||||
session.ID = s.Id
|
||||
session.UserId = s.UserId
|
||||
session.DeviceId = s.DeviceId
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
||||
func (s auditSession) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", s.ID)
|
||||
enc.StringKey("user_id", s.UserId)
|
||||
enc.StringKey("device_id", s.DeviceId)
|
||||
}
|
||||
|
||||
func (s auditSession) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditIncomingWebhook struct {
|
||||
ID string
|
||||
ChannelID string
|
||||
TeamId string
|
||||
DisplayName string
|
||||
Description string
|
||||
}
|
||||
|
||||
// newAuditIncomingWebhook creates a simplified representation of IncomingWebhook for output to audit log.
|
||||
func newAuditIncomingWebhook(h *IncomingWebhook) auditIncomingWebhook {
|
||||
var hook auditIncomingWebhook
|
||||
if h != nil {
|
||||
hook.ID = h.Id
|
||||
hook.ChannelID = h.ChannelId
|
||||
hook.TeamId = h.TeamId
|
||||
hook.DisplayName = h.DisplayName
|
||||
hook.Description = h.Description
|
||||
}
|
||||
return hook
|
||||
}
|
||||
|
||||
func (h auditIncomingWebhook) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", h.ID)
|
||||
enc.StringKey("channel_id", h.ChannelID)
|
||||
enc.StringKey("team_id", h.TeamId)
|
||||
enc.StringKey("display", h.DisplayName)
|
||||
enc.StringKey("desc", h.Description)
|
||||
}
|
||||
|
||||
func (h auditIncomingWebhook) IsNil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type auditOutgoingWebhook struct {
|
||||
ID string
|
||||
ChannelID string
|
||||
TeamID string
|
||||
TriggerWords StringArray
|
||||
TriggerWhen int
|
||||
DisplayName string
|
||||
Description string
|
||||
ContentType string
|
||||
Username string
|
||||
}
|
||||
|
||||
// newAuditOutgoingWebhook creates a simplified representation of OutgoingWebhook for output to audit log.
|
||||
func newAuditOutgoingWebhook(h *OutgoingWebhook) auditOutgoingWebhook {
|
||||
var hook auditOutgoingWebhook
|
||||
if h != nil {
|
||||
hook.ID = h.Id
|
||||
hook.ChannelID = h.ChannelId
|
||||
hook.TeamID = h.TeamId
|
||||
hook.TriggerWords = h.TriggerWords
|
||||
hook.TriggerWhen = h.TriggerWhen
|
||||
hook.DisplayName = h.DisplayName
|
||||
hook.Description = h.Description
|
||||
hook.ContentType = h.ContentType
|
||||
hook.Username = h.Username
|
||||
}
|
||||
return hook
|
||||
}
|
||||
|
||||
func (h auditOutgoingWebhook) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("id", h.ID)
|
||||
enc.StringKey("channel_id", h.ChannelID)
|
||||
enc.StringKey("team_id", h.TeamID)
|
||||
enc.SliceStringKey("trigger_words", h.TriggerWords)
|
||||
enc.IntKey("trigger_when", h.TriggerWhen)
|
||||
enc.StringKey("display", h.DisplayName)
|
||||
enc.StringKey("desc", h.Description)
|
||||
enc.StringKey("content_type", h.ContentType)
|
||||
enc.StringKey("username", h.Username)
|
||||
}
|
||||
|
||||
func (h auditOutgoingWebhook) IsNil() bool {
|
||||
return false
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -39,11 +39,11 @@ type AuthorizeRequest struct {
|
||||
// correctly.
|
||||
func (ad *AuthData) IsValid() *AppError {
|
||||
|
||||
if len(ad.ClientId) != 26 {
|
||||
if !IsValidId(ad.ClientId) {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.UserId) != 26 {
|
||||
if !IsValidId(ad.UserId) {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ func (ad *AuthData) IsValid() *AppError {
|
||||
// correctly.
|
||||
func (ar *AuthorizeRequest) IsValid() *AppError {
|
||||
|
||||
if len(ar.ClientId) != 26 {
|
||||
if !IsValidId(ar.ClientId) {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
233
vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
generated
vendored
Normal file
233
vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
generated
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
BOT_DISPLAY_NAME_MAX_RUNES = USER_FIRST_NAME_MAX_RUNES
|
||||
BOT_DESCRIPTION_MAX_RUNES = 1024
|
||||
BOT_CREATOR_ID_MAX_RUNES = KEY_VALUE_PLUGIN_ID_MAX_RUNES // UserId or PluginId
|
||||
)
|
||||
|
||||
// Bot is a special type of User meant for programmatic interactions.
|
||||
// Note that the primary key of a bot is the UserId, and matches the primary key of the
|
||||
// corresponding user.
|
||||
type Bot struct {
|
||||
UserId string `json:"user_id"`
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
OwnerId string `json:"owner_id"`
|
||||
LastIconUpdate int64 `json:"last_icon_update,omitempty"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
}
|
||||
|
||||
// BotPatch is a description of what fields to update on an existing bot.
|
||||
type BotPatch struct {
|
||||
Username *string `json:"username"`
|
||||
DisplayName *string `json:"display_name"`
|
||||
Description *string `json:"description"`
|
||||
}
|
||||
|
||||
// BotGetOptions acts as a filter on bulk bot fetching queries.
|
||||
type BotGetOptions struct {
|
||||
OwnerId string
|
||||
IncludeDeleted bool
|
||||
OnlyOrphaned bool
|
||||
Page int
|
||||
PerPage int
|
||||
}
|
||||
|
||||
// BotList is a list of bots.
|
||||
type BotList []*Bot
|
||||
|
||||
// Trace describes the minimum information required to identify a bot for the purpose of logging.
|
||||
func (b *Bot) Trace() map[string]interface{} {
|
||||
return map[string]interface{}{"user_id": b.UserId}
|
||||
}
|
||||
|
||||
// Clone returns a shallow copy of the bot.
|
||||
func (b *Bot) Clone() *Bot {
|
||||
copy := *b
|
||||
return ©
|
||||
}
|
||||
|
||||
// IsValid validates the bot and returns an error if it isn't configured correctly.
|
||||
func (b *Bot) IsValid() *AppError {
|
||||
if !IsValidId(b.UserId) {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.user_id.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidUsername(b.Username) {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.username.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(b.DisplayName) > BOT_DISPLAY_NAME_MAX_RUNES {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.user_id.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(b.Description) > BOT_DESCRIPTION_MAX_RUNES {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.description.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(b.OwnerId) == 0 || utf8.RuneCountInString(b.OwnerId) > BOT_CREATOR_ID_MAX_RUNES {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.creator_id.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if b.CreateAt == 0 {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.create_at.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if b.UpdateAt == 0 {
|
||||
return NewAppError("Bot.IsValid", "model.bot.is_valid.update_at.app_error", b.Trace(), "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreSave should be run before saving a new bot to the database.
|
||||
func (b *Bot) PreSave() {
|
||||
b.CreateAt = GetMillis()
|
||||
b.UpdateAt = b.CreateAt
|
||||
b.DeleteAt = 0
|
||||
}
|
||||
|
||||
// PreUpdate should be run before saving an updated bot to the database.
|
||||
func (b *Bot) PreUpdate() {
|
||||
b.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
// Etag generates an etag for caching.
|
||||
func (b *Bot) Etag() string {
|
||||
return Etag(b.UserId, b.UpdateAt)
|
||||
}
|
||||
|
||||
// ToJson serializes the bot to json.
|
||||
func (b *Bot) ToJson() []byte {
|
||||
data, _ := json.Marshal(b)
|
||||
return data
|
||||
}
|
||||
|
||||
// BotFromJson deserializes a bot from json.
|
||||
func BotFromJson(data io.Reader) *Bot {
|
||||
var bot *Bot
|
||||
json.NewDecoder(data).Decode(&bot)
|
||||
return bot
|
||||
}
|
||||
|
||||
// Patch modifies an existing bot with optional fields from the given patch.
|
||||
func (b *Bot) Patch(patch *BotPatch) {
|
||||
if patch.Username != nil {
|
||||
b.Username = *patch.Username
|
||||
}
|
||||
|
||||
if patch.DisplayName != nil {
|
||||
b.DisplayName = *patch.DisplayName
|
||||
}
|
||||
|
||||
if patch.Description != nil {
|
||||
b.Description = *patch.Description
|
||||
}
|
||||
}
|
||||
|
||||
// ToJson serializes the bot patch to json.
|
||||
func (b *BotPatch) ToJson() []byte {
|
||||
data, err := json.Marshal(b)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// BotPatchFromJson deserializes a bot patch from json.
|
||||
func BotPatchFromJson(data io.Reader) *BotPatch {
|
||||
decoder := json.NewDecoder(data)
|
||||
var botPatch BotPatch
|
||||
err := decoder.Decode(&botPatch)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &botPatch
|
||||
}
|
||||
|
||||
// UserFromBot returns a user model describing the bot fields stored in the User store.
|
||||
func UserFromBot(b *Bot) *User {
|
||||
return &User{
|
||||
Id: b.UserId,
|
||||
Username: b.Username,
|
||||
Email: NormalizeEmail(fmt.Sprintf("%s@localhost", b.Username)),
|
||||
FirstName: b.DisplayName,
|
||||
Roles: SYSTEM_USER_ROLE_ID,
|
||||
}
|
||||
}
|
||||
|
||||
// BotFromUser returns a bot model given a user model
|
||||
func BotFromUser(u *User) *Bot {
|
||||
return &Bot{
|
||||
OwnerId: u.Id,
|
||||
UserId: u.Id,
|
||||
Username: u.Username,
|
||||
DisplayName: u.GetDisplayName(SHOW_USERNAME),
|
||||
}
|
||||
}
|
||||
|
||||
// BotListFromJson deserializes a list of bots from json.
|
||||
func BotListFromJson(data io.Reader) BotList {
|
||||
var bots BotList
|
||||
json.NewDecoder(data).Decode(&bots)
|
||||
return bots
|
||||
}
|
||||
|
||||
// ToJson serializes a list of bots to json.
|
||||
func (l *BotList) ToJson() []byte {
|
||||
b, _ := json.Marshal(l)
|
||||
return b
|
||||
}
|
||||
|
||||
// Etag computes the etag for a list of bots.
|
||||
func (l *BotList) Etag() string {
|
||||
id := "0"
|
||||
var t int64 = 0
|
||||
var delta int64 = 0
|
||||
|
||||
for _, v := range *l {
|
||||
if v.UpdateAt > t {
|
||||
t = v.UpdateAt
|
||||
id = v.UserId
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Etag(id, t, delta, len(*l))
|
||||
}
|
||||
|
||||
// MakeBotNotFoundError creates the error returned when a bot does not exist, or when the user isn't allowed to query the bot.
|
||||
// The errors must the same in both cases to avoid leaking that a user is a bot.
|
||||
func MakeBotNotFoundError(userId string) *AppError {
|
||||
return NewAppError("SqlBotStore.Get", "store.sql_bot.get.missing.app_error", map[string]interface{}{"user_id": userId}, "", http.StatusNotFound)
|
||||
}
|
||||
|
||||
func IsBotDMChannel(channel *Channel, botUserID string) bool {
|
||||
if channel.Type != CHANNEL_DIRECT {
|
||||
return false
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(channel.Name, botUserID+"__") && !strings.HasSuffix(channel.Name, "__"+botUserID) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
288
vendor/github.com/mattermost/mattermost-server/v5/model/bot_default_image.go
generated
vendored
Normal file
288
vendor/github.com/mattermost/mattermost-server/v5/model/bot_default_image.go
generated
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
var BotDefaultImage = []byte{
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x7e,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0xec, 0xa6, 0x19, 0xa2, 0x00, 0x00, 0x00,
|
||||
0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61,
|
||||
0x05, 0x00, 0x00, 0x0c, 0xe3, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed,
|
||||
0x5d, 0x5b, 0x88, 0x15, 0xc9, 0x19, 0xae, 0xf1, 0xba, 0x5e, 0xc6, 0x4b,
|
||||
0xbc, 0xa0, 0x46, 0xd7, 0x2b, 0xce, 0x2a, 0xba, 0xca, 0x8a, 0xa3, 0x82,
|
||||
0x38, 0xa3, 0x46, 0x47, 0x5d, 0x59, 0xa3, 0x2f, 0x9b, 0x28, 0x6e, 0xc2,
|
||||
0xea, 0x83, 0x22, 0x04, 0x82, 0x78, 0x41, 0xf2, 0xb2, 0x04, 0xd4, 0x07,
|
||||
0x49, 0x22, 0xc4, 0x07, 0xcd, 0x53, 0x30, 0x26, 0x1a, 0xa2, 0x08, 0xee,
|
||||
0xaa, 0xa8, 0x71, 0xb2, 0x41, 0x11, 0xbc, 0xdf, 0xd0, 0x8d, 0x6e, 0x24,
|
||||
0x82, 0xe3, 0x65, 0x32, 0x9b, 0x19, 0x1d, 0x47, 0xd7, 0xeb, 0xc9, 0xf7,
|
||||
0xb5, 0xa7, 0x0f, 0xe7, 0x9c, 0xe9, 0x3e, 0xdd, 0xe7, 0x4c, 0x57, 0x77,
|
||||
0x75, 0x75, 0xfd, 0xf0, 0x9f, 0xee, 0xae, 0xaa, 0xae, 0xfa, 0xff, 0xef,
|
||||
0xfb, 0x4f, 0x9d, 0xee, 0xaa, 0xea, 0x3e, 0x65, 0x42, 0x4f, 0xe9, 0x0b,
|
||||
0xb7, 0x46, 0x43, 0x2b, 0xd2, 0xdb, 0x91, 0xd8, 0xf6, 0x84, 0x96, 0x67,
|
||||
0x69, 0xf7, 0xf4, 0x3e, 0x36, 0xa2, 0x19, 0xfa, 0x34, 0xbd, 0xe5, 0x3e,
|
||||
0xf5, 0x31, 0xf4, 0xdf, 0xd0, 0x5b, 0xd0, 0x7f, 0xa5, 0xb7, 0x0d, 0xd8,
|
||||
0x6a, 0x25, 0x65, 0x1a, 0x78, 0xd3, 0x1b, 0x3e, 0x54, 0x41, 0x67, 0x42,
|
||||
0x2b, 0xa1, 0x24, 0x9d, 0x69, 0x32, 0xa4, 0x11, 0x95, 0x32, 0x18, 0xce,
|
||||
0x42, 0x6b, 0xa1, 0x5f, 0x43, 0x99, 0x16, 0x5b, 0x89, 0x63, 0x00, 0x74,
|
||||
0x03, 0xda, 0xb3, 0xa0, 0x24, 0xbc, 0x1a, 0x3a, 0x01, 0xda, 0x0e, 0x1a,
|
||||
0x85, 0xbc, 0x45, 0xa3, 0x57, 0xa0, 0xff, 0x80, 0x32, 0x20, 0x4e, 0x42,
|
||||
0x5b, 0xa0, 0x46, 0x02, 0x46, 0xa0, 0x3d, 0xea, 0xab, 0x81, 0xee, 0x86,
|
||||
0xb2, 0xab, 0x4e, 0x29, 0xaa, 0xb4, 0x8d, 0x36, 0xd2, 0x56, 0xda, 0x6c,
|
||||
0xa4, 0x8d, 0x08, 0x7c, 0x84, 0xf3, 0x7f, 0x03, 0x7d, 0x00, 0x55, 0x95,
|
||||
0x74, 0x37, 0xbb, 0x68, 0x33, 0x6d, 0xa7, 0x0f, 0x46, 0x8a, 0x44, 0xe0,
|
||||
0x63, 0x94, 0x3f, 0x0d, 0x75, 0x03, 0x37, 0x6e, 0xe9, 0xf4, 0x85, 0x3e,
|
||||
0x19, 0x29, 0x80, 0x00, 0xbb, 0xcc, 0x9f, 0x40, 0xf9, 0x9b, 0x1a, 0x37,
|
||||
0x82, 0xfd, 0xda, 0x4b, 0xdf, 0xe8, 0xa3, 0xf9, 0x79, 0x00, 0x08, 0xb6,
|
||||
0xf0, 0x02, 0xee, 0x73, 0xe8, 0xb7, 0x50, 0xbf, 0x40, 0xc6, 0xbd, 0x1c,
|
||||
0x7d, 0xa5, 0xcf, 0x51, 0x5d, 0xbc, 0xa2, 0x69, 0x35, 0x84, 0xb7, 0x6d,
|
||||
0xe7, 0xa0, 0x71, 0x27, 0xb4, 0x54, 0xfb, 0xe9, 0x3b, 0x31, 0x48, 0x9c,
|
||||
0x70, 0xa0, 0x66, 0x17, 0x94, 0xb7, 0x51, 0xa5, 0x82, 0xa7, 0xcb, 0x79,
|
||||
0xc4, 0x80, 0x58, 0x10, 0x13, 0xed, 0x85, 0xe3, 0x0e, 0xab, 0xa0, 0xdf,
|
||||
0x41, 0x75, 0x21, 0x30, 0x28, 0x3f, 0x88, 0x09, 0xb1, 0x89, 0xe3, 0xd8,
|
||||
0x0c, 0xcc, 0xf6, 0x16, 0x46, 0xf8, 0x57, 0xd0, 0xa0, 0x00, 0xd3, 0xb5,
|
||||
0x1e, 0x62, 0xa4, 0x5d, 0x6f, 0x50, 0x0d, 0xa7, 0xea, 0x0c, 0xf9, 0xbe,
|
||||
0x83, 0x9f, 0x58, 0x11, 0xb3, 0xd8, 0x0b, 0x6f, 0x77, 0xbe, 0x80, 0xbe,
|
||||
0x81, 0xea, 0xfa, 0x8d, 0x95, 0xe5, 0x17, 0x31, 0x23, 0x76, 0xb1, 0xbd,
|
||||
0x65, 0xe4, 0x84, 0x4c, 0xad, 0x21, 0xbe, 0xcd, 0x81, 0x4f, 0x0c, 0x89,
|
||||
0x65, 0xac, 0xe4, 0x7d, 0x58, 0x7b, 0x03, 0x2a, 0xeb, 0xdb, 0x91, 0xb4,
|
||||
0x7a, 0x89, 0x25, 0x31, 0x8d, 0x85, 0x8c, 0x87, 0x95, 0xf7, 0xa0, 0x49,
|
||||
0x23, 0x49, 0xb6, 0xbf, 0xc4, 0x94, 0xd8, 0x2a, 0x2d, 0xd5, 0xb0, 0xae,
|
||||
0x09, 0x2a, 0x1b, 0x8c, 0xa4, 0xd6, 0x4f, 0x6c, 0x89, 0xb1, 0x92, 0xf2,
|
||||
0x09, 0xac, 0xfa, 0x1e, 0x9a, 0x54, 0x72, 0xc2, 0xf2, 0x9b, 0x18, 0x13,
|
||||
0x6b, 0xa5, 0xa4, 0x1a, 0xd6, 0x18, 0xf2, 0xc3, 0x0b, 0x7e, 0x62, 0x4d,
|
||||
0xcc, 0x95, 0x90, 0x49, 0xb0, 0xe2, 0x09, 0x34, 0xac, 0x6f, 0x80, 0x69,
|
||||
0xe7, 0x1d, 0xd6, 0xc4, 0x9c, 0xd8, 0x47, 0x2a, 0x5c, 0x78, 0x59, 0x0f,
|
||||
0x35, 0xa4, 0x44, 0x83, 0x01, 0xb1, 0x27, 0x07, 0x91, 0xc8, 0x60, 0xb4,
|
||||
0x7a, 0x17, 0x6a, 0xc8, 0x8f, 0x16, 0x03, 0x72, 0x40, 0x2e, 0x42, 0x95,
|
||||
0x4e, 0x68, 0x2d, 0xc9, 0xd3, 0xb8, 0xaa, 0x05, 0x3d, 0xb9, 0x20, 0x27,
|
||||
0x45, 0x4b, 0xa9, 0xc3, 0x8c, 0xdb, 0xd1, 0xd2, 0x8f, 0x8b, 0x6e, 0xcd,
|
||||
0x9c, 0x20, 0x0b, 0x81, 0x41, 0xa8, 0xf8, 0x07, 0xd0, 0xc3, 0xb2, 0x1a,
|
||||
0xc8, 0xae, 0xf7, 0x53, 0x1c, 0xa8, 0xf6, 0x0d, 0x30, 0xf6, 0xbc, 0xe3,
|
||||
0x84, 0xdc, 0x48, 0x15, 0x5e, 0x70, 0x98, 0x2b, 0x7e, 0x75, 0xbf, 0x00,
|
||||
0xe4, 0xa6, 0xa8, 0x8b, 0xc2, 0x62, 0xd6, 0xa4, 0xbd, 0x87, 0xca, 0xff,
|
||||
0x06, 0x2d, 0x87, 0x1a, 0x51, 0x13, 0x01, 0x72, 0x43, 0x8e, 0xc8, 0x95,
|
||||
0x2f, 0x29, 0x26, 0x00, 0x7e, 0x85, 0x1a, 0x95, 0x1f, 0x8b, 0xf6, 0xe3,
|
||||
0xf5, 0x80, 0x01, 0x03, 0xc4, 0xee, 0xdd, 0xbb, 0x45, 0x5d, 0x5d, 0x9d,
|
||||
0xa5, 0xdc, 0x67, 0x9a, 0x26, 0x42, 0x8e, 0xc8, 0x55, 0xa0, 0xf2, 0x01,
|
||||
0x6a, 0x7b, 0x01, 0x8d, 0xfd, 0x6f, 0x6d, 0xbf, 0x7e, 0xfd, 0x52, 0x0f,
|
||||
0x1f, 0x3e, 0x4c, 0xe5, 0x0b, 0xd3, 0x98, 0xa7, 0x83, 0x8f, 0x69, 0xae,
|
||||
0xc8, 0x59, 0x60, 0x52, 0x8b, 0x9a, 0xb4, 0x00, 0x67, 0xd7, 0xae, 0x5d,
|
||||
0xf9, 0xdc, 0x67, 0x8e, 0x99, 0xa7, 0x8b, 0x9f, 0xf0, 0x83, 0x9c, 0x05,
|
||||
0x22, 0x9f, 0xa1, 0x16, 0x6d, 0x80, 0xb9, 0x7d, 0xfb, 0x76, 0x86, 0xf0,
|
||||
0xfc, 0x1d, 0xe6, 0xe9, 0xe4, 0x2b, 0x7c, 0x21, 0x77, 0x05, 0xa5, 0xac,
|
||||
0x60, 0xee, 0xbb, 0x95, 0x28, 0x7c, 0x1c, 0xba, 0x9f, 0x47, 0xb9, 0xd8,
|
||||
0x64, 0xbf, 0x78, 0xf1, 0x42, 0x74, 0xea, 0xe4, 0x3c, 0x66, 0xf2, 0xf2,
|
||||
0xe5, 0x4b, 0xd1, 0xb9, 0x73, 0xe7, 0xd8, 0xf8, 0xe2, 0xc3, 0xd0, 0xff,
|
||||
0xa2, 0x4c, 0x05, 0xd4, 0xf5, 0x11, 0x76, 0xaf, 0x8b, 0xc0, 0x8d, 0x38,
|
||||
0x59, 0x1b, 0xf2, 0x7d, 0x00, 0xa6, 0x5b, 0x11, 0x72, 0x47, 0x0e, 0x5d,
|
||||
0xa5, 0x50, 0x0f, 0xc0, 0x91, 0x25, 0x8e, 0x33, 0xf3, 0x4d, 0x1a, 0xda,
|
||||
0x48, 0xc2, 0x7a, 0x00, 0xf2, 0xf6, 0x14, 0x3a, 0x14, 0xfa, 0x3f, 0x1e,
|
||||
0xe4, 0x4b, 0xa1, 0x1e, 0xe0, 0x97, 0x28, 0xac, 0x15, 0xf9, 0xf9, 0xce,
|
||||
0x27, 0xe4, 0x98, 0x1c, 0x92, 0x4b, 0x47, 0x71, 0xeb, 0x01, 0x7a, 0xa1,
|
||||
0xf4, 0x7f, 0xa0, 0x3d, 0x1d, 0xcf, 0x8a, 0x71, 0x62, 0x02, 0x7b, 0x00,
|
||||
0xb2, 0xf5, 0x18, 0x3a, 0x0c, 0xca, 0x25, 0x65, 0x39, 0xe2, 0xd6, 0x03,
|
||||
0xfc, 0x02, 0xa5, 0xb4, 0x23, 0x3f, 0xc7, 0xf3, 0x64, 0x1d, 0x90, 0x4b,
|
||||
0x72, 0xda, 0x4a, 0x9c, 0x7a, 0x80, 0x2e, 0x28, 0xc5, 0x15, 0xa8, 0xbc,
|
||||
0x06, 0xd0, 0x4e, 0x12, 0xda, 0x03, 0x90, 0x47, 0x5e, 0x03, 0x70, 0xdd,
|
||||
0xc0, 0x73, 0x1e, 0xd8, 0xe2, 0xd4, 0x03, 0x70, 0x9a, 0x57, 0x4b, 0xf2,
|
||||
0x6d, 0xa7, 0x13, 0xba, 0x25, 0xa7, 0xad, 0xa6, 0xf0, 0x3b, 0x38, 0x80,
|
||||
0xf1, 0x73, 0x87, 0xb4, 0xc8, 0x93, 0x78, 0x7f, 0x3e, 0x67, 0xce, 0x1c,
|
||||
0x31, 0x7d, 0xfa, 0x74, 0x31, 0x68, 0xd0, 0x20, 0xd1, 0xbb, 0x77, 0xef,
|
||||
0x92, 0x6c, 0xea, 0xd8, 0xb1, 0xa3, 0xeb, 0x79, 0xcc, 0x3b, 0x74, 0xe8,
|
||||
0x90, 0x6b, 0x7e, 0xa1, 0x8c, 0xc6, 0xc6, 0x46, 0x6b, 0x5e, 0xe1, 0xf4,
|
||||
0xe9, 0xd3, 0xe2, 0xf8, 0xf1, 0xe3, 0x82, 0x3d, 0x8d, 0x82, 0xf2, 0x33,
|
||||
0xd8, 0xf4, 0x97, 0x42, 0x76, 0xfd, 0x10, 0x99, 0x4a, 0x3d, 0xc7, 0xd7,
|
||||
0xa5, 0x4b, 0x97, 0xd4, 0xa6, 0x4d, 0x9b, 0x52, 0x4d, 0x4d, 0x4d, 0xf9,
|
||||
0x03, 0x77, 0xca, 0x1e, 0xd3, 0x56, 0xda, 0x4c, 0xdb, 0x81, 0xa7, 0x4a,
|
||||
0x4a, 0x6e, 0xc9, 0xb1, 0xab, 0x6c, 0x40, 0x8e, 0x32, 0x06, 0x8f, 0x18,
|
||||
0x31, 0x22, 0x75, 0xe3, 0xc6, 0x0d, 0x65, 0x89, 0xf6, 0x32, 0x8c, 0xb6,
|
||||
0xd3, 0x07, 0x95, 0x30, 0x85, 0x2d, 0xe4, 0xd8, 0x55, 0x94, 0x79, 0x9e,
|
||||
0x6f, 0xd4, 0xa8, 0x51, 0xa9, 0xfa, 0xfa, 0x7a, 0x2f, 0x8c, 0x95, 0xcf,
|
||||
0xa7, 0x0f, 0xf4, 0x05, 0x88, 0xab, 0xa2, 0xe4, 0xd8, 0x51, 0x3e, 0x44,
|
||||
0xaa, 0x12, 0x46, 0x76, 0xed, 0xda, 0x35, 0x75, 0xed, 0xda, 0x35, 0xe5,
|
||||
0xc9, 0xf5, 0x6b, 0x20, 0x7d, 0xa1, 0x4f, 0xaa, 0xe0, 0x0b, 0x3b, 0xc8,
|
||||
0xb5, 0x25, 0xd9, 0x77, 0x01, 0x3f, 0xb2, 0x13, 0xa3, 0xde, 0xae, 0x5d,
|
||||
0xbb, 0x56, 0x8c, 0x1b, 0x37, 0x2e, 0x6a, 0x33, 0x02, 0x6b, 0x9f, 0xbe,
|
||||
0xd0, 0x27, 0x85, 0xc4, 0x91, 0x6b, 0xbe, 0x9a, 0x24, 0xf2, 0x28, 0x2d,
|
||||
0x2f, 0x2f, 0x8f, 0xd5, 0x05, 0x9f, 0xdf, 0x5e, 0x80, 0x17, 0x86, 0xf4,
|
||||
0x4d, 0x05, 0x8c, 0x61, 0xc3, 0x97, 0x76, 0x30, 0xda, 0x3d, 0x00, 0x6f,
|
||||
0x07, 0x67, 0xd8, 0x89, 0x51, 0x6e, 0x6b, 0x6a, 0x6a, 0x44, 0xcf, 0x9e,
|
||||
0xfa, 0x0d, 0x42, 0xd2, 0x27, 0xfa, 0xa6, 0x88, 0x54, 0xc1, 0x0e, 0x6b,
|
||||
0x08, 0xc0, 0x0e, 0x80, 0x4a, 0x24, 0x28, 0x31, 0xf1, 0x33, 0x77, 0xee,
|
||||
0x5c, 0x45, 0x30, 0x0a, 0xde, 0x0c, 0x85, 0x7c, 0x23, 0xd7, 0xe4, 0x3c,
|
||||
0xf3, 0xa6, 0xca, 0xd9, 0xc1, 0xbb, 0x5b, 0x5a, 0x8d, 0x43, 0x87, 0x0e,
|
||||
0x2d, 0xed, 0xc4, 0x18, 0x9c, 0xa5, 0x98, 0x6f, 0x16, 0xe7, 0x76, 0x0f,
|
||||
0x30, 0x5d, 0x15, 0xfc, 0xfa, 0xf7, 0xef, 0xaf, 0x8a, 0x29, 0x81, 0xdb,
|
||||
0xa1, 0x98, 0x6f, 0x16, 0xe7, 0x76, 0x00, 0x8c, 0x09, 0xdc, 0xdb, 0x12,
|
||||
0x2b, 0xec, 0xd0, 0xc1, 0xfa, 0x69, 0x2a, 0xf1, 0x6c, 0xb5, 0x4f, 0x53,
|
||||
0xcc, 0x37, 0x8b, 0x73, 0x06, 0x40, 0x37, 0x28, 0x67, 0x89, 0x8c, 0x24,
|
||||
0x0b, 0x01, 0x72, 0xde, 0x8d, 0x01, 0xc0, 0x45, 0x83, 0x4e, 0xd3, 0xc2,
|
||||
0xc9, 0x82, 0x23, 0x79, 0xde, 0x92, 0xf3, 0x0a, 0x3b, 0x00, 0x92, 0xe7,
|
||||
0xbe, 0xf1, 0x98, 0x08, 0x58, 0x01, 0x10, 0xe8, 0x13, 0x24, 0x51, 0xe0,
|
||||
0x7a, 0xe2, 0xc4, 0x09, 0xb1, 0x62, 0xc5, 0x0a, 0x31, 0x71, 0xe2, 0x44,
|
||||
0x31, 0x73, 0xe6, 0x4c, 0xb1, 0x7e, 0xfd, 0x7a, 0x71, 0xff, 0xfe, 0xfd,
|
||||
0xc0, 0x4c, 0x39, 0x7b, 0xf6, 0xac, 0x58, 0xb9, 0x72, 0xa5, 0x98, 0x30,
|
||||
0x61, 0x82, 0x98, 0x3f, 0x7f, 0xbe, 0xd8, 0xb6, 0x6d, 0x9b, 0x78, 0xf5,
|
||||
0xea, 0x55, 0x60, 0xf5, 0x47, 0x58, 0x91, 0xc5, 0xfd, 0x9f, 0x61, 0x40,
|
||||
0x28, 0x23, 0x54, 0x3d, 0x7a, 0xf4, 0xb0, 0x66, 0xc7, 0x38, 0x43, 0x46,
|
||||
0x1d, 0x3c, 0x78, 0x70, 0xab, 0x76, 0x8b, 0x99, 0x03, 0x78, 0xfb, 0xf6,
|
||||
0x6d, 0x6a, 0xf5, 0xea, 0xd5, 0xad, 0xea, 0xa0, 0x3f, 0x58, 0x2f, 0x90,
|
||||
0x3a, 0x78, 0xf0, 0xa0, 0xdf, 0x81, 0x3a, 0xd7, 0x72, 0x3b, 0x76, 0xec,
|
||||
0x48, 0x61, 0x9d, 0x40, 0xab, 0x36, 0x2a, 0x2b, 0x2b, 0x8b, 0x9e, 0xac,
|
||||
0xa2, 0x6f, 0xf9, 0x58, 0x13, 0x03, 0x1b, 0x0f, 0x6e, 0x89, 0x51, 0x7e,
|
||||
0x19, 0x89, 0xc7, 0xe4, 0x5e, 0x1c, 0x91, 0xd8, 0x80, 0xe5, 0xcc, 0xe4,
|
||||
0xc9, 0x93, 0x53, 0x17, 0x2e, 0x5c, 0x48, 0x91, 0xb0, 0x6c, 0x71, 0x02,
|
||||
0xa4, 0x98, 0x00, 0xd8, 0xbe, 0x7d, 0x7b, 0x41, 0xb0, 0xba, 0x77, 0xef,
|
||||
0x9e, 0xba, 0x73, 0xe7, 0x4e, 0x76, 0x93, 0x45, 0xed, 0x5f, 0xb9, 0x72,
|
||||
0x25, 0x85, 0x2b, 0x77, 0xd7, 0x36, 0x96, 0x2d, 0x5b, 0x56, 0x54, 0x7d,
|
||||
0x7e, 0xfc, 0x25, 0x46, 0xc4, 0x8a, 0x98, 0xc9, 0xe6, 0x25, 0xcd, 0xbd,
|
||||
0x38, 0x25, 0xb3, 0xa1, 0xb1, 0x63, 0xc7, 0xa6, 0xb0, 0x3a, 0xc6, 0x11,
|
||||
0x28, 0x3f, 0x80, 0x38, 0x9e, 0x88, 0xc4, 0xe7, 0xcf, 0x9f, 0xfb, 0x9a,
|
||||
0x61, 0x5b, 0xba, 0x74, 0xa9, 0x5b, 0x15, 0x9e, 0xe9, 0x4b, 0x96, 0x2c,
|
||||
0xf1, 0x24, 0xe1, 0xe6, 0xcd, 0x9b, 0x9e, 0xf5, 0xd8, 0x05, 0x8a, 0xf1,
|
||||
0x97, 0x98, 0x11, 0x3b, 0x99, 0xdc, 0xa0, 0xee, 0x53, 0xbc, 0x08, 0xec,
|
||||
0x01, 0x95, 0x26, 0x5b, 0xb6, 0x6c, 0x71, 0x7d, 0x14, 0xab, 0x2d, 0x8d,
|
||||
0xe2, 0xdb, 0x29, 0x9e, 0x3d, 0x7b, 0xe6, 0x59, 0xc5, 0x99, 0x33, 0x67,
|
||||
0x3c, 0xcb, 0xb8, 0x15, 0x38, 0x77, 0x8e, 0xaf, 0xde, 0x29, 0x2c, 0xe7,
|
||||
0xcf, 0x9f, 0x2f, 0x5c, 0xa0, 0xc4, 0x5c, 0x3e, 0xbe, 0x46, 0xec, 0x24,
|
||||
0x4b, 0x0f, 0x06, 0x80, 0xd4, 0x17, 0x3e, 0x4c, 0x9d, 0x3a, 0x55, 0x8a,
|
||||
0x0f, 0x77, 0xef, 0xde, 0xf5, 0x55, 0xef, 0xbd, 0x7b, 0xf7, 0x04, 0xba,
|
||||
0x55, 0x5f, 0x65, 0xb3, 0x0b, 0xf1, 0x9c, 0x07, 0x0f, 0x1e, 0x64, 0x27,
|
||||
0x39, 0xee, 0xb3, 0x7e, 0x59, 0x22, 0x0b, 0xbb, 0x2c, 0x7b, 0xcb, 0xa5,
|
||||
0x07, 0x80, 0xac, 0xe1, 0xcf, 0xf1, 0xe3, 0xfd, 0xbd, 0xab, 0x02, 0xdd,
|
||||
0xa8, 0x68, 0xd7, 0x8e, 0x6e, 0x16, 0x27, 0x3c, 0x67, 0xf4, 0xe8, 0xd1,
|
||||
0x9e, 0x27, 0x8d, 0x19, 0x23, 0x6f, 0x10, 0x55, 0x16, 0x76, 0x59, 0x4e,
|
||||
0xc9, 0x0f, 0x80, 0xac, 0xc6, 0x02, 0xdd, 0xad, 0xa8, 0xa8, 0x10, 0xc3,
|
||||
0x87, 0x0f, 0xf7, 0xac, 0x73, 0xde, 0xbc, 0x79, 0x9e, 0x65, 0xdc, 0x0a,
|
||||
0xcc, 0x9a, 0x35, 0xcb, 0x2d, 0xcb, 0x4a, 0xc7, 0xa2, 0x4f, 0x11, 0xc2,
|
||||
0xb7, 0xb4, 0xa0, 0x0d, 0x6d, 0xcc, 0xb4, 0x7a, 0x7f, 0xa9, 0x6f, 0xfe,
|
||||
0xb0, 0x2f, 0x80, 0x9c, 0xb6, 0xc5, 0x5c, 0x14, 0x39, 0x9d, 0x7f, 0xf2,
|
||||
0xe4, 0xc9, 0x54, 0x59, 0x59, 0x99, 0xeb, 0x85, 0x12, 0xd7, 0xe2, 0xb5,
|
||||
0xb4, 0xb4, 0x38, 0x9d, 0xea, 0x2b, 0xad, 0xa1, 0xa1, 0x21, 0xd5, 0xb7,
|
||||
0x6f, 0x5f, 0xd7, 0xfa, 0x37, 0x6f, 0xde, 0xec, 0xab, 0x1e, 0xbb, 0x50,
|
||||
0x29, 0xfe, 0x82, 0x60, 0xd7, 0xf6, 0x03, 0xc8, 0x7b, 0xc1, 0xbe, 0xb1,
|
||||
0xb9, 0x8d, 0x51, 0x14, 0xd9, 0xe9, 0x1c, 0xf4, 0xd9, 0xbf, 0x7f, 0xbf,
|
||||
0xc0, 0xab, 0x5d, 0x5a, 0xd9, 0x30, 0x63, 0xc6, 0x0c, 0x71, 0xec, 0xd8,
|
||||
0x31, 0x81, 0xb5, 0x78, 0xad, 0xf2, 0xfc, 0x26, 0xf4, 0xe9, 0xd3, 0x47,
|
||||
0x1c, 0x3d, 0x7a, 0x54, 0x8c, 0x1c, 0x39, 0x32, 0xe7, 0x14, 0x04, 0x9d,
|
||||
0xd8, 0xb0, 0x61, 0x83, 0x58, 0xb7, 0x6e, 0x5d, 0x4e, 0x7a, 0x0c, 0x0f,
|
||||
0x9a, 0x39, 0xf5, 0xc6, 0x00, 0xe8, 0x13, 0x43, 0xe3, 0x2d, 0x93, 0x17,
|
||||
0x2f, 0x5e, 0x2c, 0xaa, 0xaa, 0xaa, 0xac, 0x87, 0x31, 0x2e, 0x5e, 0xbc,
|
||||
0x28, 0x7a, 0xf5, 0xea, 0x25, 0x70, 0x0f, 0x2d, 0x66, 0xcf, 0x9e, 0x2d,
|
||||
0x48, 0x54, 0x5b, 0x65, 0xd2, 0xa4, 0x49, 0xe2, 0xd2, 0xa5, 0x4b, 0xe2,
|
||||
0xc8, 0x91, 0x23, 0x82, 0x57, 0xfc, 0x03, 0x07, 0x0e, 0x14, 0xfc, 0x69,
|
||||
0xe0, 0xa8, 0xa0, 0x06, 0x62, 0x7d, 0xf9, 0xaf, 0xc2, 0x11, 0x69, 0xdd,
|
||||
0x8c, 0xdd, 0xfd, 0x39, 0x6d, 0x4b, 0xe9, 0x12, 0x9d, 0xea, 0x89, 0x4b,
|
||||
0x5a, 0x29, 0xfe, 0xca, 0xe4, 0x06, 0x75, 0x5f, 0xe5, 0x4f, 0xc0, 0x13,
|
||||
0xa8, 0x91, 0x64, 0x22, 0xf0, 0x24, 0xd6, 0xd7, 0x00, 0xc9, 0xe4, 0x2c,
|
||||
0x50, 0xaf, 0x9b, 0x19, 0x00, 0x8d, 0x81, 0x56, 0x69, 0x2a, 0x8b, 0x13,
|
||||
0x02, 0x8d, 0x0c, 0x80, 0xdb, 0x71, 0xb2, 0xd8, 0xd8, 0x1a, 0x28, 0x02,
|
||||
0xb7, 0x19, 0x00, 0xdf, 0x04, 0x5a, 0xa5, 0xa9, 0x2c, 0x4e, 0x08, 0x7c,
|
||||
0xc3, 0x00, 0xe0, 0x7b, 0x00, 0x8d, 0x24, 0x13, 0x81, 0x4c, 0x00, 0xf0,
|
||||
0x36, 0xd0, 0x48, 0xb2, 0x10, 0x20, 0xe7, 0xb7, 0xd8, 0x03, 0xb4, 0x40,
|
||||
0xe5, 0x4d, 0x69, 0x25, 0x0b, 0xd4, 0x38, 0x79, 0x4b, 0xce, 0x5b, 0x18,
|
||||
0x00, 0x94, 0x9b, 0xef, 0x36, 0xe6, 0x33, 0x41, 0x08, 0x58, 0x9c, 0x73,
|
||||
0x28, 0x98, 0x72, 0x0a, 0x3a, 0xd7, 0xda, 0x8b, 0xd9, 0xc7, 0x9b, 0x37,
|
||||
0x6f, 0x04, 0x46, 0x02, 0x5d, 0xad, 0xce, 0x7f, 0x18, 0x83, 0xf3, 0xfc,
|
||||
0x85, 0xd6, 0x07, 0xb4, 0x6f, 0xdf, 0x3e, 0x67, 0x08, 0xf9, 0xf5, 0xeb,
|
||||
0xd7, 0xae, 0x75, 0x73, 0xa8, 0x99, 0xe5, 0x63, 0x2a, 0xe4, 0x3c, 0xf3,
|
||||
0x6c, 0xe0, 0xdf, 0x65, 0x39, 0xd1, 0xdc, 0x2c, 0x77, 0xae, 0x69, 0xf9,
|
||||
0xf2, 0xe5, 0x82, 0x2f, 0x77, 0x72, 0xd3, 0xeb, 0xd7, 0xaf, 0xe7, 0xb8,
|
||||
0xb6, 0x75, 0xeb, 0x56, 0xd7, 0xb2, 0xac, 0x63, 0xdf, 0xbe, 0x7d, 0x99,
|
||||
0xf2, 0x3c, 0xd7, 0xad, 0x5e, 0xa6, 0xb3, 0x6d, 0x99, 0x22, 0x19, 0x3b,
|
||||
0x8b, 0x73, 0xfb, 0x27, 0xe0, 0x2c, 0x1c, 0x91, 0xc2, 0xd4, 0xe5, 0xcb,
|
||||
0x97, 0x65, 0x62, 0xa4, 0x75, 0xdd, 0x12, 0xb1, 0x23, 0xd7, 0xe4, 0x3c,
|
||||
0xd3, 0x03, 0xb0, 0x9f, 0xfb, 0x27, 0x13, 0x82, 0x16, 0xcc, 0x99, 0x07,
|
||||
0x5d, 0xa5, 0xd4, 0xfa, 0x0a, 0xfd, 0x9c, 0x48, 0x6d, 0xd8, 0xa1, 0x72,
|
||||
0x89, 0xd8, 0x91, 0x6b, 0xeb, 0xb7, 0xcd, 0xee, 0x01, 0xd8, 0xbc, 0x94,
|
||||
0x9f, 0x01, 0xce, 0xa7, 0xaf, 0x5a, 0xb5, 0xca, 0xd7, 0x02, 0x4e, 0x07,
|
||||
0x0c, 0x42, 0x4f, 0x0a, 0x62, 0x0a, 0xb9, 0xad, 0x46, 0x73, 0xb1, 0x2b,
|
||||
0x31, 0x23, 0x76, 0x92, 0x24, 0xc3, 0xb5, 0x7d, 0x11, 0xc8, 0x76, 0x32,
|
||||
0x89, 0x41, 0x37, 0xba, 0x73, 0xe7, 0x4e, 0xb1, 0x77, 0xef, 0x5e, 0x6b,
|
||||
0x9e, 0x3e, 0x7b, 0x9d, 0xdb, 0xe3, 0xc7, 0x7c, 0x87, 0x71, 0xdb, 0x64,
|
||||
0xcd, 0x9a, 0x35, 0x62, 0xe1, 0xc2, 0x85, 0xae, 0x95, 0x0c, 0x19, 0x32,
|
||||
0x24, 0x27, 0x6f, 0xd1, 0xa2, 0x45, 0x62, 0xd8, 0xb0, 0x61, 0x39, 0x69,
|
||||
0xd9, 0x07, 0xd3, 0xa6, 0x4d, 0xcb, 0x1c, 0xf2, 0xdc, 0x3d, 0x7b, 0xf6,
|
||||
0x64, 0x8e, 0xf3, 0x77, 0x82, 0x78, 0xde, 0x7f, 0xe3, 0xc6, 0x8d, 0x39,
|
||||
0x6f, 0x44, 0xc1, 0x5b, 0xc5, 0x04, 0x57, 0x23, 0x07, 0x81, 0x4d, 0xbe,
|
||||
0xbd, 0x59, 0xc7, 0xae, 0x5c, 0xdf, 0x40, 0x21, 0x69, 0x6b, 0x03, 0xfc,
|
||||
0xd4, 0xcd, 0x39, 0x73, 0x5d, 0xc5, 0x69, 0x3d, 0x80, 0x1f, 0x4c, 0x02,
|
||||
0x2e, 0x43, 0x8e, 0x33, 0x92, 0xfd, 0x13, 0xc0, 0xc4, 0x3f, 0x66, 0x72,
|
||||
0xcc, 0x8e, 0xae, 0x08, 0xe4, 0x70, 0x9c, 0x1f, 0x00, 0x7f, 0x82, 0xd7,
|
||||
0xc5, 0x2f, 0xa2, 0xd7, 0x15, 0x2a, 0xfd, 0xfc, 0x22, 0xb7, 0xe4, 0x38,
|
||||
0x23, 0xf9, 0x01, 0x50, 0x87, 0x9c, 0xe3, 0x99, 0xdc, 0x08, 0x76, 0x0a,
|
||||
0x0d, 0xbc, 0x44, 0x60, 0x4e, 0xa0, 0x4d, 0x2a, 0xf0, 0x44, 0x31, 0xb9,
|
||||
0x25, 0xc7, 0x19, 0xc9, 0x0f, 0x00, 0x66, 0xe4, 0x74, 0x11, 0x99, 0x92,
|
||||
0x21, 0xed, 0xe0, 0x0f, 0x1c, 0x43, 0x6a, 0x29, 0xfc, 0x66, 0x1e, 0x3d,
|
||||
0x7a, 0x14, 0x7e, 0xa3, 0xb9, 0x2d, 0xb6, 0xe2, 0xd6, 0x29, 0x00, 0x0e,
|
||||
0xe2, 0x1c, 0xfe, 0xb9, 0x40, 0x24, 0x22, 0x71, 0xf0, 0x23, 0x12, 0x7f,
|
||||
0xb2, 0x1b, 0x8d, 0xd8, 0x37, 0x72, 0x4a, 0x6e, 0x73, 0xc4, 0x29, 0x00,
|
||||
0x9e, 0xa3, 0xc4, 0xef, 0x72, 0x4a, 0x85, 0x78, 0x70, 0xe0, 0xc0, 0x81,
|
||||
0x10, 0x5b, 0x0b, 0xb7, 0xa9, 0x88, 0x7d, 0x23, 0xa7, 0xe4, 0xd6, 0x97,
|
||||
0xf4, 0x42, 0xa9, 0x26, 0x68, 0x24, 0xb7, 0x84, 0x18, 0x00, 0xd1, 0xee,
|
||||
0x4e, 0x90, 0x3e, 0x45, 0x85, 0x67, 0x9a, 0x4b, 0x72, 0x5a, 0x94, 0xfc,
|
||||
0x1a, 0xa5, 0x23, 0x31, 0x1a, 0x03, 0x35, 0x29, 0x3e, 0x96, 0xa5, 0x8b,
|
||||
0xd0, 0x17, 0xfa, 0x14, 0x15, 0x9e, 0x68, 0x97, 0x5c, 0x16, 0x2d, 0xfc,
|
||||
0x8f, 0x19, 0x4e, 0x1a, 0x44, 0x62, 0xf8, 0x94, 0x29, 0x53, 0x8a, 0x7e,
|
||||
0x05, 0x8b, 0x8a, 0x01, 0xc3, 0xff, 0x0b, 0xa0, 0x2f, 0x51, 0xe1, 0x98,
|
||||
0xe6, 0x90, 0x5c, 0x96, 0x24, 0x5b, 0x71, 0x56, 0x64, 0xc6, 0x63, 0x28,
|
||||
0x36, 0x85, 0x21, 0xe4, 0x56, 0xaf, 0x96, 0x51, 0x91, 0xe8, 0x7c, 0x9b,
|
||||
0xb0, 0xe6, 0xc0, 0xb2, 0x9d, 0x3e, 0x44, 0x89, 0x21, 0xda, 0x26, 0x87,
|
||||
0xae, 0x52, 0xe6, 0x9a, 0xf3, 0x2e, 0x83, 0xff, 0xcc, 0xc4, 0x45, 0xa3,
|
||||
0xad, 0x9f, 0xbe, 0xf4, 0x38, 0x31, 0xc8, 0x6c, 0xbc, 0x48, 0x49, 0x2c,
|
||||
0x58, 0xb0, 0x40, 0xe0, 0x25, 0x4a, 0x25, 0xff, 0x59, 0x54, 0x90, 0xf6,
|
||||
0x14, 0xaa, 0x8b, 0x7f, 0x1e, 0x85, 0xf7, 0x12, 0x89, 0xc3, 0x87, 0x0f,
|
||||
0x0b, 0x99, 0x2f, 0x8f, 0x28, 0x64, 0x43, 0x56, 0x9e, 0xe7, 0x9f, 0x47,
|
||||
0x67, 0x95, 0x75, 0xdd, 0xfd, 0x0c, 0x39, 0x51, 0x47, 0xb1, 0x69, 0xbf,
|
||||
0x34, 0x0e, 0x96, 0xbb, 0xb2, 0x5a, 0x64, 0x46, 0xad, 0x09, 0x82, 0xd8,
|
||||
0x7d, 0x09, 0xc8, 0x99, 0xa7, 0x78, 0xfd, 0x04, 0xd8, 0x15, 0x7c, 0x80,
|
||||
0x9d, 0x2b, 0xd0, 0x4e, 0x76, 0x82, 0xd9, 0x2a, 0x8d, 0xc0, 0x4b, 0x58,
|
||||
0xc7, 0xe7, 0xd7, 0x3d, 0x1f, 0xfa, 0xf1, 0xbb, 0xa2, 0xb1, 0x01, 0x95,
|
||||
0xbd, 0x07, 0x9d, 0x01, 0x35, 0xa2, 0x3e, 0x02, 0xbc, 0xf0, 0xfb, 0x6b,
|
||||
0xd0, 0x66, 0x32, 0x00, 0xa4, 0xbe, 0x4b, 0x00, 0xf5, 0x9b, 0xdf, 0xfa,
|
||||
0xb6, 0x63, 0x40, 0x8e, 0xc8, 0x95, 0x14, 0xe1, 0x6b, 0xb3, 0x9e, 0x40,
|
||||
0x0d, 0x51, 0x6a, 0x62, 0x40, 0x6e, 0xc8, 0x91, 0x54, 0xf9, 0x14, 0xb5,
|
||||
0x9b, 0x00, 0x50, 0x13, 0x03, 0x72, 0x13, 0x8a, 0xfc, 0x1e, 0xad, 0x98,
|
||||
0x20, 0x50, 0x0b, 0x03, 0x72, 0x12, 0x9a, 0xf0, 0x6e, 0x80, 0xef, 0x51,
|
||||
0x35, 0x41, 0xa0, 0x06, 0x06, 0xe4, 0x22, 0xf4, 0x3b, 0x34, 0xfe, 0xe5,
|
||||
0xc8, 0x5d, 0x13, 0x04, 0x91, 0x7f, 0x09, 0xc8, 0x01, 0xb9, 0x88, 0x44,
|
||||
0x78, 0xc1, 0x51, 0x0f, 0x35, 0x3d, 0x41, 0x34, 0x18, 0x10, 0x7b, 0xe9,
|
||||
0x17, 0x7d, 0x5e, 0x91, 0x35, 0x09, 0x05, 0xcc, 0x9d, 0x41, 0xf8, 0x01,
|
||||
0x40, 0xcc, 0x89, 0xbd, 0x12, 0x52, 0x0d, 0x2b, 0xbe, 0x87, 0x9a, 0x9e,
|
||||
0x20, 0x1c, 0x0c, 0x88, 0x35, 0x31, 0x57, 0x4a, 0x3e, 0x81, 0x35, 0x26,
|
||||
0x08, 0xe4, 0x07, 0x00, 0x31, 0x26, 0xd6, 0x4a, 0x4a, 0x35, 0xac, 0x8a,
|
||||
0x6c, 0x29, 0x19, 0xda, 0xd6, 0xbd, 0x07, 0x22, 0xb6, 0xc4, 0x58, 0x69,
|
||||
0xe1, 0x8b, 0xfc, 0xef, 0x41, 0x75, 0x27, 0x23, 0x6c, 0xff, 0x88, 0xa9,
|
||||
0xbf, 0x3f, 0x49, 0x50, 0x20, 0x3c, 0xde, 0x87, 0x0d, 0x91, 0x3f, 0x67,
|
||||
0xa8, 0x51, 0x10, 0x12, 0x4b, 0x62, 0x1a, 0x2b, 0xe1, 0x6a, 0xa2, 0x5a,
|
||||
0x68, 0xd8, 0xdf, 0x14, 0xdd, 0xda, 0x23, 0x86, 0xc4, 0x32, 0x96, 0xc2,
|
||||
0xe9, 0xe6, 0x2f, 0xa0, 0x6f, 0xa0, 0xba, 0x11, 0x23, 0xdb, 0x1f, 0x62,
|
||||
0x46, 0xec, 0xfc, 0x4e, 0xd9, 0xa3, 0xa8, 0xba, 0x52, 0x0d, 0xd3, 0xf8,
|
||||
0x4c, 0x9a, 0x6c, 0xd0, 0x74, 0xa9, 0x9f, 0x58, 0x11, 0x33, 0xad, 0xa4,
|
||||
0x2f, 0xbc, 0xf9, 0x0a, 0xaa, 0x0b, 0x49, 0xb2, 0xfc, 0x20, 0x46, 0xc4,
|
||||
0x4a, 0x4b, 0x29, 0x83, 0x57, 0xab, 0xa0, 0xdf, 0x41, 0x65, 0x01, 0x18,
|
||||
0xd7, 0x7a, 0x89, 0x09, 0xb1, 0x21, 0x46, 0xda, 0x0b, 0x23, 0xfc, 0x0f,
|
||||
0xd0, 0xb7, 0xd0, 0xb8, 0x12, 0x16, 0x94, 0xdd, 0xc4, 0x80, 0x58, 0x68,
|
||||
0xfb, 0xad, 0x87, 0x6f, 0xae, 0x52, 0x89, 0x9c, 0x24, 0x4f, 0x2b, 0xd3,
|
||||
0x77, 0x62, 0x90, 0x68, 0xe1, 0x13, 0xca, 0x9f, 0x43, 0xbf, 0x85, 0x06,
|
||||
0xf5, 0xad, 0x52, 0xbd, 0x1e, 0xfa, 0x4a, 0x9f, 0xe9, 0xbb, 0x91, 0x34,
|
||||
0x02, 0xbc, 0xdd, 0xf9, 0x29, 0x94, 0xcb, 0xcf, 0x55, 0x27, 0xb0, 0x54,
|
||||
0xfb, 0xe8, 0x1b, 0x7d, 0xd4, 0xe2, 0xd6, 0x0e, 0x7e, 0x48, 0x93, 0x8f,
|
||||
0x51, 0xf3, 0x69, 0x68, 0xa9, 0x40, 0xab, 0x76, 0x1e, 0x7d, 0xa1, 0x4f,
|
||||
0x46, 0x8a, 0x44, 0xe0, 0x23, 0x94, 0xff, 0x2d, 0x94, 0xff, 0xe2, 0xac,
|
||||
0x1a, 0xa9, 0x5e, 0xf6, 0xd0, 0x66, 0xda, 0x4e, 0x1f, 0x8c, 0xb4, 0x11,
|
||||
0x01, 0x76, 0x99, 0x35, 0xd0, 0xdd, 0xd0, 0xa7, 0x50, 0x2f, 0xf0, 0xa3,
|
||||
0xca, 0xa7, 0x6d, 0xb4, 0x91, 0xb6, 0xc6, 0xa2, 0x9b, 0x8f, 0xe3, 0x3d,
|
||||
0x67, 0x37, 0x80, 0x3b, 0x0b, 0x3a, 0x33, 0xad, 0x1f, 0x62, 0x1b, 0xd5,
|
||||
0xc5, 0x14, 0x6f, 0xe1, 0xae, 0x42, 0x6b, 0xd3, 0x7a, 0x12, 0x5b, 0xfe,
|
||||
0x01, 0x47, 0x6c, 0x24, 0x8e, 0x01, 0x90, 0x0f, 0x2e, 0x27, 0x4a, 0xaa,
|
||||
0xa0, 0x0c, 0x08, 0xde, 0x52, 0x55, 0x40, 0x65, 0x4d, 0x9e, 0xf0, 0x2f,
|
||||
0xf6, 0xf8, 0xb8, 0x3c, 0xdf, 0xb4, 0x4d, 0xd2, 0xbf, 0x86, 0x32, 0x2d,
|
||||
0xb6, 0xa2, 0x43, 0x00, 0x38, 0x81, 0xcf, 0x41, 0x15, 0x06, 0x02, 0x17,
|
||||
0x4c, 0x72, 0x3b, 0x02, 0xca, 0x77, 0xe4, 0x74, 0x87, 0x96, 0xa7, 0xd5,
|
||||
0xde, 0xc7, 0xa1, 0xf5, 0x26, 0x14, 0x76, 0xdf, 0x7c, 0x23, 0x0a, 0x95,
|
||||
0xfb, 0x5c, 0x7c, 0x71, 0x07, 0x4a, 0xc2, 0x6f, 0xa5, 0xb7, 0x7c, 0x46,
|
||||
0x52, 0x2b, 0xf9, 0x3f, 0x92, 0xc9, 0x00, 0xb6, 0x61, 0xee, 0xab, 0xc9,
|
||||
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,9 +1,9 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import "github.com/mattermost/mattermost-server/mlog"
|
||||
import "github.com/mattermost/mattermost-server/v5/mlog"
|
||||
|
||||
type BundleInfo struct {
|
||||
Path string
|
364
vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
generated
vendored
Normal file
364
vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
generated
vendored
Normal file
@ -0,0 +1,364 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
CHANNEL_OPEN = "O"
|
||||
CHANNEL_PRIVATE = "P"
|
||||
CHANNEL_DIRECT = "D"
|
||||
CHANNEL_GROUP = "G"
|
||||
CHANNEL_GROUP_MAX_USERS = 8
|
||||
CHANNEL_GROUP_MIN_USERS = 3
|
||||
DEFAULT_CHANNEL = "town-square"
|
||||
CHANNEL_DISPLAY_NAME_MAX_RUNES = 64
|
||||
CHANNEL_NAME_MIN_LENGTH = 2
|
||||
CHANNEL_NAME_MAX_LENGTH = 64
|
||||
CHANNEL_HEADER_MAX_RUNES = 1024
|
||||
CHANNEL_PURPOSE_MAX_RUNES = 250
|
||||
CHANNEL_CACHE_SIZE = 25000
|
||||
|
||||
CHANNEL_SORT_BY_USERNAME = "username"
|
||||
CHANNEL_SORT_BY_STATUS = "status"
|
||||
)
|
||||
|
||||
type Channel struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
TeamId string `json:"team_id"`
|
||||
Type string `json:"type"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Header string `json:"header"`
|
||||
Purpose string `json:"purpose"`
|
||||
LastPostAt int64 `json:"last_post_at"`
|
||||
TotalMsgCount int64 `json:"total_msg_count"`
|
||||
ExtraUpdateAt int64 `json:"extra_update_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
SchemeId *string `json:"scheme_id"`
|
||||
Props map[string]interface{} `json:"props" db:"-"`
|
||||
GroupConstrained *bool `json:"group_constrained"`
|
||||
}
|
||||
|
||||
type ChannelWithTeamData struct {
|
||||
Channel
|
||||
TeamDisplayName string `json:"team_display_name"`
|
||||
TeamName string `json:"team_name"`
|
||||
TeamUpdateAt int64 `json:"team_update_at"`
|
||||
}
|
||||
|
||||
type ChannelsWithCount struct {
|
||||
Channels *ChannelListWithTeamData `json:"channels"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
}
|
||||
|
||||
type ChannelPatch struct {
|
||||
DisplayName *string `json:"display_name"`
|
||||
Name *string `json:"name"`
|
||||
Header *string `json:"header"`
|
||||
Purpose *string `json:"purpose"`
|
||||
GroupConstrained *bool `json:"group_constrained"`
|
||||
}
|
||||
|
||||
type ChannelForExport struct {
|
||||
Channel
|
||||
TeamName string
|
||||
SchemeName *string
|
||||
}
|
||||
|
||||
type DirectChannelForExport struct {
|
||||
Channel
|
||||
Members *[]string
|
||||
}
|
||||
|
||||
type ChannelModeration struct {
|
||||
Name string `json:"name"`
|
||||
Roles *ChannelModeratedRoles `json:"roles"`
|
||||
}
|
||||
|
||||
type ChannelModeratedRoles struct {
|
||||
Guests *ChannelModeratedRole `json:"guests"`
|
||||
Members *ChannelModeratedRole `json:"members"`
|
||||
}
|
||||
|
||||
type ChannelModeratedRole struct {
|
||||
Value bool `json:"value"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type ChannelModerationPatch struct {
|
||||
Name *string `json:"name"`
|
||||
Roles *ChannelModeratedRolesPatch `json:"roles"`
|
||||
}
|
||||
|
||||
type ChannelModeratedRolesPatch struct {
|
||||
Guests *bool `json:"guests"`
|
||||
Members *bool `json:"members"`
|
||||
}
|
||||
|
||||
// ChannelSearchOpts contains options for searching channels.
|
||||
//
|
||||
// NotAssociatedToGroup will exclude channels that have associated, active GroupChannels records.
|
||||
// ExcludeDefaultChannels will exclude the configured default channels (ex 'town-square' and 'off-topic').
|
||||
// IncludeDeleted will include channel records where DeleteAt != 0.
|
||||
// ExcludeChannelNames will exclude channels from the results by name.
|
||||
// Paginate whether to paginate the results.
|
||||
// Page page requested, if results are paginated.
|
||||
// PerPage number of results per page, if paginated.
|
||||
//
|
||||
type ChannelSearchOpts struct {
|
||||
NotAssociatedToGroup string
|
||||
ExcludeDefaultChannels bool
|
||||
IncludeDeleted bool
|
||||
ExcludeChannelNames []string
|
||||
Page *int
|
||||
PerPage *int
|
||||
}
|
||||
|
||||
type ChannelMemberCountByGroup struct {
|
||||
GroupId string `db:"-" json:"group_id"`
|
||||
ChannelMemberCount int64 `db:"-" json:"channel_member_count"`
|
||||
ChannelMemberTimezonesCount int64 `db:"-" json:"channel_member_timezones_count"`
|
||||
}
|
||||
|
||||
func (o *Channel) DeepCopy() *Channel {
|
||||
copy := *o
|
||||
if copy.SchemeId != nil {
|
||||
copy.SchemeId = NewString(*o.SchemeId)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
func (o *Channel) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *ChannelPatch) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *ChannelsWithCount) ToJson() []byte {
|
||||
b, _ := json.Marshal(o)
|
||||
return b
|
||||
}
|
||||
|
||||
func ChannelsWithCountFromJson(data io.Reader) *ChannelsWithCount {
|
||||
var o *ChannelsWithCount
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelFromJson(data io.Reader) *Channel {
|
||||
var o *Channel
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelPatchFromJson(data io.Reader) *ChannelPatch {
|
||||
var o *ChannelPatch
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelModerationsFromJson(data io.Reader) []*ChannelModeration {
|
||||
var o []*ChannelModeration
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelModerationsPatchFromJson(data io.Reader) []*ChannelModerationPatch {
|
||||
var o []*ChannelModerationPatch
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelMemberCountsByGroupFromJson(data io.Reader) []*ChannelMemberCountByGroup {
|
||||
var o []*ChannelMemberCountByGroup
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Channel) Etag() string {
|
||||
return Etag(o.Id, o.UpdateAt)
|
||||
}
|
||||
|
||||
func (o *Channel) IsValid() *AppError {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.DisplayName) > CHANNEL_DISPLAY_NAME_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.display_name.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidChannelIdentifier(o.Name) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(o.Type == CHANNEL_OPEN || o.Type == CHANNEL_PRIVATE || o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.type.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Header) > CHANNEL_HEADER_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.header.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Purpose) > CHANNEL_PURPOSE_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.purpose.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) > 26 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.creator_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
userIds := strings.Split(o.Name, "__")
|
||||
if o.Type != CHANNEL_DIRECT && len(userIds) == 2 && IsValidId(userIds[0]) && IsValidId(userIds[1]) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Channel) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
o.Name = SanitizeUnicode(o.Name)
|
||||
o.DisplayName = SanitizeUnicode(o.DisplayName)
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
o.UpdateAt = o.CreateAt
|
||||
o.ExtraUpdateAt = 0
|
||||
}
|
||||
|
||||
func (o *Channel) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
o.Name = SanitizeUnicode(o.Name)
|
||||
o.DisplayName = SanitizeUnicode(o.DisplayName)
|
||||
}
|
||||
|
||||
func (o *Channel) IsGroupOrDirect() bool {
|
||||
return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP
|
||||
}
|
||||
|
||||
func (o *Channel) IsOpen() bool {
|
||||
return o.Type == CHANNEL_OPEN
|
||||
}
|
||||
|
||||
func (o *Channel) Patch(patch *ChannelPatch) {
|
||||
if patch.DisplayName != nil {
|
||||
o.DisplayName = *patch.DisplayName
|
||||
}
|
||||
|
||||
if patch.Name != nil {
|
||||
o.Name = *patch.Name
|
||||
}
|
||||
|
||||
if patch.Header != nil {
|
||||
o.Header = *patch.Header
|
||||
}
|
||||
|
||||
if patch.Purpose != nil {
|
||||
o.Purpose = *patch.Purpose
|
||||
}
|
||||
|
||||
if patch.GroupConstrained != nil {
|
||||
o.GroupConstrained = patch.GroupConstrained
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Channel) MakeNonNil() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Channel) AddProp(key string, value interface{}) {
|
||||
o.MakeNonNil()
|
||||
|
||||
o.Props[key] = value
|
||||
}
|
||||
|
||||
func (o *Channel) IsGroupConstrained() bool {
|
||||
return o.GroupConstrained != nil && *o.GroupConstrained
|
||||
}
|
||||
|
||||
func (o *Channel) GetOtherUserIdForDM(userId string) string {
|
||||
if o.Type != CHANNEL_DIRECT {
|
||||
return ""
|
||||
}
|
||||
|
||||
userIds := strings.Split(o.Name, "__")
|
||||
|
||||
var otherUserId string
|
||||
|
||||
if userIds[0] != userIds[1] {
|
||||
if userIds[0] == userId {
|
||||
otherUserId = userIds[1]
|
||||
} else {
|
||||
otherUserId = userIds[0]
|
||||
}
|
||||
}
|
||||
|
||||
return otherUserId
|
||||
}
|
||||
|
||||
func GetDMNameFromIds(userId1, userId2 string) string {
|
||||
if userId1 > userId2 {
|
||||
return userId2 + "__" + userId1
|
||||
} else {
|
||||
return userId1 + "__" + userId2
|
||||
}
|
||||
}
|
||||
|
||||
func GetGroupDisplayNameFromUsers(users []*User, truncate bool) string {
|
||||
usernames := make([]string, len(users))
|
||||
for index, user := range users {
|
||||
usernames[index] = user.Username
|
||||
}
|
||||
|
||||
sort.Strings(usernames)
|
||||
|
||||
name := strings.Join(usernames, ", ")
|
||||
|
||||
if truncate && len(name) > CHANNEL_NAME_MAX_LENGTH {
|
||||
name = name[:CHANNEL_NAME_MAX_LENGTH]
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func GetGroupNameFromUserIds(userIds []string) string {
|
||||
sort.Strings(userIds)
|
||||
|
||||
h := sha1.New()
|
||||
for _, id := range userIds {
|
||||
io.WriteString(h, id)
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -51,3 +51,45 @@ func ChannelSliceFromJson(data io.Reader) []*Channel {
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
type ChannelListWithTeamData []*ChannelWithTeamData
|
||||
|
||||
func (o *ChannelListWithTeamData) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ChannelListWithTeamData) Etag() string {
|
||||
|
||||
id := "0"
|
||||
var t int64 = 0
|
||||
var delta int64 = 0
|
||||
|
||||
for _, v := range *o {
|
||||
if v.LastPostAt > t {
|
||||
t = v.LastPostAt
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
if v.UpdateAt > t {
|
||||
t = v.UpdateAt
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
if v.TeamUpdateAt > t {
|
||||
t = v.TeamUpdateAt
|
||||
id = v.Id
|
||||
}
|
||||
}
|
||||
|
||||
return Etag(id, t, delta, len(*o))
|
||||
}
|
||||
|
||||
func ChannelListWithTeamDataFromJson(data io.Reader) *ChannelListWithTeamData {
|
||||
var o *ChannelListWithTeamData
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -11,12 +11,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
CHANNEL_NOTIFY_DEFAULT = "default"
|
||||
CHANNEL_NOTIFY_ALL = "all"
|
||||
CHANNEL_NOTIFY_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_NONE = "none"
|
||||
CHANNEL_MARK_UNREAD_ALL = "all"
|
||||
CHANNEL_MARK_UNREAD_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_DEFAULT = "default"
|
||||
CHANNEL_NOTIFY_ALL = "all"
|
||||
CHANNEL_NOTIFY_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_NONE = "none"
|
||||
CHANNEL_MARK_UNREAD_ALL = "all"
|
||||
CHANNEL_MARK_UNREAD_MENTION = "mention"
|
||||
IGNORE_CHANNEL_MENTIONS_DEFAULT = "default"
|
||||
IGNORE_CHANNEL_MENTIONS_OFF = "off"
|
||||
IGNORE_CHANNEL_MENTIONS_ON = "on"
|
||||
IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP = "ignore_channel_mentions"
|
||||
)
|
||||
|
||||
type ChannelUnread struct {
|
||||
@ -27,6 +31,16 @@ type ChannelUnread struct {
|
||||
NotifyProps StringMap `json:"-"`
|
||||
}
|
||||
|
||||
type ChannelUnreadAt struct {
|
||||
TeamId string `json:"team_id"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
LastViewedAt int64 `json:"last_viewed_at"`
|
||||
NotifyProps StringMap `json:"-"`
|
||||
}
|
||||
|
||||
type ChannelMember struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
UserId string `json:"user_id"`
|
||||
@ -36,6 +50,7 @@ type ChannelMember struct {
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
NotifyProps StringMap `json:"notify_props"`
|
||||
LastUpdateAt int64 `json:"last_update_at"`
|
||||
SchemeGuest bool `json:"scheme_guest"`
|
||||
SchemeUser bool `json:"scheme_user"`
|
||||
SchemeAdmin bool `json:"scheme_admin"`
|
||||
ExplicitRoles string `json:"explicit_roles"`
|
||||
@ -46,6 +61,7 @@ type ChannelMembers []ChannelMember
|
||||
type ChannelMemberForExport struct {
|
||||
ChannelMember
|
||||
ChannelName string
|
||||
Username string
|
||||
}
|
||||
|
||||
func (o *ChannelMembers) ToJson() string {
|
||||
@ -61,6 +77,11 @@ func (o *ChannelUnread) ToJson() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *ChannelUnreadAt) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelMembersFromJson(data io.Reader) *ChannelMembers {
|
||||
var o *ChannelMembers
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
@ -73,6 +94,12 @@ func ChannelUnreadFromJson(data io.Reader) *ChannelUnread {
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelUnreadAtFromJson(data io.Reader) *ChannelUnreadAt {
|
||||
var o *ChannelUnreadAt
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *ChannelMember) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
@ -86,11 +113,11 @@ func ChannelMemberFromJson(data io.Reader) *ChannelMember {
|
||||
|
||||
func (o *ChannelMember) IsValid() *AppError {
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
if !IsValidId(o.ChannelId) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
if !IsValidId(o.UserId) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -116,6 +143,12 @@ func (o *ChannelMember) IsValid() *AppError {
|
||||
}
|
||||
}
|
||||
|
||||
if ignoreChannelMentions, ok := o.NotifyProps[IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP]; ok {
|
||||
if len(ignoreChannelMentions) > 40 || !IsIgnoreChannelMentionsValid(ignoreChannelMentions) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.ignore_channel_mentions_value.app_error", nil, "ignore_channel_mentions="+ignoreChannelMentions, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -146,11 +179,16 @@ func IsSendEmailValid(sendEmail string) bool {
|
||||
return sendEmail == CHANNEL_NOTIFY_DEFAULT || sendEmail == "true" || sendEmail == "false"
|
||||
}
|
||||
|
||||
func IsIgnoreChannelMentionsValid(ignoreChannelMentions string) bool {
|
||||
return ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_ON || ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_OFF || ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_DEFAULT
|
||||
}
|
||||
|
||||
func GetDefaultChannelNotifyProps() StringMap {
|
||||
return StringMap{
|
||||
DESKTOP_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
MARK_UNREAD_NOTIFY_PROP: CHANNEL_MARK_UNREAD_ALL,
|
||||
PUSH_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
EMAIL_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
DESKTOP_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
MARK_UNREAD_NOTIFY_PROP: CHANNEL_MARK_UNREAD_ALL,
|
||||
PUSH_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
EMAIL_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP: IGNORE_CHANNEL_MENTIONS_DEFAULT,
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -12,4 +12,5 @@ type ChannelMemberHistoryResult struct {
|
||||
// these two fields are never set in the database - when we SELECT, we join on Users to get them
|
||||
UserEmail string `db:"Email"`
|
||||
Username string
|
||||
IsBot bool
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
32
vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
generated
vendored
Normal file
32
vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const CHANNEL_SEARCH_DEFAULT_LIMIT = 50
|
||||
|
||||
type ChannelSearch struct {
|
||||
Term string `json:"term"`
|
||||
ExcludeDefaultChannels bool `json:"exclude_default_channels"`
|
||||
NotAssociatedToGroup string `json:"not_associated_to_group"`
|
||||
Page *int `json:"page,omitempty"`
|
||||
PerPage *int `json:"per_page,omitempty"`
|
||||
}
|
||||
|
||||
// ToJson convert a Channel to a json string
|
||||
func (c *ChannelSearch) ToJson() string {
|
||||
b, _ := json.Marshal(c)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// ChannelSearchFromJson will decode the input and return a Channel
|
||||
func ChannelSearchFromJson(data io.Reader) *ChannelSearch {
|
||||
var cs *ChannelSearch
|
||||
json.NewDecoder(data).Decode(&cs)
|
||||
return cs
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -9,8 +9,10 @@ import (
|
||||
)
|
||||
|
||||
type ChannelStats struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
MemberCount int64 `json:"member_count"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MemberCount int64 `json:"member_count"`
|
||||
GuestCount int64 `json:"guest_count"`
|
||||
PinnedPostCount int64 `json:"pinnedpost_count"`
|
||||
}
|
||||
|
||||
func (o *ChannelStats) ToJson() string {
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
5095
vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
generated
vendored
Normal file
5095
vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -46,10 +46,14 @@ func (o *ClusterDiscovery) AutoFillHostname() {
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) AutoFillIpAddress() {
|
||||
func (o *ClusterDiscovery) AutoFillIpAddress(iface string, ipAddress string) {
|
||||
// attempt to set the hostname to the first non-local IP address
|
||||
if len(o.Hostname) == 0 {
|
||||
o.Hostname = GetServerIpAddress()
|
||||
if len(ipAddress) > 0 {
|
||||
o.Hostname = ipAddress
|
||||
} else {
|
||||
o.Hostname = GetServerIpAddress(iface)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +89,7 @@ func FilterClusterDiscovery(vs []*ClusterDiscovery, f func(*ClusterDiscovery) bo
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -19,11 +19,31 @@ const (
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS = "inv_channel_members"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_BY_NAME = "inv_channel_name"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL = "inv_channel"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT = "inv_channel_guest_count"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER = "inv_user"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER_TEAMS = "inv_user_teams"
|
||||
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER = "clear_session_user"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES = "inv_roles"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS = "inv_role_permissions"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS = "inv_profile_ids"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL = "inv_profile_in_channel"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES = "inv_schemes"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_FILE_INFOS = "inv_file_infos"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS = "inv_webhooks"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID = "inv_emojis_by_id"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME = "inv_emojis_id_by_name"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_PINNEDPOSTS_COUNTS = "inv_channel_pinnedposts_counts"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS = "inv_channel_member_counts"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS = "inv_last_posts"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME = "inv_last_post_time"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS = "inv_teams"
|
||||
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_ALL_USERS = "inv_all_user_sessions"
|
||||
CLUSTER_EVENT_INSTALL_PLUGIN = "install_plugin"
|
||||
CLUSTER_EVENT_REMOVE_PLUGIN = "remove_plugin"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE = "inv_terms_of_service"
|
||||
CLUSTER_EVENT_BUSY_STATE_CHANGED = "busy_state_change"
|
||||
|
||||
// SendTypes for ClusterMessage.
|
||||
CLUSTER_SEND_BEST_EFFORT = "best_effort"
|
||||
CLUSTER_SEND_RELIABLE = "reliable"
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -18,23 +18,26 @@ const (
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
AutocompleteData *AutocompleteData `db:"-" json:"autocomplete_data,omitempty"`
|
||||
// AutocompleteIconData is a base64 encoded svg
|
||||
AutocompleteIconData string `db:"-" json:"autocomplete_icon_data,omitempty"`
|
||||
}
|
||||
|
||||
func (o *Command) ToJson() string {
|
||||
@ -61,7 +64,7 @@ func CommandListFromJson(data io.Reader) []*Command {
|
||||
|
||||
func (o *Command) IsValid() *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -77,11 +80,11 @@ func (o *Command) IsValid() *AppError {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.update_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) != 26 {
|
||||
if !IsValidId(o.CreatorId) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
if !IsValidId(o.TeamId) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -109,6 +112,12 @@ func (o *Command) IsValid() *AppError {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.description.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.AutocompleteData != nil {
|
||||
if err := o.AutocompleteData.IsValid(); err != nil {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.autocomplete_data.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
57
vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
generated
vendored
Normal file
57
vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
goi18n "github.com/mattermost/go-i18n/i18n"
|
||||
)
|
||||
|
||||
type CommandArgs struct {
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
RootId string `json:"root_id"`
|
||||
ParentId string `json:"parent_id"`
|
||||
TriggerId string `json:"trigger_id,omitempty"`
|
||||
Command string `json:"command"`
|
||||
SiteURL string `json:"-"`
|
||||
T goi18n.TranslateFunc `json:"-"`
|
||||
Session Session `json:"-"`
|
||||
UserMentions UserMentionMap `json:"-"`
|
||||
ChannelMentions ChannelMentionMap `json:"-"`
|
||||
}
|
||||
|
||||
func (o *CommandArgs) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CommandArgsFromJson(data io.Reader) *CommandArgs {
|
||||
var o *CommandArgs
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
// AddUserMention adds or overrides an entry in UserMentions with name username
|
||||
// and identifier userId
|
||||
func (o *CommandArgs) AddUserMention(username, userId string) {
|
||||
if o.UserMentions == nil {
|
||||
o.UserMentions = make(UserMentionMap)
|
||||
}
|
||||
|
||||
o.UserMentions[username] = userId
|
||||
}
|
||||
|
||||
// AddChannelMention adds or overrides an entry in ChannelMentions with name
|
||||
// channelName and identifier channelId
|
||||
func (o *CommandArgs) AddChannelMention(channelName, channelId string) {
|
||||
if o.ChannelMentions == nil {
|
||||
o.ChannelMentions = make(ChannelMentionMap)
|
||||
}
|
||||
|
||||
o.ChannelMentions[channelName] = channelId
|
||||
}
|
455
vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go
generated
vendored
Normal file
455
vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go
generated
vendored
Normal file
@ -0,0 +1,455 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// AutocompleteArgType describes autocomplete argument type
|
||||
type AutocompleteArgType string
|
||||
|
||||
// Argument types
|
||||
const (
|
||||
AutocompleteArgTypeText AutocompleteArgType = "TextInput"
|
||||
AutocompleteArgTypeStaticList AutocompleteArgType = "StaticList"
|
||||
AutocompleteArgTypeDynamicList AutocompleteArgType = "DynamicList"
|
||||
)
|
||||
|
||||
// AutocompleteData describes slash command autocomplete information.
|
||||
type AutocompleteData struct {
|
||||
// Trigger of the command
|
||||
Trigger string
|
||||
// Hint of a command
|
||||
Hint string
|
||||
// Text displayed to the user to help with the autocomplete description
|
||||
HelpText string
|
||||
// Role of the user who should be able to see the autocomplete info of this command
|
||||
RoleID string
|
||||
// Arguments of the command. Arguments can be named or positional.
|
||||
// If they are positional order in the list matters, if they are named order does not matter.
|
||||
// All arguments should be either named or positional, no mixing allowed.
|
||||
Arguments []*AutocompleteArg
|
||||
// Subcommands of the command
|
||||
SubCommands []*AutocompleteData
|
||||
}
|
||||
|
||||
// AutocompleteArg describes an argument of the command. Arguments can be named or positional.
|
||||
// If Name is empty string Argument is positional otherwise it is named argument.
|
||||
// Named arguments are passed as --Name Argument_Value.
|
||||
type AutocompleteArg struct {
|
||||
// Name of the argument
|
||||
Name string
|
||||
// Text displayed to the user to help with the autocomplete
|
||||
HelpText string
|
||||
// Type of the argument
|
||||
Type AutocompleteArgType
|
||||
// Required determins if argument is optional or not.
|
||||
Required bool
|
||||
// Actual data of the argument (depends on the Type)
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
// AutocompleteTextArg describes text user can input as an argument.
|
||||
type AutocompleteTextArg struct {
|
||||
// Hint of the input text
|
||||
Hint string
|
||||
// Regex pattern to match
|
||||
Pattern string
|
||||
}
|
||||
|
||||
// AutocompleteListItem describes an item in the AutocompleteStaticListArg.
|
||||
type AutocompleteListItem struct {
|
||||
Item string
|
||||
Hint string
|
||||
HelpText string
|
||||
}
|
||||
|
||||
// AutocompleteStaticListArg is used to input one of the arguments from the list,
|
||||
// for example [yes, no], [on, off], and so on.
|
||||
type AutocompleteStaticListArg struct {
|
||||
PossibleArguments []AutocompleteListItem
|
||||
}
|
||||
|
||||
// AutocompleteDynamicListArg is used when user wants to download possible argument list from the URL.
|
||||
type AutocompleteDynamicListArg struct {
|
||||
FetchURL string
|
||||
}
|
||||
|
||||
// AutocompleteSuggestion describes a single suggestion item sent to the front-end
|
||||
// Example: for user input `/jira cre` -
|
||||
// Complete might be `/jira create`
|
||||
// Suggestion might be `create`,
|
||||
// Hint might be `[issue text]`,
|
||||
// Description might be `Create a new Issue`
|
||||
type AutocompleteSuggestion struct {
|
||||
// Complete describes completed suggestion
|
||||
Complete string
|
||||
// Suggestion describes what user might want to input next
|
||||
Suggestion string
|
||||
// Hint describes a hint about the suggested input
|
||||
Hint string
|
||||
// Description of the command or a suggestion
|
||||
Description string
|
||||
// IconData is base64 encoded svg image
|
||||
IconData string
|
||||
}
|
||||
|
||||
// NewAutocompleteData returns new Autocomplete data.
|
||||
func NewAutocompleteData(trigger, hint, helpText string) *AutocompleteData {
|
||||
return &AutocompleteData{
|
||||
Trigger: trigger,
|
||||
Hint: hint,
|
||||
HelpText: helpText,
|
||||
RoleID: SYSTEM_USER_ROLE_ID,
|
||||
Arguments: []*AutocompleteArg{},
|
||||
SubCommands: []*AutocompleteData{},
|
||||
}
|
||||
}
|
||||
|
||||
// AddCommand adds a subcommand to the autocomplete data.
|
||||
func (ad *AutocompleteData) AddCommand(command *AutocompleteData) {
|
||||
ad.SubCommands = append(ad.SubCommands, command)
|
||||
}
|
||||
|
||||
// AddTextArgument adds positional AutocompleteArgTypeText argument to the command.
|
||||
func (ad *AutocompleteData) AddTextArgument(helpText, hint, pattern string) {
|
||||
ad.AddNamedTextArgument("", helpText, hint, pattern, true)
|
||||
}
|
||||
|
||||
// AddNamedTextArgument adds named AutocompleteArgTypeText argument to the command.
|
||||
func (ad *AutocompleteData) AddNamedTextArgument(name, helpText, hint, pattern string, required bool) {
|
||||
argument := AutocompleteArg{
|
||||
Name: name,
|
||||
HelpText: helpText,
|
||||
Type: AutocompleteArgTypeText,
|
||||
Required: required,
|
||||
Data: &AutocompleteTextArg{Hint: hint, Pattern: pattern},
|
||||
}
|
||||
ad.Arguments = append(ad.Arguments, &argument)
|
||||
}
|
||||
|
||||
// AddStaticListArgument adds positional AutocompleteArgTypeStaticList argument to the command.
|
||||
func (ad *AutocompleteData) AddStaticListArgument(helpText string, required bool, items []AutocompleteListItem) {
|
||||
ad.AddNamedStaticListArgument("", helpText, required, items)
|
||||
}
|
||||
|
||||
// AddNamedStaticListArgument adds named AutocompleteArgTypeStaticList argument to the command.
|
||||
func (ad *AutocompleteData) AddNamedStaticListArgument(name, helpText string, required bool, items []AutocompleteListItem) {
|
||||
argument := AutocompleteArg{
|
||||
Name: name,
|
||||
HelpText: helpText,
|
||||
Type: AutocompleteArgTypeStaticList,
|
||||
Required: required,
|
||||
Data: &AutocompleteStaticListArg{PossibleArguments: items},
|
||||
}
|
||||
ad.Arguments = append(ad.Arguments, &argument)
|
||||
}
|
||||
|
||||
// AddDynamicListArgument adds positional AutocompleteArgTypeDynamicList argument to the command.
|
||||
func (ad *AutocompleteData) AddDynamicListArgument(helpText, url string, required bool) {
|
||||
ad.AddNamedDynamicListArgument("", helpText, url, required)
|
||||
}
|
||||
|
||||
// AddNamedDynamicListArgument adds named AutocompleteArgTypeDynamicList argument to the command.
|
||||
func (ad *AutocompleteData) AddNamedDynamicListArgument(name, helpText, url string, required bool) {
|
||||
argument := AutocompleteArg{
|
||||
Name: name,
|
||||
HelpText: helpText,
|
||||
Type: AutocompleteArgTypeDynamicList,
|
||||
Required: required,
|
||||
Data: &AutocompleteDynamicListArg{FetchURL: url},
|
||||
}
|
||||
ad.Arguments = append(ad.Arguments, &argument)
|
||||
}
|
||||
|
||||
// Equals method checks if command is the same.
|
||||
func (ad *AutocompleteData) Equals(command *AutocompleteData) bool {
|
||||
if !(ad.Trigger == command.Trigger && ad.HelpText == command.HelpText && ad.RoleID == command.RoleID && ad.Hint == command.Hint) {
|
||||
return false
|
||||
}
|
||||
if len(ad.Arguments) != len(command.Arguments) || len(ad.SubCommands) != len(command.SubCommands) {
|
||||
return false
|
||||
}
|
||||
for i := range ad.Arguments {
|
||||
if !ad.Arguments[i].Equals(command.Arguments[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for i := range ad.SubCommands {
|
||||
if !ad.SubCommands[i].Equals(command.SubCommands[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// UpdateRelativeURLsForPluginCommands method updates relative urls for plugin commands
|
||||
func (ad *AutocompleteData) UpdateRelativeURLsForPluginCommands(baseURL *url.URL) error {
|
||||
for _, arg := range ad.Arguments {
|
||||
if arg.Type != AutocompleteArgTypeDynamicList {
|
||||
continue
|
||||
}
|
||||
dynamicList, ok := arg.Data.(*AutocompleteDynamicListArg)
|
||||
if !ok {
|
||||
return errors.New("Not a proper DynamicList type argument")
|
||||
}
|
||||
dynamicListURL, err := url.Parse(dynamicList.FetchURL)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "FetchURL is not a proper url")
|
||||
}
|
||||
if !dynamicListURL.IsAbs() {
|
||||
absURL := &url.URL{}
|
||||
*absURL = *baseURL
|
||||
absURL.Path = path.Join(absURL.Path, dynamicList.FetchURL)
|
||||
dynamicList.FetchURL = absURL.String()
|
||||
}
|
||||
|
||||
}
|
||||
for _, command := range ad.SubCommands {
|
||||
err := command.UpdateRelativeURLsForPluginCommands(baseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsValid method checks if autocomplete data is valid.
|
||||
func (ad *AutocompleteData) IsValid() error {
|
||||
if ad == nil {
|
||||
return errors.New("No nil commands are allowed in AutocompleteData")
|
||||
}
|
||||
if ad.Trigger == "" {
|
||||
return errors.New("An empty command name in the autocomplete data")
|
||||
}
|
||||
if strings.ToLower(ad.Trigger) != ad.Trigger {
|
||||
return errors.New("Command should be lowercase")
|
||||
}
|
||||
roles := []string{SYSTEM_ADMIN_ROLE_ID, SYSTEM_USER_ROLE_ID, ""}
|
||||
if stringNotInSlice(ad.RoleID, roles) {
|
||||
return errors.New("Wrong role in the autocomplete data")
|
||||
}
|
||||
if len(ad.Arguments) > 0 && len(ad.SubCommands) > 0 {
|
||||
return errors.New("Command can't have arguments and subcommands")
|
||||
}
|
||||
if len(ad.Arguments) > 0 {
|
||||
namedArgumentIndex := -1
|
||||
for i, arg := range ad.Arguments {
|
||||
if arg.Name != "" { // it's a named argument
|
||||
if namedArgumentIndex == -1 { // first named argument
|
||||
namedArgumentIndex = i
|
||||
}
|
||||
} else { // it's a positional argument
|
||||
if namedArgumentIndex != -1 {
|
||||
return errors.New("Named argument should not be before positional argument")
|
||||
}
|
||||
}
|
||||
if arg.Type == AutocompleteArgTypeDynamicList {
|
||||
dynamicList, ok := arg.Data.(*AutocompleteDynamicListArg)
|
||||
if !ok {
|
||||
return errors.New("Not a proper DynamicList type argument")
|
||||
}
|
||||
_, err := url.Parse(dynamicList.FetchURL)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "FetchURL is not a proper url")
|
||||
}
|
||||
} else if arg.Type == AutocompleteArgTypeStaticList {
|
||||
staticList, ok := arg.Data.(*AutocompleteStaticListArg)
|
||||
if !ok {
|
||||
return errors.New("Not a proper StaticList type argument")
|
||||
}
|
||||
for _, arg := range staticList.PossibleArguments {
|
||||
if arg.Item == "" {
|
||||
return errors.New("Possible argument name not set in StaticList argument")
|
||||
}
|
||||
}
|
||||
} else if arg.Type == AutocompleteArgTypeText {
|
||||
if _, ok := arg.Data.(*AutocompleteTextArg); !ok {
|
||||
return errors.New("Not a proper TextInput type argument")
|
||||
}
|
||||
if arg.Name == "" && !arg.Required {
|
||||
return errors.New("Positional argument can not be optional")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, command := range ad.SubCommands {
|
||||
err := command.IsValid()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToJSON encodes AutocompleteData struct to the json
|
||||
func (ad *AutocompleteData) ToJSON() ([]byte, error) {
|
||||
b, err := json.Marshal(ad)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "can't marshal slash command %s", ad.Trigger)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// AutocompleteDataFromJSON decodes AutocompleteData struct from the json
|
||||
func AutocompleteDataFromJSON(data []byte) (*AutocompleteData, error) {
|
||||
var ad AutocompleteData
|
||||
if err := json.Unmarshal(data, &ad); err != nil {
|
||||
return nil, errors.Wrap(err, "can't unmarshal AutocompleteData")
|
||||
}
|
||||
return &ad, nil
|
||||
}
|
||||
|
||||
// Equals method checks if argument is the same.
|
||||
func (a *AutocompleteArg) Equals(arg *AutocompleteArg) bool {
|
||||
if a.Name != arg.Name ||
|
||||
a.HelpText != arg.HelpText ||
|
||||
a.Type != arg.Type ||
|
||||
a.Required != arg.Required ||
|
||||
!reflect.DeepEqual(a.Data, arg.Data) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// UnmarshalJSON will unmarshal argument
|
||||
func (a *AutocompleteArg) UnmarshalJSON(b []byte) error {
|
||||
var arg map[string]interface{}
|
||||
if err := json.Unmarshal(b, &arg); err != nil {
|
||||
return errors.Wrapf(err, "Can't unmarshal argument %s", string(b))
|
||||
}
|
||||
var ok bool
|
||||
a.Name, ok = arg["Name"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Name in the argument %s", string(b))
|
||||
}
|
||||
|
||||
a.HelpText, ok = arg["HelpText"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field HelpText in the argument %s", string(b))
|
||||
}
|
||||
|
||||
t, ok := arg["Type"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Type in the argument %s", string(b))
|
||||
}
|
||||
a.Type = AutocompleteArgType(t)
|
||||
|
||||
a.Required, ok = arg["Required"].(bool)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Required in the argument %s", string(b))
|
||||
}
|
||||
|
||||
data, ok := arg["Data"]
|
||||
if !ok {
|
||||
return errors.Errorf("No field Data in the argument %s", string(b))
|
||||
}
|
||||
|
||||
if a.Type == AutocompleteArgTypeText {
|
||||
m, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return errors.Errorf("Wrong Data type in the TextInput argument %s", string(b))
|
||||
}
|
||||
pattern, ok := m["Pattern"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Pattern in the TextInput argument %s", string(b))
|
||||
}
|
||||
hint, ok := m["Hint"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Hint in the TextInput argument %s", string(b))
|
||||
}
|
||||
a.Data = &AutocompleteTextArg{Hint: hint, Pattern: pattern}
|
||||
} else if a.Type == AutocompleteArgTypeStaticList {
|
||||
m, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return errors.Errorf("Wrong Data type in the StaticList argument %s", string(b))
|
||||
}
|
||||
list, ok := m["PossibleArguments"].([]interface{})
|
||||
if !ok {
|
||||
return errors.Errorf("No field PossibleArguments in the StaticList argument %s", string(b))
|
||||
}
|
||||
|
||||
possibleArguments := []AutocompleteListItem{}
|
||||
for i := range list {
|
||||
args, ok := list[i].(map[string]interface{})
|
||||
if !ok {
|
||||
return errors.Errorf("Wrong AutocompleteStaticListItem type in the StaticList argument %s", string(b))
|
||||
}
|
||||
item, ok := args["Item"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Item in the StaticList's possible arguments %s", string(b))
|
||||
}
|
||||
|
||||
hint, ok := args["Hint"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Hint in the StaticList's possible arguments %s", string(b))
|
||||
}
|
||||
helpText, ok := args["HelpText"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field Hint in the StaticList's possible arguments %s", string(b))
|
||||
}
|
||||
|
||||
possibleArguments = append(possibleArguments, AutocompleteListItem{
|
||||
Item: item,
|
||||
Hint: hint,
|
||||
HelpText: helpText,
|
||||
})
|
||||
}
|
||||
a.Data = &AutocompleteStaticListArg{PossibleArguments: possibleArguments}
|
||||
} else if a.Type == AutocompleteArgTypeDynamicList {
|
||||
m, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return errors.Errorf("Wrong type in the DynamicList argument %s", string(b))
|
||||
}
|
||||
url, ok := m["FetchURL"].(string)
|
||||
if !ok {
|
||||
return errors.Errorf("No field FetchURL in the DynamicList's argument %s", string(b))
|
||||
}
|
||||
a.Data = &AutocompleteDynamicListArg{FetchURL: url}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AutocompleteSuggestionsToJSON returns json for a list of AutocompleteSuggestion objects
|
||||
func AutocompleteSuggestionsToJSON(suggestions []AutocompleteSuggestion) []byte {
|
||||
b, _ := json.Marshal(suggestions)
|
||||
return b
|
||||
}
|
||||
|
||||
// AutocompleteSuggestionsFromJSON returns list of AutocompleteSuggestions from json.
|
||||
func AutocompleteSuggestionsFromJSON(data io.Reader) []AutocompleteSuggestion {
|
||||
var o []AutocompleteSuggestion
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
// AutocompleteStaticListItemsToJSON returns json for a list of AutocompleteStaticListItem objects
|
||||
func AutocompleteStaticListItemsToJSON(items []AutocompleteListItem) []byte {
|
||||
b, _ := json.Marshal(items)
|
||||
return b
|
||||
}
|
||||
|
||||
// AutocompleteStaticListItemsFromJSON returns list of AutocompleteStaticListItem from json.
|
||||
func AutocompleteStaticListItemsFromJSON(data io.Reader) []AutocompleteListItem {
|
||||
var o []AutocompleteListItem
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func stringNotInSlice(a string, slice []string) bool {
|
||||
for _, b := range slice {
|
||||
if b == a {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
31
vendor/github.com/mattermost/mattermost-server/v5/model/command_request.go
generated
vendored
Normal file
31
vendor/github.com/mattermost/mattermost-server/v5/model/command_request.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type CommandMoveRequest struct {
|
||||
TeamId string `json:"team_id"`
|
||||
}
|
||||
|
||||
func CommandMoveRequestFromJson(data io.Reader) (*CommandMoveRequest, error) {
|
||||
decoder := json.NewDecoder(data)
|
||||
var cmr CommandMoveRequest
|
||||
err := decoder.Decode(&cmr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cmr, nil
|
||||
}
|
||||
|
||||
func (cmr *CommandMoveRequest) ToJson() string {
|
||||
b, err := json.Marshal(cmr)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(b)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/utils/jsonutils"
|
||||
"github.com/mattermost/mattermost-server/v5/utils/jsonutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -18,14 +18,18 @@ const (
|
||||
)
|
||||
|
||||
type CommandResponse struct {
|
||||
ResponseType string `json:"response_type"`
|
||||
Text string `json:"text"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Type string `json:"type"`
|
||||
Props StringInterface `json:"props"`
|
||||
GotoLocation string `json:"goto_location"`
|
||||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
ResponseType string `json:"response_type"`
|
||||
Text string `json:"text"`
|
||||
Username string `json:"username"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Type string `json:"type"`
|
||||
Props StringInterface `json:"props"`
|
||||
GotoLocation string `json:"goto_location"`
|
||||
TriggerId string `json:"trigger_id"`
|
||||
SkipSlackParsing bool `json:"skip_slack_parsing"` // Set to `true` to skip the Slack-compatibility handling of Text.
|
||||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
ExtraResponses []*CommandResponse `json:"extra_responses"`
|
||||
}
|
||||
|
||||
func (o *CommandResponse) ToJson() string {
|
||||
@ -63,5 +67,11 @@ func CommandResponseFromJson(data io.Reader) (*CommandResponse, error) {
|
||||
|
||||
o.Attachments = StringifySlackFieldValue(o.Attachments)
|
||||
|
||||
if o.ExtraResponses != nil {
|
||||
for _, resp := range o.ExtraResponses {
|
||||
resp.Attachments = StringifySlackFieldValue(resp.Attachments)
|
||||
}
|
||||
}
|
||||
|
||||
return &o, nil
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -33,7 +33,7 @@ func (o *CommandWebhook) PreSave() {
|
||||
}
|
||||
|
||||
func (o *CommandWebhook) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -41,23 +41,23 @@ func (o *CommandWebhook) IsValid() *AppError {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CommandId) != 26 {
|
||||
if !IsValidId(o.CommandId) {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.command_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
if !IsValidId(o.UserId) {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
if !IsValidId(o.ChannelId) {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.RootId) != 0 && len(o.RootId) != 26 {
|
||||
if len(o.RootId) != 0 && !IsValidId(o.RootId) {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.root_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ParentId) != 0 && len(o.ParentId) != 26 {
|
||||
if len(o.ParentId) != 0 && !IsValidId(o.ParentId) {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.parent_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -37,61 +37,61 @@ type Compliance struct {
|
||||
|
||||
type Compliances []Compliance
|
||||
|
||||
func (o *Compliance) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
func (c *Compliance) ToJson() string {
|
||||
b, _ := json.Marshal(c)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (me *Compliance) PreSave() {
|
||||
if me.Id == "" {
|
||||
me.Id = NewId()
|
||||
func (c *Compliance) PreSave() {
|
||||
if c.Id == "" {
|
||||
c.Id = NewId()
|
||||
}
|
||||
|
||||
if me.Status == "" {
|
||||
me.Status = COMPLIANCE_STATUS_CREATED
|
||||
if c.Status == "" {
|
||||
c.Status = COMPLIANCE_STATUS_CREATED
|
||||
}
|
||||
|
||||
me.Count = 0
|
||||
me.Emails = NormalizeEmail(me.Emails)
|
||||
me.Keywords = strings.ToLower(me.Keywords)
|
||||
c.Count = 0
|
||||
c.Emails = NormalizeEmail(c.Emails)
|
||||
c.Keywords = strings.ToLower(c.Keywords)
|
||||
|
||||
me.CreateAt = GetMillis()
|
||||
c.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (me *Compliance) JobName() string {
|
||||
jobName := me.Type
|
||||
if me.Type == COMPLIANCE_TYPE_DAILY {
|
||||
jobName += "-" + me.Desc
|
||||
func (c *Compliance) JobName() string {
|
||||
jobName := c.Type
|
||||
if c.Type == COMPLIANCE_TYPE_DAILY {
|
||||
jobName += "-" + c.Desc
|
||||
}
|
||||
|
||||
jobName += "-" + me.Id
|
||||
jobName += "-" + c.Id
|
||||
|
||||
return jobName
|
||||
}
|
||||
|
||||
func (me *Compliance) IsValid() *AppError {
|
||||
func (c *Compliance) IsValid() *AppError {
|
||||
|
||||
if len(me.Id) != 26 {
|
||||
if !IsValidId(c.Id) {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.CreateAt == 0 {
|
||||
if c.CreateAt == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(me.Desc) > 512 || len(me.Desc) == 0 {
|
||||
if len(c.Desc) > 512 || len(c.Desc) == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.desc.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.StartAt == 0 {
|
||||
if c.StartAt == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.start_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.EndAt == 0 {
|
||||
if c.EndAt == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.end_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.EndAt <= me.StartAt {
|
||||
if c.EndAt <= c.StartAt {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.start_end_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -99,13 +99,13 @@ func (me *Compliance) IsValid() *AppError {
|
||||
}
|
||||
|
||||
func ComplianceFromJson(data io.Reader) *Compliance {
|
||||
var o *Compliance
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
var c *Compliance
|
||||
json.NewDecoder(data).Decode(&c)
|
||||
return c
|
||||
}
|
||||
|
||||
func (o Compliances) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
func (c Compliances) ToJson() string {
|
||||
if b, err := json.Marshal(c); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -37,6 +37,8 @@ type CompliancePost struct {
|
||||
PostProps string
|
||||
PostHashtags string
|
||||
PostFileIds string
|
||||
|
||||
IsBot bool
|
||||
}
|
||||
|
||||
func CompliancePostHeader() []string {
|
||||
@ -64,6 +66,7 @@ func CompliancePostHeader() []string {
|
||||
"PostProps",
|
||||
"PostHashtags",
|
||||
"PostFileIds",
|
||||
"UserType",
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,6 +91,11 @@ func (me *CompliancePost) Row() []string {
|
||||
postUpdateAt = time.Unix(0, me.PostUpdateAt*int64(1000*1000)).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
userType := "user"
|
||||
if me.IsBot {
|
||||
userType = "bot"
|
||||
}
|
||||
|
||||
return []string{
|
||||
cleanComplianceStrings(me.TeamName),
|
||||
cleanComplianceStrings(me.TeamDisplayName),
|
||||
@ -99,6 +107,7 @@ func (me *CompliancePost) Row() []string {
|
||||
cleanComplianceStrings(me.UserUsername),
|
||||
cleanComplianceStrings(me.UserEmail),
|
||||
cleanComplianceStrings(me.UserNickname),
|
||||
userType,
|
||||
|
||||
me.PostId,
|
||||
time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339),
|
3451
vendor/github.com/mattermost/mattermost-server/v5/model/config.go
generated
vendored
Normal file
3451
vendor/github.com/mattermost/mattermost-server/v5/model/config.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -14,6 +15,8 @@ const (
|
||||
EMOJI_SORT_BY_NAME = "name"
|
||||
)
|
||||
|
||||
var EMOJI_PATTERN = regexp.MustCompile(`:[a-zA-Z0-9_-]+:`)
|
||||
|
||||
type Emoji struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
@ -28,8 +31,13 @@ func inSystemEmoji(emojiName string) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func GetSystemEmojiId(emojiName string) (string, bool) {
|
||||
id, found := SystemEmojis[emojiName]
|
||||
return id, found
|
||||
}
|
||||
|
||||
func (emoji *Emoji) IsValid() *AppError {
|
||||
if len(emoji.Id) != 26 {
|
||||
if !IsValidId(emoji.Id) {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -9,12 +9,12 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
|
||||
MaxImageSize = int64(6048 * 4032) // 24 megapixels, roughly 36MB as a raw image
|
||||
)
|
||||
|
||||
var (
|
||||
IMAGE_EXTENSIONS = [5]string{".jpg", ".jpeg", ".gif", ".bmp", ".png"}
|
||||
IMAGE_MIME_TYPES = map[string]string{".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".bmp": "image/bmp", ".png": "image/png", ".tiff": "image/tiff"}
|
||||
IMAGE_EXTENSIONS = [7]string{".jpg", ".jpeg", ".gif", ".bmp", ".png", ".tiff", "tif"}
|
||||
IMAGE_MIME_TYPES = map[string]string{".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".bmp": "image/bmp", ".png": "image/png", ".tiff": "image/tiff", ".tif": "image/tif"}
|
||||
)
|
||||
|
||||
type FileUploadResponse struct {
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -15,6 +15,27 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
FILEINFO_SORT_BY_CREATED = "CreateAt"
|
||||
FILEINFO_SORT_BY_SIZE = "Size"
|
||||
)
|
||||
|
||||
// GetFileInfosOptions contains options for getting FileInfos
|
||||
type GetFileInfosOptions struct {
|
||||
// UserIds optionally limits the FileInfos to those created by the given users.
|
||||
UserIds []string `json:"user_ids"`
|
||||
// ChannelIds optionally limits the FileInfos to those created in the given channels.
|
||||
ChannelIds []string `json:"channel_ids"`
|
||||
// Since optionally limits FileInfos to those created at or after the given time, specified as Unix time in milliseconds.
|
||||
Since int64 `json:"since"`
|
||||
// IncludeDeleted if set includes deleted FileInfos.
|
||||
IncludeDeleted bool `json:"include_deleted"`
|
||||
// SortBy sorts the FileInfos by this field. The default is to sort by date created.
|
||||
SortBy string `json:"sort_by"`
|
||||
// SortDescending changes the sort direction to descending order when true.
|
||||
SortDescending bool `json:"sort_descending"`
|
||||
}
|
||||
|
||||
type FileInfo struct {
|
||||
Id string `json:"id"`
|
||||
CreatorId string `json:"user_id"`
|
||||
@ -34,19 +55,19 @@ type FileInfo struct {
|
||||
HasPreviewImage bool `json:"has_preview_image,omitempty"`
|
||||
}
|
||||
|
||||
func (info *FileInfo) ToJson() string {
|
||||
b, _ := json.Marshal(info)
|
||||
func (fi *FileInfo) ToJson() string {
|
||||
b, _ := json.Marshal(fi)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func FileInfoFromJson(data io.Reader) *FileInfo {
|
||||
decoder := json.NewDecoder(data)
|
||||
|
||||
var info FileInfo
|
||||
if err := decoder.Decode(&info); err != nil {
|
||||
var fi FileInfo
|
||||
if err := decoder.Decode(&fi); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return &info
|
||||
return &fi
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,50 +87,68 @@ func FileInfosFromJson(data io.Reader) []*FileInfo {
|
||||
}
|
||||
}
|
||||
|
||||
func (o *FileInfo) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
func (fi *FileInfo) PreSave() {
|
||||
if fi.Id == "" {
|
||||
fi.Id = NewId()
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
o.CreateAt = GetMillis()
|
||||
if fi.CreateAt == 0 {
|
||||
fi.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
if o.UpdateAt < o.CreateAt {
|
||||
o.UpdateAt = o.CreateAt
|
||||
if fi.UpdateAt < fi.CreateAt {
|
||||
fi.UpdateAt = fi.CreateAt
|
||||
}
|
||||
}
|
||||
|
||||
func (o *FileInfo) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
func (fi *FileInfo) IsValid() *AppError {
|
||||
if !IsValidId(fi.Id) {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) != 26 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.user_id.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
if !IsValidId(fi.CreatorId) && fi.CreatorId != "nouser" {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.user_id.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.PostId) != 0 && len(o.PostId) != 26 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.post_id.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
if len(fi.PostId) != 0 && !IsValidId(fi.PostId) {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.post_id.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
if fi.CreateAt == 0 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.create_at.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
if fi.UpdateAt == 0 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.update_at.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.Path == "" {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.path.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
if fi.Path == "" {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.path.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *FileInfo) IsImage() bool {
|
||||
return strings.HasPrefix(o.MimeType, "image")
|
||||
func (fi *FileInfo) IsImage() bool {
|
||||
return strings.HasPrefix(fi.MimeType, "image")
|
||||
}
|
||||
|
||||
func NewInfo(name string) *FileInfo {
|
||||
info := &FileInfo{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
extension := strings.ToLower(filepath.Ext(name))
|
||||
info.MimeType = mime.TypeByExtension(extension)
|
||||
|
||||
if extension != "" && extension[0] == '.' {
|
||||
// The client expects a file extension without the leading period
|
||||
info.Extension = extension[1:]
|
||||
} else {
|
||||
info.Extension = extension
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func GetInfoForBytes(name string, data []byte) (*FileInfo, *AppError) {
|
||||
@ -140,7 +179,7 @@ func GetInfoForBytes(name string, data []byte) (*FileInfo, *AppError) {
|
||||
if gifConfig, err := gif.DecodeAll(bytes.NewReader(data)); err != nil {
|
||||
// Still return the rest of the info even though it doesn't appear to be an actual gif
|
||||
info.HasPreviewImage = true
|
||||
err = NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, "name="+name, http.StatusBadRequest)
|
||||
return info, NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, "name="+name, http.StatusBadRequest)
|
||||
} else {
|
||||
info.HasPreviewImage = len(gifConfig.Image) == 1
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
210
vendor/github.com/mattermost/mattermost-server/v5/model/group.go
generated
vendored
Normal file
210
vendor/github.com/mattermost/mattermost-server/v5/model/group.go
generated
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
GroupSourceLdap GroupSource = "ldap"
|
||||
|
||||
GroupNameMaxLength = 64
|
||||
GroupSourceMaxLength = 64
|
||||
GroupDisplayNameMaxLength = 128
|
||||
GroupDescriptionMaxLength = 1024
|
||||
GroupRemoteIDMaxLength = 48
|
||||
)
|
||||
|
||||
type GroupSource string
|
||||
|
||||
var allGroupSources = []GroupSource{
|
||||
GroupSourceLdap,
|
||||
}
|
||||
|
||||
var groupSourcesRequiringRemoteID = []GroupSource{
|
||||
GroupSourceLdap,
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Id string `json:"id"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
Source GroupSource `json:"source"`
|
||||
RemoteId string `json:"remote_id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
HasSyncables bool `db:"-" json:"has_syncables"`
|
||||
MemberCount *int `db:"-" json:"member_count,omitempty"`
|
||||
AllowReference bool `json:"allow_reference"`
|
||||
}
|
||||
|
||||
type GroupWithSchemeAdmin struct {
|
||||
Group
|
||||
SchemeAdmin *bool `db:"SyncableSchemeAdmin" json:"scheme_admin,omitempty"`
|
||||
}
|
||||
|
||||
type GroupsAssociatedToChannelWithSchemeAdmin struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
Group
|
||||
SchemeAdmin *bool `db:"SyncableSchemeAdmin" json:"scheme_admin,omitempty"`
|
||||
}
|
||||
type GroupsAssociatedToChannel struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
Groups []*GroupWithSchemeAdmin `json:"groups"`
|
||||
}
|
||||
|
||||
type GroupPatch struct {
|
||||
Name *string `json:"name"`
|
||||
DisplayName *string `json:"display_name"`
|
||||
Description *string `json:"description"`
|
||||
AllowReference *bool `json:"allow_reference"`
|
||||
}
|
||||
|
||||
type LdapGroupSearchOpts struct {
|
||||
Q string
|
||||
IsLinked *bool
|
||||
IsConfigured *bool
|
||||
}
|
||||
|
||||
type GroupSearchOpts struct {
|
||||
Q string
|
||||
NotAssociatedToTeam string
|
||||
NotAssociatedToChannel string
|
||||
IncludeMemberCount bool
|
||||
FilterAllowReference bool
|
||||
PageOpts *PageOpts
|
||||
Since int64
|
||||
|
||||
// FilterParentTeamPermitted filters the groups to the intersect of the
|
||||
// set associated to the parent team and those returned by the query.
|
||||
// If the parent team is not group-constrained or if NotAssociatedToChannel
|
||||
// is not set then this option is ignored.
|
||||
FilterParentTeamPermitted bool
|
||||
}
|
||||
|
||||
type PageOpts struct {
|
||||
Page int
|
||||
PerPage int
|
||||
}
|
||||
|
||||
func (group *Group) Patch(patch *GroupPatch) {
|
||||
if patch.Name != nil {
|
||||
group.Name = patch.Name
|
||||
}
|
||||
if patch.DisplayName != nil {
|
||||
group.DisplayName = *patch.DisplayName
|
||||
}
|
||||
if patch.Description != nil {
|
||||
group.Description = *patch.Description
|
||||
}
|
||||
if patch.AllowReference != nil {
|
||||
group.AllowReference = *patch.AllowReference
|
||||
}
|
||||
}
|
||||
|
||||
func (group *Group) IsValidForCreate() *AppError {
|
||||
err := group.IsValidName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if l := len(group.DisplayName); l == 0 || l > GroupDisplayNameMaxLength {
|
||||
return NewAppError("Group.IsValidForCreate", "model.group.display_name.app_error", map[string]interface{}{"GroupDisplayNameMaxLength": GroupDisplayNameMaxLength}, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(group.Description) > GroupDescriptionMaxLength {
|
||||
return NewAppError("Group.IsValidForCreate", "model.group.description.app_error", map[string]interface{}{"GroupDescriptionMaxLength": GroupDescriptionMaxLength}, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
isValidSource := false
|
||||
for _, groupSource := range allGroupSources {
|
||||
if group.Source == groupSource {
|
||||
isValidSource = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isValidSource {
|
||||
return NewAppError("Group.IsValidForCreate", "model.group.source.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(group.RemoteId) > GroupRemoteIDMaxLength || (len(group.RemoteId) == 0 && group.requiresRemoteId()) {
|
||||
return NewAppError("Group.IsValidForCreate", "model.group.remote_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (group *Group) requiresRemoteId() bool {
|
||||
for _, groupSource := range groupSourcesRequiringRemoteID {
|
||||
if groupSource == group.Source {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (group *Group) IsValidForUpdate() *AppError {
|
||||
if !IsValidId(group.Id) {
|
||||
return NewAppError("Group.IsValidForUpdate", "model.group.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if group.CreateAt == 0 {
|
||||
return NewAppError("Group.IsValidForUpdate", "model.group.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if group.UpdateAt == 0 {
|
||||
return NewAppError("Group.IsValidForUpdate", "model.group.update_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if err := group.IsValidForCreate(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (group *Group) ToJson() string {
|
||||
b, _ := json.Marshal(group)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
var validGroupnameChars = regexp.MustCompile(`^[a-z0-9\.\-_]+$`)
|
||||
|
||||
func (group *Group) IsValidName() *AppError {
|
||||
|
||||
if group.Name == nil {
|
||||
if group.AllowReference {
|
||||
return NewAppError("Group.IsValidName", "model.group.name.app_error", map[string]interface{}{"GroupNameMaxLength": GroupNameMaxLength}, "", http.StatusBadRequest)
|
||||
}
|
||||
} else {
|
||||
if l := len(*group.Name); l == 0 || l > GroupNameMaxLength {
|
||||
return NewAppError("Group.IsValidName", "model.group.name.invalid_length.app_error", map[string]interface{}{"GroupNameMaxLength": GroupNameMaxLength}, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !validGroupnameChars.MatchString(*group.Name) {
|
||||
return NewAppError("Group.IsValidName", "model.group.name.invalid_chars.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GroupFromJson(data io.Reader) *Group {
|
||||
var group *Group
|
||||
json.NewDecoder(data).Decode(&group)
|
||||
return group
|
||||
}
|
||||
|
||||
func GroupsFromJson(data io.Reader) []*Group {
|
||||
var groups []*Group
|
||||
json.NewDecoder(data).Decode(&groups)
|
||||
return groups
|
||||
}
|
||||
|
||||
func GroupPatchFromJson(data io.Reader) *GroupPatch {
|
||||
var groupPatch *GroupPatch
|
||||
json.NewDecoder(data).Decode(&groupPatch)
|
||||
return groupPatch
|
||||
}
|
23
vendor/github.com/mattermost/mattermost-server/v5/model/group_member.go
generated
vendored
Normal file
23
vendor/github.com/mattermost/mattermost-server/v5/model/group_member.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import "net/http"
|
||||
|
||||
type GroupMember struct {
|
||||
GroupId string `json:"group_id"`
|
||||
UserId string `json:"user_id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
}
|
||||
|
||||
func (gm *GroupMember) IsValid() *AppError {
|
||||
if !IsValidId(gm.GroupId) {
|
||||
return NewAppError("GroupMember.IsValid", "model.group_member.group_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if !IsValidId(gm.UserId) {
|
||||
return NewAppError("GroupMember.IsValid", "model.group_member.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
return nil
|
||||
}
|
180
vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go
generated
vendored
Normal file
180
vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type GroupSyncableType string
|
||||
|
||||
const (
|
||||
GroupSyncableTypeTeam GroupSyncableType = "Team"
|
||||
GroupSyncableTypeChannel GroupSyncableType = "Channel"
|
||||
)
|
||||
|
||||
func (gst GroupSyncableType) String() string {
|
||||
return string(gst)
|
||||
}
|
||||
|
||||
type GroupSyncable struct {
|
||||
GroupId string `json:"group_id"`
|
||||
|
||||
// SyncableId represents the Id of the model that is being synced with the group, for example a ChannelId or
|
||||
// TeamId.
|
||||
SyncableId string `db:"-" json:"-"`
|
||||
|
||||
AutoAdd bool `json:"auto_add"`
|
||||
SchemeAdmin bool `json:"scheme_admin"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
Type GroupSyncableType `db:"-" json:"-"`
|
||||
|
||||
// Values joined in from the associated team and/or channel
|
||||
ChannelDisplayName string `db:"-" json:"-"`
|
||||
TeamDisplayName string `db:"-" json:"-"`
|
||||
TeamType string `db:"-" json:"-"`
|
||||
ChannelType string `db:"-" json:"-"`
|
||||
TeamID string `db:"-" json:"-"`
|
||||
}
|
||||
|
||||
func (syncable *GroupSyncable) IsValid() *AppError {
|
||||
if !IsValidId(syncable.GroupId) {
|
||||
return NewAppError("GroupSyncable.SyncableIsValid", "model.group_syncable.group_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if !IsValidId(syncable.SyncableId) {
|
||||
return NewAppError("GroupSyncable.SyncableIsValid", "model.group_syncable.syncable_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (syncable *GroupSyncable) UnmarshalJSON(b []byte) error {
|
||||
var kvp map[string]interface{}
|
||||
err := json.Unmarshal(b, &kvp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for key, value := range kvp {
|
||||
switch key {
|
||||
case "team_id":
|
||||
syncable.SyncableId = value.(string)
|
||||
syncable.Type = GroupSyncableTypeTeam
|
||||
case "channel_id":
|
||||
syncable.SyncableId = value.(string)
|
||||
syncable.Type = GroupSyncableTypeChannel
|
||||
case "group_id":
|
||||
syncable.GroupId = value.(string)
|
||||
case "auto_add":
|
||||
syncable.AutoAdd = value.(bool)
|
||||
default:
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (syncable *GroupSyncable) MarshalJSON() ([]byte, error) {
|
||||
type Alias GroupSyncable
|
||||
|
||||
switch syncable.Type {
|
||||
case GroupSyncableTypeTeam:
|
||||
return json.Marshal(&struct {
|
||||
TeamID string `json:"team_id"`
|
||||
TeamDisplayName string `json:"team_display_name,omitempty"`
|
||||
TeamType string `json:"team_type,omitempty"`
|
||||
*Alias
|
||||
}{
|
||||
TeamDisplayName: syncable.TeamDisplayName,
|
||||
TeamType: syncable.TeamType,
|
||||
TeamID: syncable.SyncableId,
|
||||
Alias: (*Alias)(syncable),
|
||||
})
|
||||
case GroupSyncableTypeChannel:
|
||||
return json.Marshal(&struct {
|
||||
ChannelID string `json:"channel_id"`
|
||||
ChannelDisplayName string `json:"channel_display_name,omitempty"`
|
||||
ChannelType string `json:"channel_type,omitempty"`
|
||||
|
||||
TeamID string `json:"team_id,omitempty"`
|
||||
TeamDisplayName string `json:"team_display_name,omitempty"`
|
||||
TeamType string `json:"team_type,omitempty"`
|
||||
|
||||
*Alias
|
||||
}{
|
||||
ChannelID: syncable.SyncableId,
|
||||
ChannelDisplayName: syncable.ChannelDisplayName,
|
||||
ChannelType: syncable.ChannelType,
|
||||
|
||||
TeamID: syncable.TeamID,
|
||||
TeamDisplayName: syncable.TeamDisplayName,
|
||||
TeamType: syncable.TeamType,
|
||||
|
||||
Alias: (*Alias)(syncable),
|
||||
})
|
||||
default:
|
||||
return nil, &json.MarshalerError{
|
||||
Err: fmt.Errorf("unknown syncable type: %s", syncable.Type),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type GroupSyncablePatch struct {
|
||||
AutoAdd *bool `json:"auto_add"`
|
||||
SchemeAdmin *bool `json:"scheme_admin"`
|
||||
}
|
||||
|
||||
func (syncable *GroupSyncable) Patch(patch *GroupSyncablePatch) {
|
||||
if patch.AutoAdd != nil {
|
||||
syncable.AutoAdd = *patch.AutoAdd
|
||||
}
|
||||
if patch.SchemeAdmin != nil {
|
||||
syncable.SchemeAdmin = *patch.SchemeAdmin
|
||||
}
|
||||
}
|
||||
|
||||
type UserTeamIDPair struct {
|
||||
UserID string
|
||||
TeamID string
|
||||
}
|
||||
|
||||
type UserChannelIDPair struct {
|
||||
UserID string
|
||||
ChannelID string
|
||||
}
|
||||
|
||||
func GroupSyncableFromJson(data io.Reader) *GroupSyncable {
|
||||
groupSyncable := &GroupSyncable{}
|
||||
bodyBytes, _ := ioutil.ReadAll(data)
|
||||
json.Unmarshal(bodyBytes, groupSyncable)
|
||||
return groupSyncable
|
||||
}
|
||||
|
||||
func GroupSyncablesFromJson(data io.Reader) []*GroupSyncable {
|
||||
groupSyncables := []*GroupSyncable{}
|
||||
bodyBytes, _ := ioutil.ReadAll(data)
|
||||
json.Unmarshal(bodyBytes, &groupSyncables)
|
||||
return groupSyncables
|
||||
}
|
||||
|
||||
func NewGroupTeam(groupID, teamID string, autoAdd bool) *GroupSyncable {
|
||||
return &GroupSyncable{
|
||||
GroupId: groupID,
|
||||
SyncableId: teamID,
|
||||
Type: GroupSyncableTypeTeam,
|
||||
AutoAdd: autoAdd,
|
||||
}
|
||||
}
|
||||
|
||||
func NewGroupChannel(groupID, channelID string, autoAdd bool) *GroupSyncable {
|
||||
return &GroupSyncable{
|
||||
GroupId: groupID,
|
||||
SyncableId: channelID,
|
||||
Type: GroupSyncableTypeChannel,
|
||||
AutoAdd: autoAdd,
|
||||
}
|
||||
}
|
53
vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go
generated
vendored
Normal file
53
vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type GuestsInvite struct {
|
||||
Emails []string `json:"emails"`
|
||||
Channels []string `json:"channels"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// IsValid validates the user and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (i *GuestsInvite) IsValid() *AppError {
|
||||
if len(i.Emails) == 0 {
|
||||
return NewAppError("GuestsInvite.IsValid", "model.guest.is_valid.emails.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
for _, email := range i.Emails {
|
||||
if len(email) > USER_EMAIL_MAX_LENGTH || len(email) == 0 || !IsValidEmail(email) {
|
||||
return NewAppError("GuestsInvite.IsValid", "model.guest.is_valid.email.app_error", nil, "email="+email, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if len(i.Channels) == 0 {
|
||||
return NewAppError("GuestsInvite.IsValid", "model.guest.is_valid.channels.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
for _, channel := range i.Channels {
|
||||
if len(channel) != 26 {
|
||||
return NewAppError("GuestsInvite.IsValid", "model.guest.is_valid.channel.app_error", nil, "channel="+channel, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GuestsInviteFromJson will decode the input and return a GuestsInvite
|
||||
func GuestsInviteFromJson(data io.Reader) *GuestsInvite {
|
||||
var i *GuestsInvite
|
||||
json.NewDecoder(data).Decode(&i)
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *GuestsInvite) ToJson() string {
|
||||
b, _ := json.Marshal(i)
|
||||
return string(b)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -38,6 +38,7 @@ type IncomingWebhookRequest struct {
|
||||
Props StringInterface `json:"props"`
|
||||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
Type string `json:"type"`
|
||||
IconEmoji string `json:"icon_emoji"`
|
||||
}
|
||||
|
||||
func (o *IncomingWebhook) ToJson() string {
|
||||
@ -64,7 +65,7 @@ func IncomingWebhookListFromJson(data io.Reader) []*IncomingWebhook {
|
||||
|
||||
func (o *IncomingWebhook) IsValid() *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.id.app_error", nil, "", http.StatusBadRequest)
|
||||
|
||||
}
|
||||
@ -77,15 +78,15 @@ func (o *IncomingWebhook) IsValid() *AppError {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
if !IsValidId(o.UserId) {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
if !IsValidId(o.ChannelId) {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
if !IsValidId(o.TeamId) {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
525
vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go
generated
vendored
Normal file
525
vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go
generated
vendored
Normal file
@ -0,0 +1,525 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
POST_ACTION_TYPE_BUTTON = "button"
|
||||
POST_ACTION_TYPE_SELECT = "select"
|
||||
INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS = 3000
|
||||
)
|
||||
|
||||
var PostActionRetainPropKeys = []string{"from_webhook", "override_username", "override_icon_url"}
|
||||
|
||||
type DoPostActionRequest struct {
|
||||
SelectedOption string `json:"selected_option,omitempty"`
|
||||
Cookie string `json:"cookie,omitempty"`
|
||||
}
|
||||
|
||||
type PostAction struct {
|
||||
// A unique Action ID. If not set, generated automatically.
|
||||
Id string `json:"id,omitempty"`
|
||||
|
||||
// The type of the interactive element. Currently supported are
|
||||
// "select" and "button".
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
// The text on the button, or in the select placeholder.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// If the action is disabled.
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
|
||||
// Style defines a text and border style.
|
||||
// Supported values are "default", "primary", "success", "good", "warning", "danger"
|
||||
// and any hex color.
|
||||
Style string `json:"style,omitempty"`
|
||||
|
||||
// DataSource indicates the data source for the select action. If left
|
||||
// empty, the select is populated from Options. Other supported values
|
||||
// are "users" and "channels".
|
||||
DataSource string `json:"data_source,omitempty"`
|
||||
|
||||
// Options contains the values listed in a select dropdown on the post.
|
||||
Options []*PostActionOptions `json:"options,omitempty"`
|
||||
|
||||
// DefaultOption contains the option, if any, that will appear as the
|
||||
// default selection in a select box. It has no effect when used with
|
||||
// other types of actions.
|
||||
DefaultOption string `json:"default_option,omitempty"`
|
||||
|
||||
// Defines the interaction with the backend upon a user action.
|
||||
// Integration contains Context, which is private plugin data;
|
||||
// Integrations are stripped from Posts when they are sent to the
|
||||
// client, or are encrypted in a Cookie.
|
||||
Integration *PostActionIntegration `json:"integration,omitempty"`
|
||||
Cookie string `json:"cookie,omitempty" db:"-"`
|
||||
}
|
||||
|
||||
func (p *PostAction) Equals(input *PostAction) bool {
|
||||
if p.Id != input.Id {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Type != input.Type {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Name != input.Name {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.DataSource != input.DataSource {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.DefaultOption != input.DefaultOption {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Cookie != input.Cookie {
|
||||
return false
|
||||
}
|
||||
|
||||
// Compare PostActionOptions
|
||||
if len(p.Options) != len(input.Options) {
|
||||
return false
|
||||
}
|
||||
|
||||
for k := range p.Options {
|
||||
if p.Options[k].Text != input.Options[k].Text {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Options[k].Value != input.Options[k].Value {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Compare PostActionIntegration
|
||||
if p.Integration.URL != input.Integration.URL {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(p.Integration.Context) != len(input.Integration.Context) {
|
||||
return false
|
||||
}
|
||||
|
||||
for key, value := range p.Integration.Context {
|
||||
inputValue, ok := input.Integration.Context[key]
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if value != inputValue {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// PostActionCookie is set by the server, serialized and encrypted into
|
||||
// PostAction.Cookie. The clients should hold on to it, and include it with
|
||||
// subsequent DoPostAction requests. This allows the server to access the
|
||||
// action metadata even when it's not available in the database, for ephemeral
|
||||
// posts.
|
||||
type PostActionCookie struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
PostId string `json:"post_id,omitempty"`
|
||||
RootPostId string `json:"root_post_id,omitempty"`
|
||||
ChannelId string `json:"channel_id,omitempty"`
|
||||
DataSource string `json:"data_source,omitempty"`
|
||||
Integration *PostActionIntegration `json:"integration,omitempty"`
|
||||
RetainProps map[string]interface{} `json:"retain_props,omitempty"`
|
||||
RemoveProps []string `json:"remove_props,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionOptions struct {
|
||||
Text string `json:"text"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type PostActionIntegration struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
Context map[string]interface{} `json:"context,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionIntegrationRequest struct {
|
||||
UserId string `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
ChannelName string `json:"channel_name"`
|
||||
TeamId string `json:"team_id"`
|
||||
TeamName string `json:"team_domain"`
|
||||
PostId string `json:"post_id"`
|
||||
TriggerId string `json:"trigger_id"`
|
||||
Type string `json:"type"`
|
||||
DataSource string `json:"data_source"`
|
||||
Context map[string]interface{} `json:"context,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionIntegrationResponse struct {
|
||||
Update *Post `json:"update"`
|
||||
EphemeralText string `json:"ephemeral_text"`
|
||||
SkipSlackParsing bool `json:"skip_slack_parsing"` // Set to `true` to skip the Slack-compatibility handling of Text.
|
||||
}
|
||||
|
||||
type PostActionAPIResponse struct {
|
||||
Status string `json:"status"` // needed to maintain backwards compatibility
|
||||
TriggerId string `json:"trigger_id"`
|
||||
}
|
||||
|
||||
type Dialog struct {
|
||||
CallbackId string `json:"callback_id"`
|
||||
Title string `json:"title"`
|
||||
IntroductionText string `json:"introduction_text"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Elements []DialogElement `json:"elements"`
|
||||
SubmitLabel string `json:"submit_label"`
|
||||
NotifyOnCancel bool `json:"notify_on_cancel"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
type DialogElement struct {
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
SubType string `json:"subtype"`
|
||||
Default string `json:"default"`
|
||||
Placeholder string `json:"placeholder"`
|
||||
HelpText string `json:"help_text"`
|
||||
Optional bool `json:"optional"`
|
||||
MinLength int `json:"min_length"`
|
||||
MaxLength int `json:"max_length"`
|
||||
DataSource string `json:"data_source"`
|
||||
Options []*PostActionOptions `json:"options"`
|
||||
}
|
||||
|
||||
type OpenDialogRequest struct {
|
||||
TriggerId string `json:"trigger_id"`
|
||||
URL string `json:"url"`
|
||||
Dialog Dialog `json:"dialog"`
|
||||
}
|
||||
|
||||
type SubmitDialogRequest struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url,omitempty"`
|
||||
CallbackId string `json:"callback_id"`
|
||||
State string `json:"state"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Submission map[string]interface{} `json:"submission"`
|
||||
Cancelled bool `json:"cancelled"`
|
||||
}
|
||||
|
||||
type SubmitDialogResponse struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
Errors map[string]string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
func GenerateTriggerId(userId string, s crypto.Signer) (string, string, *AppError) {
|
||||
clientTriggerId := NewId()
|
||||
triggerData := strings.Join([]string{clientTriggerId, userId, strconv.FormatInt(GetMillis(), 10)}, ":") + ":"
|
||||
|
||||
h := crypto.SHA256
|
||||
sum := h.New()
|
||||
sum.Write([]byte(triggerData))
|
||||
signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
|
||||
if err != nil {
|
||||
return "", "", NewAppError("GenerateTriggerId", "interactive_message.generate_trigger_id.signing_failed", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
base64Sig := base64.StdEncoding.EncodeToString(signature)
|
||||
|
||||
triggerId := base64.StdEncoding.EncodeToString([]byte(triggerData + base64Sig))
|
||||
return clientTriggerId, triggerId, nil
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationRequest) GenerateTriggerId(s crypto.Signer) (string, string, *AppError) {
|
||||
clientTriggerId, triggerId, err := GenerateTriggerId(r.UserId, s)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
r.TriggerId = triggerId
|
||||
return clientTriggerId, triggerId, nil
|
||||
}
|
||||
|
||||
func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, string, *AppError) {
|
||||
triggerIdBytes, err := base64.StdEncoding.DecodeString(triggerId)
|
||||
if err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
split := strings.Split(string(triggerIdBytes), ":")
|
||||
if len(split) != 4 {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.missing_data", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
clientTriggerId := split[0]
|
||||
userId := split[1]
|
||||
timestampStr := split[2]
|
||||
timestamp, _ := strconv.ParseInt(timestampStr, 10, 64)
|
||||
|
||||
now := GetMillis()
|
||||
if now-timestamp > INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.expired", map[string]interface{}{"Seconds": INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS / 1000}, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
signature, err := base64.StdEncoding.DecodeString(split[3])
|
||||
if err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed_signature", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
var esig struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
|
||||
if _, err := asn1.Unmarshal(signature, &esig); err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.signature_decode_failed", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
triggerData := strings.Join([]string{clientTriggerId, userId, timestampStr}, ":") + ":"
|
||||
|
||||
h := crypto.SHA256
|
||||
sum := h.New()
|
||||
sum.Write([]byte(triggerData))
|
||||
|
||||
if !ecdsa.Verify(&s.PublicKey, sum.Sum(nil), esig.R, esig.S) {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.verify_signature_failed", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return clientTriggerId, userId, nil
|
||||
}
|
||||
|
||||
func (r *OpenDialogRequest) DecodeAndVerifyTriggerId(s *ecdsa.PrivateKey) (string, string, *AppError) {
|
||||
return DecodeAndVerifyTriggerId(r.TriggerId, s)
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationRequest) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func PostActionIntegrationRequestFromJson(data io.Reader) *PostActionIntegrationRequest {
|
||||
var o *PostActionIntegrationRequest
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationResponse) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func PostActionIntegrationResponseFromJson(data io.Reader) *PostActionIntegrationResponse {
|
||||
var o *PostActionIntegrationResponse
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func SubmitDialogRequestFromJson(data io.Reader) *SubmitDialogRequest {
|
||||
var o *SubmitDialogRequest
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (r *SubmitDialogRequest) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func SubmitDialogResponseFromJson(data io.Reader) *SubmitDialogResponse {
|
||||
var o *SubmitDialogResponse
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (r *SubmitDialogResponse) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func (o *Post) StripActionIntegrations() {
|
||||
attachments := o.Attachments()
|
||||
if o.GetProp("attachments") != nil {
|
||||
o.AddProp("attachments", attachments)
|
||||
}
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
action.Integration = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Post) GetAction(id string) *PostAction {
|
||||
for _, attachment := range o.Attachments() {
|
||||
for _, action := range attachment.Actions {
|
||||
if action.Id == id {
|
||||
return action
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Post) GenerateActionIds() {
|
||||
if o.GetProp("attachments") != nil {
|
||||
o.AddProp("attachments", o.Attachments())
|
||||
}
|
||||
if attachments, ok := o.GetProp("attachments").([]*SlackAttachment); ok {
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
if action.Id == "" {
|
||||
action.Id = NewId()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AddPostActionCookies(o *Post, secret []byte) *Post {
|
||||
p := o.Clone()
|
||||
|
||||
// retainedProps carry over their value from the old post, including no value
|
||||
retainProps := map[string]interface{}{}
|
||||
removeProps := []string{}
|
||||
for _, key := range PostActionRetainPropKeys {
|
||||
value, ok := p.GetProps()[key]
|
||||
if ok {
|
||||
retainProps[key] = value
|
||||
} else {
|
||||
removeProps = append(removeProps, key)
|
||||
}
|
||||
}
|
||||
|
||||
attachments := p.Attachments()
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
c := &PostActionCookie{
|
||||
Type: action.Type,
|
||||
ChannelId: p.ChannelId,
|
||||
DataSource: action.DataSource,
|
||||
Integration: action.Integration,
|
||||
RetainProps: retainProps,
|
||||
RemoveProps: removeProps,
|
||||
}
|
||||
|
||||
c.PostId = p.Id
|
||||
if p.RootId == "" {
|
||||
c.RootPostId = p.Id
|
||||
} else {
|
||||
c.RootPostId = p.RootId
|
||||
}
|
||||
|
||||
b, _ := json.Marshal(c)
|
||||
action.Cookie, _ = encryptPostActionCookie(string(b), secret)
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func encryptPostActionCookie(plain string, secret []byte) (string, error) {
|
||||
if len(secret) == 0 {
|
||||
return plain, nil
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
nonce := make([]byte, aesgcm.NonceSize())
|
||||
_, err = io.ReadFull(rand.Reader, nonce)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sealed := aesgcm.Seal(nil, nonce, []byte(plain), nil)
|
||||
|
||||
combined := append(nonce, sealed...)
|
||||
encoded := make([]byte, base64.StdEncoding.EncodedLen(len(combined)))
|
||||
base64.StdEncoding.Encode(encoded, combined)
|
||||
|
||||
return string(encoded), nil
|
||||
}
|
||||
|
||||
func DecryptPostActionCookie(encoded string, secret []byte) (string, error) {
|
||||
if len(secret) == 0 {
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
decoded := make([]byte, base64.StdEncoding.DecodedLen(len(encoded)))
|
||||
n, err := base64.StdEncoding.Decode(decoded, []byte(encoded))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
decoded = decoded[:n]
|
||||
|
||||
nonceSize := aesgcm.NonceSize()
|
||||
if len(decoded) < nonceSize {
|
||||
return "", fmt.Errorf("cookie too short")
|
||||
}
|
||||
|
||||
nonce, decoded := decoded[:nonceSize], decoded[nonceSize:]
|
||||
plain, err := aesgcm.Open(nil, nonce, decoded, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(plain), nil
|
||||
}
|
||||
|
||||
func DoPostActionRequestFromJson(data io.Reader) *DoPostActionRequest {
|
||||
var o *DoPostActionRequest
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -15,8 +15,10 @@ const (
|
||||
JOB_TYPE_MESSAGE_EXPORT = "message_export"
|
||||
JOB_TYPE_ELASTICSEARCH_POST_INDEXING = "elasticsearch_post_indexing"
|
||||
JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION = "elasticsearch_post_aggregation"
|
||||
JOB_TYPE_BLEVE_POST_INDEXING = "bleve_post_indexing"
|
||||
JOB_TYPE_LDAP_SYNC = "ldap_sync"
|
||||
JOB_TYPE_MIGRATIONS = "migrations"
|
||||
JOB_TYPE_PLUGINS = "plugins"
|
||||
|
||||
JOB_STATUS_PENDING = "pending"
|
||||
JOB_STATUS_IN_PROGRESS = "in_progress"
|
||||
@ -24,6 +26,7 @@ const (
|
||||
JOB_STATUS_ERROR = "error"
|
||||
JOB_STATUS_CANCEL_REQUESTED = "cancel_requested"
|
||||
JOB_STATUS_CANCELED = "canceled"
|
||||
JOB_STATUS_WARNING = "warning"
|
||||
)
|
||||
|
||||
type Job struct {
|
||||
@ -39,7 +42,7 @@ type Job struct {
|
||||
}
|
||||
|
||||
func (j *Job) IsValid() *AppError {
|
||||
if len(j.Id) != 26 {
|
||||
if !IsValidId(j.Id) {
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.id.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -51,9 +54,11 @@ func (j *Job) IsValid() *AppError {
|
||||
case JOB_TYPE_DATA_RETENTION:
|
||||
case JOB_TYPE_ELASTICSEARCH_POST_INDEXING:
|
||||
case JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION:
|
||||
case JOB_TYPE_BLEVE_POST_INDEXING:
|
||||
case JOB_TYPE_LDAP_SYNC:
|
||||
case JOB_TYPE_MESSAGE_EXPORT:
|
||||
case JOB_TYPE_MIGRATIONS:
|
||||
case JOB_TYPE_PLUGINS:
|
||||
default:
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.type.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
@ -72,8 +77,8 @@ func (j *Job) IsValid() *AppError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (js *Job) ToJson() string {
|
||||
b, _ := json.Marshal(js)
|
||||
func (j *Job) ToJson() string {
|
||||
b, _ := json.Marshal(j)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
@ -100,8 +105,8 @@ func JobsFromJson(data io.Reader) []*Job {
|
||||
}
|
||||
}
|
||||
|
||||
func (js *Job) DataToJson() string {
|
||||
b, _ := json.Marshal(js.Data)
|
||||
func (j *Job) DataToJson() string {
|
||||
b, _ := json.Marshal(j.Data)
|
||||
return string(b)
|
||||
}
|
||||
|
8
vendor/github.com/mattermost/mattermost-server/v5/model/ldap.go
generated
vendored
Normal file
8
vendor/github.com/mattermost/mattermost-server/v5/model/ldap.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_LDAP = "ldap"
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -12,6 +12,8 @@ import (
|
||||
const (
|
||||
EXPIRED_LICENSE_ERROR = "api.license.add_license.expired.app_error"
|
||||
INVALID_LICENSE_ERROR = "api.license.add_license.invalid.app_error"
|
||||
LICENSE_GRACE_PERIOD = 1000 * 60 * 60 * 24 * 10 //10 days
|
||||
LICENSE_RENEWAL_LINK = "https://licensing.mattermost.com/renew"
|
||||
)
|
||||
|
||||
type LicenseRecord struct {
|
||||
@ -21,25 +23,43 @@ type LicenseRecord struct {
|
||||
}
|
||||
|
||||
type License struct {
|
||||
Id string `json:"id"`
|
||||
IssuedAt int64 `json:"issued_at"`
|
||||
StartsAt int64 `json:"starts_at"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
Customer *Customer `json:"customer"`
|
||||
Features *Features `json:"features"`
|
||||
Id string `json:"id"`
|
||||
IssuedAt int64 `json:"issued_at"`
|
||||
StartsAt int64 `json:"starts_at"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
Customer *Customer `json:"customer"`
|
||||
Features *Features `json:"features"`
|
||||
SkuName string `json:"sku_name"`
|
||||
SkuShortName string `json:"sku_short_name"`
|
||||
}
|
||||
|
||||
type Customer struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Company string `json:"company"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Company string `json:"company"`
|
||||
}
|
||||
|
||||
type TrialLicenseRequest struct {
|
||||
ServerID string `json:"server_id"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
SiteURL string `json:"site_url"`
|
||||
SiteName string `json:"site_name"`
|
||||
Users int `json:"users"`
|
||||
TermsAccepted bool `json:"terms_accepted"`
|
||||
ReceiveEmailsAccepted bool `json:"receive_emails_accepted"`
|
||||
}
|
||||
|
||||
func (tlr *TrialLicenseRequest) ToJson() string {
|
||||
b, _ := json.Marshal(tlr)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
type Features struct {
|
||||
Users *int `json:"users"`
|
||||
LDAP *bool `json:"ldap"`
|
||||
LDAPGroups *bool `json:"ldap_groups"`
|
||||
MFA *bool `json:"mfa"`
|
||||
GoogleOAuth *bool `json:"google_oauth"`
|
||||
Office365OAuth *bool `json:"office365_oauth"`
|
||||
@ -56,14 +76,20 @@ type Features struct {
|
||||
MessageExport *bool `json:"message_export"`
|
||||
CustomPermissionsSchemes *bool `json:"custom_permissions_schemes"`
|
||||
CustomTermsOfService *bool `json:"custom_terms_of_service"`
|
||||
GuestAccounts *bool `json:"guest_accounts"`
|
||||
GuestAccountsPermissions *bool `json:"guest_accounts_permissions"`
|
||||
IDLoadedPushNotifications *bool `json:"id_loaded"`
|
||||
LockTeammateNameDisplay *bool `json:"lock_teammate_name_display"`
|
||||
EnterprisePlugins *bool `json:"enterprise_plugins"`
|
||||
|
||||
// after we enabled more features for webrtc we'll need to control them with this
|
||||
// after we enabled more features we'll need to control them with this
|
||||
FutureFeatures *bool `json:"future_features"`
|
||||
}
|
||||
|
||||
func (f *Features) ToMap() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"ldap": *f.LDAP,
|
||||
"ldap_groups": *f.LDAPGroups,
|
||||
"mfa": *f.MFA,
|
||||
"google": *f.GoogleOAuth,
|
||||
"office365": *f.Office365OAuth,
|
||||
@ -77,6 +103,11 @@ func (f *Features) ToMap() map[string]interface{} {
|
||||
"data_retention": *f.DataRetention,
|
||||
"message_export": *f.MessageExport,
|
||||
"custom_permissions_schemes": *f.CustomPermissionsSchemes,
|
||||
"guest_accounts": *f.GuestAccounts,
|
||||
"guest_accounts_permissions": *f.GuestAccountsPermissions,
|
||||
"id_loaded": *f.IDLoadedPushNotifications,
|
||||
"lock_teammate_name_display": *f.LockTeammateNameDisplay,
|
||||
"enterprise_plugins": *f.EnterprisePlugins,
|
||||
"future": *f.FutureFeatures,
|
||||
}
|
||||
}
|
||||
@ -94,6 +125,10 @@ func (f *Features) SetDefaults() {
|
||||
f.LDAP = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.LDAPGroups == nil {
|
||||
f.LDAPGroups = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.MFA == nil {
|
||||
f.MFA = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
@ -154,15 +189,40 @@ func (f *Features) SetDefaults() {
|
||||
f.CustomPermissionsSchemes = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.GuestAccounts == nil {
|
||||
f.GuestAccounts = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.GuestAccountsPermissions == nil {
|
||||
f.GuestAccountsPermissions = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.CustomTermsOfService == nil {
|
||||
f.CustomTermsOfService = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.IDLoadedPushNotifications == nil {
|
||||
f.IDLoadedPushNotifications = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.LockTeammateNameDisplay == nil {
|
||||
f.LockTeammateNameDisplay = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.EnterprisePlugins == nil {
|
||||
f.EnterprisePlugins = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *License) IsExpired() bool {
|
||||
return l.ExpiresAt < GetMillis()
|
||||
}
|
||||
|
||||
func (l *License) IsPastGracePeriod() bool {
|
||||
timeDiff := GetMillis() - l.ExpiresAt
|
||||
return timeDiff > LICENSE_GRACE_PERIOD
|
||||
}
|
||||
|
||||
func (l *License) IsStarted() bool {
|
||||
return l.StartsAt < GetMillis()
|
||||
}
|
||||
@ -198,7 +258,7 @@ func LicenseFromJson(data io.Reader) *License {
|
||||
}
|
||||
|
||||
func (lr *LicenseRecord) IsValid() *AppError {
|
||||
if len(lr.Id) != 26 {
|
||||
if !IsValidId(lr.Id) {
|
||||
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
193
vendor/github.com/mattermost/mattermost-server/v5/model/link_metadata.go
generated
vendored
Normal file
193
vendor/github.com/mattermost/mattermost-server/v5/model/link_metadata.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"net/http"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/dyatlov/go-opengraph/opengraph"
|
||||
)
|
||||
|
||||
const (
|
||||
LINK_METADATA_TYPE_IMAGE LinkMetadataType = "image"
|
||||
LINK_METADATA_TYPE_NONE LinkMetadataType = "none"
|
||||
LINK_METADATA_TYPE_OPENGRAPH LinkMetadataType = "opengraph"
|
||||
MAX_IMAGES int = 5
|
||||
)
|
||||
|
||||
type LinkMetadataType string
|
||||
|
||||
// LinkMetadata stores arbitrary data about a link posted in a message. This includes dimensions of linked images
|
||||
// and OpenGraph metadata.
|
||||
type LinkMetadata struct {
|
||||
// Hash is a value computed from the URL and Timestamp for use as a primary key in the database.
|
||||
Hash int64
|
||||
|
||||
URL string
|
||||
Timestamp int64
|
||||
Type LinkMetadataType
|
||||
|
||||
// Data is the actual metadata for the link. It should contain data of one of the following types:
|
||||
// - *model.PostImage if the linked content is an image
|
||||
// - *opengraph.OpenGraph if the linked content is an HTML document
|
||||
// - nil if the linked content has no metadata
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
// truncateText ensure string is 300 chars, truncate and add ellipsis
|
||||
// if it was bigger.
|
||||
func truncateText(original string) string {
|
||||
if utf8.RuneCountInString(original) > 300 {
|
||||
return fmt.Sprintf("%.300s[...]", original)
|
||||
}
|
||||
return original
|
||||
}
|
||||
|
||||
func firstNImages(images []*opengraph.Image, maxImages int) []*opengraph.Image {
|
||||
if maxImages < 0 { // dont break stuff, if it's weird, go for sane defaults
|
||||
maxImages = MAX_IMAGES
|
||||
}
|
||||
numImages := len(images)
|
||||
if numImages > maxImages {
|
||||
return images[0:maxImages]
|
||||
}
|
||||
return images
|
||||
}
|
||||
|
||||
// TruncateOpenGraph ensure OpenGraph metadata doesn't grow too big by
|
||||
// shortening strings, trimming fields and reducing the number of
|
||||
// images.
|
||||
func TruncateOpenGraph(ogdata *opengraph.OpenGraph) *opengraph.OpenGraph {
|
||||
if ogdata != nil {
|
||||
empty := &opengraph.OpenGraph{}
|
||||
ogdata.Title = truncateText(ogdata.Title)
|
||||
ogdata.Description = truncateText(ogdata.Description)
|
||||
ogdata.SiteName = truncateText(ogdata.SiteName)
|
||||
ogdata.Article = empty.Article
|
||||
ogdata.Book = empty.Book
|
||||
ogdata.Profile = empty.Profile
|
||||
ogdata.Determiner = empty.Determiner
|
||||
ogdata.Locale = empty.Locale
|
||||
ogdata.LocalesAlternate = empty.LocalesAlternate
|
||||
ogdata.Images = firstNImages(ogdata.Images, MAX_IMAGES)
|
||||
ogdata.Audios = empty.Audios
|
||||
ogdata.Videos = empty.Videos
|
||||
}
|
||||
return ogdata
|
||||
}
|
||||
|
||||
func (o *LinkMetadata) PreSave() {
|
||||
o.Hash = GenerateLinkMetadataHash(o.URL, o.Timestamp)
|
||||
}
|
||||
|
||||
func (o *LinkMetadata) IsValid() *AppError {
|
||||
if o.URL == "" {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.url.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.Timestamp == 0 || !isRoundedToNearestHour(o.Timestamp) {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.timestamp.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch o.Type {
|
||||
case LINK_METADATA_TYPE_IMAGE:
|
||||
if o.Data == nil {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.data.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if _, ok := o.Data.(*PostImage); !ok {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.data_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
case LINK_METADATA_TYPE_NONE:
|
||||
if o.Data != nil {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.data_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
case LINK_METADATA_TYPE_OPENGRAPH:
|
||||
if o.Data == nil {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.data.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if _, ok := o.Data.(*opengraph.OpenGraph); !ok {
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.data_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
default:
|
||||
return NewAppError("LinkMetadata.IsValid", "model.link_metadata.is_valid.type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeserializeDataToConcreteType converts o.Data from JSON into properly structured data. This is intended to be used
|
||||
// after getting a LinkMetadata object that has been stored in the database.
|
||||
func (o *LinkMetadata) DeserializeDataToConcreteType() error {
|
||||
var b []byte
|
||||
switch t := o.Data.(type) {
|
||||
case []byte:
|
||||
// MySQL uses a byte slice for JSON
|
||||
b = t
|
||||
case string:
|
||||
// Postgres uses a string for JSON
|
||||
b = []byte(t)
|
||||
}
|
||||
|
||||
if b == nil {
|
||||
// Data doesn't need to be fixed
|
||||
return nil
|
||||
}
|
||||
|
||||
var data interface{}
|
||||
var err error
|
||||
|
||||
switch o.Type {
|
||||
case LINK_METADATA_TYPE_IMAGE:
|
||||
image := &PostImage{}
|
||||
|
||||
err = json.Unmarshal(b, &image)
|
||||
|
||||
data = image
|
||||
case LINK_METADATA_TYPE_OPENGRAPH:
|
||||
og := &opengraph.OpenGraph{}
|
||||
|
||||
json.Unmarshal(b, &og)
|
||||
|
||||
data = og
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.Data = data
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FloorToNearestHour takes a timestamp (in milliseconds) and returns it rounded to the previous hour in UTC.
|
||||
func FloorToNearestHour(ms int64) int64 {
|
||||
t := time.Unix(0, ms*int64(1000*1000))
|
||||
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), 0, 0, 0, t.Location()).UnixNano() / int64(time.Millisecond)
|
||||
}
|
||||
|
||||
// isRoundedToNearestHour returns true if the given timestamp (in milliseconds) has been rounded to the nearest hour in UTC.
|
||||
func isRoundedToNearestHour(ms int64) bool {
|
||||
return FloorToNearestHour(ms) == ms
|
||||
}
|
||||
|
||||
// GenerateLinkMetadataHash generates a unique hash for a given URL and timestamp for use as a database key.
|
||||
func GenerateLinkMetadataHash(url string, timestamp int64) int64 {
|
||||
hash := fnv.New32()
|
||||
|
||||
// Note that we ignore write errors here because the Hash interface says that its Write will never return an error
|
||||
binary.Write(hash, binary.LittleEndian, timestamp)
|
||||
hash.Write([]byte(url))
|
||||
|
||||
return int64(hash.Sum32())
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -12,6 +12,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
@ -23,6 +25,20 @@ type PluginOption struct {
|
||||
Value string `json:"value" yaml:"value"`
|
||||
}
|
||||
|
||||
type PluginSettingType int
|
||||
|
||||
const (
|
||||
Bool PluginSettingType = iota
|
||||
Dropdown
|
||||
Generated
|
||||
Radio
|
||||
Text
|
||||
LongText
|
||||
Number
|
||||
Username
|
||||
Custom
|
||||
)
|
||||
|
||||
type PluginSetting struct {
|
||||
// The key that the setting will be assigned to in the configuration file.
|
||||
Key string `json:"key" yaml:"key"`
|
||||
@ -45,16 +61,22 @@ type PluginSetting struct {
|
||||
//
|
||||
// "text" will result in a string setting that can be typed in manually.
|
||||
//
|
||||
// "longtext" will result in a multi line string that can be typed in manually.
|
||||
//
|
||||
// "number" will result in in integer setting that can be typed in manually.
|
||||
//
|
||||
// "username" will result in a text setting that will autocomplete to a username.
|
||||
//
|
||||
// "custom" will result in a custom defined setting and will load the custom component registered for the Web App System Console.
|
||||
Type string `json:"type" yaml:"type"`
|
||||
|
||||
// The help text to display to the user.
|
||||
// The help text to display to the user. Supports Markdown formatting.
|
||||
HelpText string `json:"help_text" yaml:"help_text"`
|
||||
|
||||
// The help text to display alongside the "Regenerate" button for settings of the "generated" type.
|
||||
RegenerateHelpText string `json:"regenerate_help_text,omitempty" yaml:"regenerate_help_text,omitempty"`
|
||||
|
||||
// The placeholder to display for "text", "generated" and "username" types when blank.
|
||||
// The placeholder to display for "generated", "text", "longtext", "number" and "username" types when blank.
|
||||
Placeholder string `json:"placeholder" yaml:"placeholder"`
|
||||
|
||||
// The default value of the setting.
|
||||
@ -66,10 +88,10 @@ type PluginSetting struct {
|
||||
}
|
||||
|
||||
type PluginSettingsSchema struct {
|
||||
// Optional text to display above the settings.
|
||||
// Optional text to display above the settings. Supports Markdown formatting.
|
||||
Header string `json:"header" yaml:"header"`
|
||||
|
||||
// Optional text to display below the settings.
|
||||
// Optional text to display below the settings. Supports Markdown formatting.
|
||||
Footer string `json:"footer" yaml:"footer"`
|
||||
|
||||
// A list of setting definitions.
|
||||
@ -80,20 +102,44 @@ type PluginSettingsSchema struct {
|
||||
// file should be named plugin.json or plugin.yaml and placed in the top of your
|
||||
// plugin bundle.
|
||||
//
|
||||
// Example plugin.yaml:
|
||||
// Example plugin.json:
|
||||
//
|
||||
// id: com.mycompany.myplugin
|
||||
// name: My Plugin
|
||||
// description: This is my plugin. It does stuff.
|
||||
// server:
|
||||
// executable: myplugin
|
||||
// settings_schema:
|
||||
// settings:
|
||||
// - key: enable_extra_thing
|
||||
// type: bool
|
||||
// display_name: Enable Extra Thing
|
||||
// help_text: When true, an extra thing will be enabled!
|
||||
// default: false
|
||||
//
|
||||
// {
|
||||
// "id": "com.mycompany.myplugin",
|
||||
// "name": "My Plugin",
|
||||
// "description": "This is my plugin",
|
||||
// "homepage_url": "https://example.com",
|
||||
// "support_url": "https://example.com/support",
|
||||
// "release_notes_url": "https://example.com/releases/v0.0.1",
|
||||
// "icon_path": "assets/logo.svg",
|
||||
// "version": "0.1.0",
|
||||
// "min_server_version": "5.6.0",
|
||||
// "server": {
|
||||
// "executables": {
|
||||
// "linux-amd64": "server/dist/plugin-linux-amd64",
|
||||
// "darwin-amd64": "server/dist/plugin-darwin-amd64",
|
||||
// "windows-amd64": "server/dist/plugin-windows-amd64.exe"
|
||||
// }
|
||||
// },
|
||||
// "webapp": {
|
||||
// "bundle_path": "webapp/dist/main.js"
|
||||
// },
|
||||
// "settings_schema": {
|
||||
// "header": "Some header text",
|
||||
// "footer": "Some footer text",
|
||||
// "settings": [{
|
||||
// "key": "someKey",
|
||||
// "display_name": "Enable Extra Feature",
|
||||
// "type": "bool",
|
||||
// "help_text": "When true, an extra feature will be enabled!",
|
||||
// "default": "false"
|
||||
// }]
|
||||
// },
|
||||
// "props": {
|
||||
// "someKey": "someData"
|
||||
// }
|
||||
// }
|
||||
type Manifest struct {
|
||||
// The id is a globally unique identifier that represents your plugin. Ids must be at least
|
||||
// 3 characters, at most 190 characters and must match ^[a-zA-Z0-9-_\.]+$.
|
||||
@ -106,9 +152,27 @@ type Manifest struct {
|
||||
// A description of what your plugin is and does.
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
|
||||
// HomepageURL is an optional link to learn more about the plugin.
|
||||
HomepageURL string `json:"homepage_url,omitempty" yaml:"homepage_url,omitempty"`
|
||||
|
||||
// SupportURL is an optional URL where plugin issues can be reported.
|
||||
SupportURL string `json:"support_url,omitempty" yaml:"support_url,omitempty"`
|
||||
|
||||
// ReleaseNotesURL is an optional URL where a changelog for the release can be found.
|
||||
ReleaseNotesURL string `json:"release_notes_url,omitempty" yaml:"release_notes_url,omitempty"`
|
||||
|
||||
// A relative file path in the bundle that points to the plugins svg icon for use with the Plugin Marketplace.
|
||||
// This should be relative to the root of your bundle and the location of the manifest file. Bitmap image formats are not supported.
|
||||
IconPath string `json:"icon_path,omitempty" yaml:"icon_path,omitempty"`
|
||||
|
||||
// A version number for your plugin. Semantic versioning is recommended: http://semver.org
|
||||
Version string `json:"version" yaml:"version"`
|
||||
|
||||
// The minimum Mattermost server version required for your plugin.
|
||||
//
|
||||
// Minimum server version: 5.6
|
||||
MinServerVersion string `json:"min_server_version,omitempty" yaml:"min_server_version,omitempty"`
|
||||
|
||||
// Server defines the server-side portion of your plugin.
|
||||
Server *ManifestServer `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
|
||||
@ -121,6 +185,14 @@ type Manifest struct {
|
||||
// To allow administrators to configure your plugin via the Mattermost system console, you can
|
||||
// provide your settings schema.
|
||||
SettingsSchema *PluginSettingsSchema `json:"settings_schema,omitempty" yaml:"settings_schema,omitempty"`
|
||||
|
||||
// Plugins can store any kind of data in Props to allow other plugins to use it.
|
||||
Props map[string]interface{} `json:"props,omitempty" yaml:"props,omitempty"`
|
||||
|
||||
// RequiredConfig defines any required server configuration fields for the plugin to function properly.
|
||||
//
|
||||
// Use the plugin helpers CheckRequiredServerConfiguration method to enforce this.
|
||||
RequiredConfig *Config `json:"required_configuration,omitempty" yaml:"required_configuration,omitempty"`
|
||||
}
|
||||
|
||||
type ManifestServer struct {
|
||||
@ -240,6 +312,129 @@ func (m *Manifest) HasWebapp() bool {
|
||||
return m.Webapp != nil
|
||||
}
|
||||
|
||||
func (m *Manifest) MeetMinServerVersion(serverVersion string) (bool, error) {
|
||||
minServerVersion, err := semver.Parse(m.MinServerVersion)
|
||||
if err != nil {
|
||||
return false, errors.New("failed to parse MinServerVersion")
|
||||
}
|
||||
sv := semver.MustParse(serverVersion)
|
||||
if sv.LT(minServerVersion) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (m *Manifest) IsValid() error {
|
||||
if !IsValidPluginId(m.Id) {
|
||||
return errors.New("invalid plugin ID")
|
||||
}
|
||||
|
||||
if m.HomepageURL != "" && !IsValidHttpUrl(m.HomepageURL) {
|
||||
return errors.New("invalid HomepageURL")
|
||||
}
|
||||
|
||||
if m.SupportURL != "" && !IsValidHttpUrl(m.SupportURL) {
|
||||
return errors.New("invalid SupportURL")
|
||||
}
|
||||
|
||||
if m.ReleaseNotesURL != "" && !IsValidHttpUrl(m.ReleaseNotesURL) {
|
||||
return errors.New("invalid ReleaseNotesURL")
|
||||
}
|
||||
|
||||
if m.Version != "" {
|
||||
_, err := semver.Parse(m.Version)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse Version")
|
||||
}
|
||||
}
|
||||
|
||||
if m.MinServerVersion != "" {
|
||||
_, err := semver.Parse(m.MinServerVersion)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse MinServerVersion")
|
||||
}
|
||||
}
|
||||
|
||||
if m.SettingsSchema != nil {
|
||||
err := m.SettingsSchema.isValid()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid settings schema")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PluginSettingsSchema) isValid() error {
|
||||
for _, setting := range s.Settings {
|
||||
err := setting.isValid()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PluginSetting) isValid() error {
|
||||
pluginSettingType, err := convertTypeToPluginSettingType(s.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.RegenerateHelpText != "" && pluginSettingType != Generated {
|
||||
return errors.New("should not set RegenerateHelpText for setting type that is not generated")
|
||||
}
|
||||
|
||||
if s.Placeholder != "" && !(pluginSettingType == Generated ||
|
||||
pluginSettingType == Text ||
|
||||
pluginSettingType == LongText ||
|
||||
pluginSettingType == Number ||
|
||||
pluginSettingType == Username) {
|
||||
return errors.New("should not set Placeholder for setting type not in text, generated or username")
|
||||
}
|
||||
|
||||
if s.Options != nil {
|
||||
if pluginSettingType != Radio && pluginSettingType != Dropdown {
|
||||
return errors.New("should not set Options for setting type not in radio or dropdown")
|
||||
}
|
||||
|
||||
for _, option := range s.Options {
|
||||
if option.DisplayName == "" || option.Value == "" {
|
||||
return errors.New("should not have empty Displayname or Value for any option")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertTypeToPluginSettingType(t string) (PluginSettingType, error) {
|
||||
var settingType PluginSettingType
|
||||
switch t {
|
||||
case "bool":
|
||||
return Bool, nil
|
||||
case "dropdown":
|
||||
return Dropdown, nil
|
||||
case "generated":
|
||||
return Generated, nil
|
||||
case "radio":
|
||||
return Radio, nil
|
||||
case "text":
|
||||
return Text, nil
|
||||
case "number":
|
||||
return Number, nil
|
||||
case "longtext":
|
||||
return LongText, nil
|
||||
case "username":
|
||||
return Username, nil
|
||||
case "custom":
|
||||
return Custom, nil
|
||||
default:
|
||||
return settingType, errors.New("invalid setting type: " + t)
|
||||
}
|
||||
}
|
||||
|
||||
// FindManifest will find and parse the manifest in a given directory.
|
||||
//
|
||||
// In all cases other than a does-not-exist error, path is set to the path of the manifest file that was
|
||||
@ -252,25 +447,23 @@ func FindManifest(dir string) (manifest *Manifest, path string, err error) {
|
||||
f, ferr := os.Open(path)
|
||||
if ferr != nil {
|
||||
if !os.IsNotExist(ferr) {
|
||||
err = ferr
|
||||
return
|
||||
return nil, "", ferr
|
||||
}
|
||||
continue
|
||||
}
|
||||
b, ioerr := ioutil.ReadAll(f)
|
||||
f.Close()
|
||||
if ioerr != nil {
|
||||
err = ioerr
|
||||
return
|
||||
return nil, path, ioerr
|
||||
}
|
||||
var parsed Manifest
|
||||
err = yaml.Unmarshal(b, &parsed)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, path, err
|
||||
}
|
||||
manifest = &parsed
|
||||
manifest.Id = strings.ToLower(manifest.Id)
|
||||
return
|
||||
return manifest, path, nil
|
||||
}
|
||||
|
||||
path = filepath.Join(dir, "plugin.json")
|
||||
@ -279,16 +472,15 @@ func FindManifest(dir string) (manifest *Manifest, path string, err error) {
|
||||
if os.IsNotExist(ferr) {
|
||||
path = ""
|
||||
}
|
||||
err = ferr
|
||||
return
|
||||
return nil, path, ferr
|
||||
}
|
||||
defer f.Close()
|
||||
var parsed Manifest
|
||||
err = json.NewDecoder(f).Decode(&parsed)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, path, err
|
||||
}
|
||||
manifest = &parsed
|
||||
manifest.Id = strings.ToLower(manifest.Id)
|
||||
return
|
||||
return manifest, path, nil
|
||||
}
|
124
vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go
generated
vendored
Normal file
124
vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// BaseMarketplacePlugin is a Mattermost plugin received from the Marketplace server.
|
||||
type BaseMarketplacePlugin struct {
|
||||
HomepageURL string `json:"homepage_url"`
|
||||
IconData string `json:"icon_data"`
|
||||
DownloadURL string `json:"download_url"`
|
||||
ReleaseNotesURL string `json:"release_notes_url"`
|
||||
Labels []MarketplaceLabel `json:"labels"`
|
||||
Signature string `json:"signature"` // Signature represents a signature of a plugin saved in base64 encoding.
|
||||
Manifest *Manifest `json:"manifest"`
|
||||
}
|
||||
|
||||
// MarketplaceLabel represents a label shown in the Marketplace UI.
|
||||
type MarketplaceLabel struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
// MarketplacePlugin is a state aware Marketplace plugin.
|
||||
type MarketplacePlugin struct {
|
||||
*BaseMarketplacePlugin
|
||||
InstalledVersion string `json:"installed_version"`
|
||||
}
|
||||
|
||||
// BaseMarketplacePluginsFromReader decodes a json-encoded list of plugins from the given io.Reader.
|
||||
func BaseMarketplacePluginsFromReader(reader io.Reader) ([]*BaseMarketplacePlugin, error) {
|
||||
plugins := []*BaseMarketplacePlugin{}
|
||||
decoder := json.NewDecoder(reader)
|
||||
|
||||
if err := decoder.Decode(&plugins); err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plugins, nil
|
||||
}
|
||||
|
||||
// MarketplacePluginsFromReader decodes a json-encoded list of plugins from the given io.Reader.
|
||||
func MarketplacePluginsFromReader(reader io.Reader) ([]*MarketplacePlugin, error) {
|
||||
plugins := []*MarketplacePlugin{}
|
||||
decoder := json.NewDecoder(reader)
|
||||
|
||||
if err := decoder.Decode(&plugins); err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plugins, nil
|
||||
}
|
||||
|
||||
// DecodeSignature Decodes signature and returns ReadSeeker.
|
||||
func (plugin *BaseMarketplacePlugin) DecodeSignature() (io.ReadSeeker, error) {
|
||||
signatureBytes, err := base64.StdEncoding.DecodeString(plugin.Signature)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to decode base64 signature.")
|
||||
}
|
||||
return bytes.NewReader(signatureBytes), nil
|
||||
}
|
||||
|
||||
// MarketplacePluginFilter describes the parameters to request a list of plugins.
|
||||
type MarketplacePluginFilter struct {
|
||||
Page int
|
||||
PerPage int
|
||||
Filter string
|
||||
ServerVersion string
|
||||
BuildEnterpriseReady bool
|
||||
EnterprisePlugins bool
|
||||
LocalOnly bool
|
||||
}
|
||||
|
||||
// ApplyToURL modifies the given url to include query string parameters for the request.
|
||||
func (filter *MarketplacePluginFilter) ApplyToURL(u *url.URL) {
|
||||
q := u.Query()
|
||||
q.Add("page", strconv.Itoa(filter.Page))
|
||||
if filter.PerPage > 0 {
|
||||
q.Add("per_page", strconv.Itoa(filter.PerPage))
|
||||
}
|
||||
q.Add("filter", filter.Filter)
|
||||
q.Add("server_version", filter.ServerVersion)
|
||||
q.Add("build_enterprise_ready", strconv.FormatBool(filter.BuildEnterpriseReady))
|
||||
q.Add("enterprise_plugins", strconv.FormatBool(filter.EnterprisePlugins))
|
||||
q.Add("local_only", strconv.FormatBool(filter.LocalOnly))
|
||||
u.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
// InstallMarketplacePluginRequest struct describes parameters of the requested plugin.
|
||||
type InstallMarketplacePluginRequest struct {
|
||||
Id string `json:"id"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// PluginRequestFromReader decodes a json-encoded plugin request from the given io.Reader.
|
||||
func PluginRequestFromReader(reader io.Reader) (*InstallMarketplacePluginRequest, error) {
|
||||
var r *InstallMarketplacePluginRequest
|
||||
err := json.NewDecoder(reader).Decode(&r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// ToJson method will return json from plugin request.
|
||||
func (r *InstallMarketplacePluginRequest) ToJson() (string, error) {
|
||||
b, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
80
vendor/github.com/mattermost/mattermost-server/v5/model/mention_map.go
generated
vendored
Normal file
80
vendor/github.com/mattermost/mattermost-server/v5/model/mention_map.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type UserMentionMap map[string]string
|
||||
type ChannelMentionMap map[string]string
|
||||
|
||||
const (
|
||||
userMentionsKey = "user_mentions"
|
||||
userMentionsIdsKey = "user_mentions_ids"
|
||||
channelMentionsKey = "channel_mentions"
|
||||
channelMentionsIdsKey = "channel_mentions_ids"
|
||||
)
|
||||
|
||||
func UserMentionMapFromURLValues(values url.Values) (UserMentionMap, error) {
|
||||
return mentionsFromURLValues(values, userMentionsKey, userMentionsIdsKey)
|
||||
}
|
||||
|
||||
func (m UserMentionMap) ToURLValues() url.Values {
|
||||
return mentionsToURLValues(m, userMentionsKey, userMentionsIdsKey)
|
||||
}
|
||||
|
||||
func ChannelMentionMapFromURLValues(values url.Values) (ChannelMentionMap, error) {
|
||||
return mentionsFromURLValues(values, channelMentionsKey, channelMentionsIdsKey)
|
||||
}
|
||||
|
||||
func (m ChannelMentionMap) ToURLValues() url.Values {
|
||||
return mentionsToURLValues(m, channelMentionsKey, channelMentionsIdsKey)
|
||||
}
|
||||
|
||||
func mentionsFromURLValues(values url.Values, mentionKey, idKey string) (map[string]string, error) {
|
||||
mentions, mentionsOk := values[mentionKey]
|
||||
ids, idsOk := values[idKey]
|
||||
|
||||
if !mentionsOk && !idsOk {
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
|
||||
if !mentionsOk {
|
||||
return nil, fmt.Errorf("%s key not found", mentionKey)
|
||||
}
|
||||
|
||||
if !idsOk {
|
||||
return nil, fmt.Errorf("%s key not found", idKey)
|
||||
}
|
||||
|
||||
if len(mentions) != len(ids) {
|
||||
return nil, fmt.Errorf("keys %s and %s have different length", mentionKey, idKey)
|
||||
}
|
||||
|
||||
mentionsMap := make(map[string]string)
|
||||
for i, mention := range mentions {
|
||||
id := ids[i]
|
||||
|
||||
if oldId, ok := mentionsMap[mention]; ok && oldId != id {
|
||||
return nil, fmt.Errorf("key %s has two different values: %s and %s", mention, oldId, id)
|
||||
}
|
||||
|
||||
mentionsMap[mention] = id
|
||||
}
|
||||
|
||||
return mentionsMap, nil
|
||||
}
|
||||
|
||||
func mentionsToURLValues(mentions map[string]string, mentionKey, idKey string) url.Values {
|
||||
values := url.Values{}
|
||||
|
||||
for mention, id := range mentions {
|
||||
values.Add(mentionKey, mention)
|
||||
values.Add(idKey, id)
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -16,12 +16,16 @@ type MessageExport struct {
|
||||
UserId *string
|
||||
UserEmail *string
|
||||
Username *string
|
||||
IsBot bool
|
||||
|
||||
PostId *string
|
||||
PostCreateAt *int64
|
||||
PostUpdateAt *int64
|
||||
PostDeleteAt *int64
|
||||
PostMessage *string
|
||||
PostType *string
|
||||
PostRootId *string
|
||||
PostProps *string
|
||||
PostOriginalId *string
|
||||
PostFileIds StringArray
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
20
vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
generated
vendored
Normal file
20
vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2 = "migration_advanced_permissions_phase_2"
|
||||
|
||||
MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split"
|
||||
MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_permissions_split"
|
||||
MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS = "list_join_public_private_teams"
|
||||
MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER = "remove_permanent_delete_user"
|
||||
MIGRATION_KEY_ADD_BOT_PERMISSIONS = "add_bot_permissions"
|
||||
MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER = "apply_channel_manage_delete_to_channel_user"
|
||||
MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER = "remove_channel_manage_delete_from_team_user"
|
||||
MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION = "view_members_new_permission"
|
||||
MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS = "add_manage_guests_permissions"
|
||||
MIGRATION_KEY_CHANNEL_MODERATIONS_PERMISSIONS = "channel_moderations_permissions"
|
||||
MIGRATION_KEY_ADD_USE_GROUP_MENTIONS_PERMISSION = "add_use_group_mentions_permission"
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -17,7 +17,6 @@ const (
|
||||
OAUTH_ACTION_EMAIL_TO_SSO = "email_to_sso"
|
||||
OAUTH_ACTION_SSO_TO_EMAIL = "sso_to_email"
|
||||
OAUTH_ACTION_MOBILE = "mobile"
|
||||
OAUTH_ACTION_CLIENT = "client"
|
||||
)
|
||||
|
||||
type OAuthApp struct {
|
||||
@ -38,7 +37,7 @@ type OAuthApp struct {
|
||||
// correctly.
|
||||
func (a *OAuthApp) IsValid() *AppError {
|
||||
|
||||
if len(a.Id) != 26 {
|
||||
if !IsValidId(a.Id) {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.app_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -50,7 +49,7 @@ func (a *OAuthApp) IsValid() *AppError {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.update_at.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(a.CreatorId) != 26 {
|
||||
if !IsValidId(a.CreatorId) {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.creator_id.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -109,15 +109,15 @@ func (o *OutgoingWebhookResponse) ToJson() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func OutgoingWebhookResponseFromJson(data io.Reader) *OutgoingWebhookResponse {
|
||||
func OutgoingWebhookResponseFromJson(data io.Reader) (*OutgoingWebhookResponse, error) {
|
||||
var o *OutgoingWebhookResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
return o, err
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) IsValid() *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -133,15 +133,15 @@ func (o *OutgoingWebhook) IsValid() *AppError {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) != 26 {
|
||||
if !IsValidId(o.CreatorId) {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 0 && len(o.ChannelId) != 26 {
|
||||
if len(o.ChannelId) != 0 && !IsValidId(o.ChannelId) {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
if !IsValidId(o.TeamId) {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -33,6 +33,10 @@ var PERMISSION_CREATE_DIRECT_CHANNEL *Permission
|
||||
var PERMISSION_CREATE_GROUP_CHANNEL *Permission
|
||||
var PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES *Permission
|
||||
var PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES *Permission
|
||||
var PERMISSION_LIST_PUBLIC_TEAMS *Permission
|
||||
var PERMISSION_JOIN_PUBLIC_TEAMS *Permission
|
||||
var PERMISSION_LIST_PRIVATE_TEAMS *Permission
|
||||
var PERMISSION_JOIN_PRIVATE_TEAMS *Permission
|
||||
var PERMISSION_LIST_TEAM_CHANNELS *Permission
|
||||
var PERMISSION_JOIN_PUBLIC_CHANNELS *Permission
|
||||
var PERMISSION_DELETE_PUBLIC_CHANNEL *Permission
|
||||
@ -48,10 +52,17 @@ var PERMISSION_UPLOAD_FILE *Permission
|
||||
var PERMISSION_GET_PUBLIC_LINK *Permission
|
||||
var PERMISSION_MANAGE_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_INCOMING_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OUTGOING_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OAUTH *Permission
|
||||
var PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH *Permission
|
||||
var PERMISSION_MANAGE_EMOJIS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_EMOJIS *Permission
|
||||
var PERMISSION_CREATE_EMOJIS *Permission
|
||||
var PERMISSION_DELETE_EMOJIS *Permission
|
||||
var PERMISSION_DELETE_OTHERS_EMOJIS *Permission
|
||||
var PERMISSION_CREATE_POST *Permission
|
||||
var PERMISSION_CREATE_POST_PUBLIC *Permission
|
||||
var PERMISSION_CREATE_POST_EPHEMERAL *Permission
|
||||
@ -69,6 +80,18 @@ var PERMISSION_MANAGE_JOBS *Permission
|
||||
var PERMISSION_CREATE_USER_ACCESS_TOKEN *Permission
|
||||
var PERMISSION_READ_USER_ACCESS_TOKEN *Permission
|
||||
var PERMISSION_REVOKE_USER_ACCESS_TOKEN *Permission
|
||||
var PERMISSION_CREATE_BOT *Permission
|
||||
var PERMISSION_ASSIGN_BOT *Permission
|
||||
var PERMISSION_READ_BOTS *Permission
|
||||
var PERMISSION_READ_OTHERS_BOTS *Permission
|
||||
var PERMISSION_MANAGE_BOTS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_BOTS *Permission
|
||||
var PERMISSION_VIEW_MEMBERS *Permission
|
||||
var PERMISSION_INVITE_GUEST *Permission
|
||||
var PERMISSION_PROMOTE_GUEST *Permission
|
||||
var PERMISSION_DEMOTE_TO_GUEST *Permission
|
||||
var PERMISSION_USE_CHANNEL_MENTIONS *Permission
|
||||
var PERMISSION_USE_GROUP_MENTIONS *Permission
|
||||
|
||||
// General permission that encompasses all system admin functions
|
||||
// in the future this could be broken up to allow access to some
|
||||
@ -77,6 +100,9 @@ var PERMISSION_MANAGE_SYSTEM *Permission
|
||||
|
||||
var ALL_PERMISSIONS []*Permission
|
||||
|
||||
var CHANNEL_MODERATED_PERMISSIONS []string
|
||||
var CHANNEL_MODERATED_PERMISSIONS_MAP map[string]string
|
||||
|
||||
func initializePermissions() {
|
||||
PERMISSION_INVITE_USER = &Permission{
|
||||
"invite_user",
|
||||
@ -186,6 +212,30 @@ func initializePermissions() {
|
||||
"authentication.permissions.manage_private_channel_properties.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_LIST_PUBLIC_TEAMS = &Permission{
|
||||
"list_public_teams",
|
||||
"authentication.permissions.list_public_teams.name",
|
||||
"authentication.permissions.list_public_teams.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_JOIN_PUBLIC_TEAMS = &Permission{
|
||||
"join_public_teams",
|
||||
"authentication.permissions.join_public_teams.name",
|
||||
"authentication.permissions.join_public_teams.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_LIST_PRIVATE_TEAMS = &Permission{
|
||||
"list_private_teams",
|
||||
"authentication.permissions.list_private_teams.name",
|
||||
"authentication.permissions.list_private_teams.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS = &Permission{
|
||||
"join_private_teams",
|
||||
"authentication.permissions.join_private_teams.name",
|
||||
"authentication.permissions.join_private_teams.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_LIST_TEAM_CHANNELS = &Permission{
|
||||
"list_team_channels",
|
||||
"authentication.permissions.list_team_channels.name",
|
||||
@ -246,6 +296,7 @@ func initializePermissions() {
|
||||
"authentication.permissions.remove_others_reactions.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
// DEPRECATED
|
||||
PERMISSION_PERMANENT_DELETE_USER = &Permission{
|
||||
"permanent_delete_user",
|
||||
"authentication.permissions.permanent_delete_user.name",
|
||||
@ -264,18 +315,44 @@ func initializePermissions() {
|
||||
"authentication.permissions.get_public_link.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
// DEPRECATED
|
||||
PERMISSION_MANAGE_WEBHOOKS = &Permission{
|
||||
"manage_webhooks",
|
||||
"authentication.permissions.manage_webhooks.name",
|
||||
"authentication.permissions.manage_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
// DEPRECATED
|
||||
PERMISSION_MANAGE_OTHERS_WEBHOOKS = &Permission{
|
||||
"manage_others_webhooks",
|
||||
"authentication.permissions.manage_others_webhooks.name",
|
||||
"authentication.permissions.manage_others_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_INCOMING_WEBHOOKS = &Permission{
|
||||
"manage_incoming_webhooks",
|
||||
"authentication.permissions.manage_incoming_webhooks.name",
|
||||
"authentication.permissions.manage_incoming_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OUTGOING_WEBHOOKS = &Permission{
|
||||
"manage_outgoing_webhooks",
|
||||
"authentication.permissions.manage_outgoing_webhooks.name",
|
||||
"authentication.permissions.manage_outgoing_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS = &Permission{
|
||||
"manage_others_incoming_webhooks",
|
||||
"authentication.permissions.manage_others_incoming_webhooks.name",
|
||||
"authentication.permissions.manage_others_incoming_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS = &Permission{
|
||||
"manage_others_outgoing_webhooks",
|
||||
"authentication.permissions.manage_others_outgoing_webhooks.name",
|
||||
"authentication.permissions.manage_others_outgoing_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OAUTH = &Permission{
|
||||
"manage_oauth",
|
||||
"authentication.permissions.manage_oauth.name",
|
||||
@ -288,18 +365,38 @@ func initializePermissions() {
|
||||
"authentication.permissions.manage_system_wide_oauth.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
// DEPRECATED
|
||||
PERMISSION_MANAGE_EMOJIS = &Permission{
|
||||
"manage_emojis",
|
||||
"authentication.permissions.manage_emojis.name",
|
||||
"authentication.permissions.manage_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
// DEPRECATED
|
||||
PERMISSION_MANAGE_OTHERS_EMOJIS = &Permission{
|
||||
"manage_others_emojis",
|
||||
"authentication.permissions.manage_others_emojis.name",
|
||||
"authentication.permissions.manage_others_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_CREATE_EMOJIS = &Permission{
|
||||
"create_emojis",
|
||||
"authentication.permissions.create_emojis.name",
|
||||
"authentication.permissions.create_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_DELETE_EMOJIS = &Permission{
|
||||
"delete_emojis",
|
||||
"authentication.permissions.delete_emojis.name",
|
||||
"authentication.permissions.delete_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_DELETE_OTHERS_EMOJIS = &Permission{
|
||||
"delete_others_emojis",
|
||||
"authentication.permissions.delete_others_emojis.name",
|
||||
"authentication.permissions.delete_others_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_CREATE_POST = &Permission{
|
||||
"create_post",
|
||||
"authentication.permissions.create_post.name",
|
||||
@ -396,12 +493,87 @@ func initializePermissions() {
|
||||
"authentication.permissions.revoke_user_access_token.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_CREATE_BOT = &Permission{
|
||||
"create_bot",
|
||||
"authentication.permissions.create_bot.name",
|
||||
"authentication.permissions.create_bot.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_ASSIGN_BOT = &Permission{
|
||||
"assign_bot",
|
||||
"authentication.permissions.assign_bot.name",
|
||||
"authentication.permissions.assign_bot.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_READ_BOTS = &Permission{
|
||||
"read_bots",
|
||||
"authentication.permissions.read_bots.name",
|
||||
"authentication.permissions.read_bots.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_READ_OTHERS_BOTS = &Permission{
|
||||
"read_others_bots",
|
||||
"authentication.permissions.read_others_bots.name",
|
||||
"authentication.permissions.read_others_bots.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_BOTS = &Permission{
|
||||
"manage_bots",
|
||||
"authentication.permissions.manage_bots.name",
|
||||
"authentication.permissions.manage_bots.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_OTHERS_BOTS = &Permission{
|
||||
"manage_others_bots",
|
||||
"authentication.permissions.manage_others_bots.name",
|
||||
"authentication.permissions.manage_others_bots.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_JOBS = &Permission{
|
||||
"manage_jobs",
|
||||
"authentication.permisssions.manage_jobs.name",
|
||||
"authentication.permisssions.manage_jobs.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_VIEW_MEMBERS = &Permission{
|
||||
"view_members",
|
||||
"authentication.permisssions.view_members.name",
|
||||
"authentication.permisssions.view_members.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_INVITE_GUEST = &Permission{
|
||||
"invite_guest",
|
||||
"authentication.permissions.invite_guest.name",
|
||||
"authentication.permissions.invite_guest.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_PROMOTE_GUEST = &Permission{
|
||||
"promote_guest",
|
||||
"authentication.permissions.promote_guest.name",
|
||||
"authentication.permissions.promote_guest.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
|
||||
PERMISSION_DEMOTE_TO_GUEST = &Permission{
|
||||
"demote_to_guest",
|
||||
"authentication.permissions.demote_to_guest.name",
|
||||
"authentication.permissions.demote_to_guest.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
|
||||
PERMISSION_USE_CHANNEL_MENTIONS = &Permission{
|
||||
"use_channel_mentions",
|
||||
"authentication.permissions.use_channel_mentions.name",
|
||||
"authentication.permissions.use_channel_mentions.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
|
||||
PERMISSION_USE_GROUP_MENTIONS = &Permission{
|
||||
"use_group_mentions",
|
||||
"authentication.permissions.use_group_mentions.name",
|
||||
"authentication.permissions.use_group_mentions.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
|
||||
ALL_PERMISSIONS = []*Permission{
|
||||
PERMISSION_INVITE_USER,
|
||||
@ -421,6 +593,10 @@ func initializePermissions() {
|
||||
PERMISSION_CREATE_GROUP_CHANNEL,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES,
|
||||
PERMISSION_LIST_PUBLIC_TEAMS,
|
||||
PERMISSION_JOIN_PUBLIC_TEAMS,
|
||||
PERMISSION_LIST_PRIVATE_TEAMS,
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS,
|
||||
PERMISSION_LIST_TEAM_CHANNELS,
|
||||
PERMISSION_JOIN_PUBLIC_CHANNELS,
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL,
|
||||
@ -436,10 +612,17 @@ func initializePermissions() {
|
||||
PERMISSION_GET_PUBLIC_LINK,
|
||||
PERMISSION_MANAGE_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OTHERS_WEBHOOKS,
|
||||
PERMISSION_MANAGE_INCOMING_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OUTGOING_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OAUTH,
|
||||
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH,
|
||||
PERMISSION_MANAGE_EMOJIS,
|
||||
PERMISSION_MANAGE_OTHERS_EMOJIS,
|
||||
PERMISSION_CREATE_EMOJIS,
|
||||
PERMISSION_DELETE_EMOJIS,
|
||||
PERMISSION_DELETE_OTHERS_EMOJIS,
|
||||
PERMISSION_CREATE_POST,
|
||||
PERMISSION_CREATE_POST_PUBLIC,
|
||||
PERMISSION_CREATE_POST_EPHEMERAL,
|
||||
@ -457,7 +640,34 @@ func initializePermissions() {
|
||||
PERMISSION_CREATE_USER_ACCESS_TOKEN,
|
||||
PERMISSION_READ_USER_ACCESS_TOKEN,
|
||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN,
|
||||
PERMISSION_CREATE_BOT,
|
||||
PERMISSION_READ_BOTS,
|
||||
PERMISSION_READ_OTHERS_BOTS,
|
||||
PERMISSION_MANAGE_BOTS,
|
||||
PERMISSION_MANAGE_OTHERS_BOTS,
|
||||
PERMISSION_MANAGE_SYSTEM,
|
||||
PERMISSION_VIEW_MEMBERS,
|
||||
PERMISSION_INVITE_GUEST,
|
||||
PERMISSION_PROMOTE_GUEST,
|
||||
PERMISSION_DEMOTE_TO_GUEST,
|
||||
PERMISSION_USE_CHANNEL_MENTIONS,
|
||||
PERMISSION_USE_GROUP_MENTIONS,
|
||||
}
|
||||
|
||||
CHANNEL_MODERATED_PERMISSIONS = []string{
|
||||
PERMISSION_CREATE_POST.Id,
|
||||
"create_reactions",
|
||||
"manage_members",
|
||||
PERMISSION_USE_CHANNEL_MENTIONS.Id,
|
||||
}
|
||||
|
||||
CHANNEL_MODERATED_PERMISSIONS_MAP = map[string]string{
|
||||
PERMISSION_CREATE_POST.Id: CHANNEL_MODERATED_PERMISSIONS[0],
|
||||
PERMISSION_ADD_REACTION.Id: CHANNEL_MODERATED_PERMISSIONS[1],
|
||||
PERMISSION_REMOVE_REACTION.Id: CHANNEL_MODERATED_PERMISSIONS[1],
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id: CHANNEL_MODERATED_PERMISSIONS[2],
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id: CHANNEL_MODERATED_PERMISSIONS[2],
|
||||
PERMISSION_USE_CHANNEL_MENTIONS.Id: CHANNEL_MODERATED_PERMISSIONS[3],
|
||||
}
|
||||
}
|
||||
|
25
vendor/github.com/mattermost/mattermost-server/v5/model/plugin_event_data.go
generated
vendored
Normal file
25
vendor/github.com/mattermost/mattermost-server/v5/model/plugin_event_data.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// PluginEventData used to notify peers about plugin changes.
|
||||
type PluginEventData struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
func (p *PluginEventData) ToJson() string {
|
||||
b, _ := json.Marshal(p)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PluginEventDataFromJson(data io.Reader) PluginEventData {
|
||||
var m PluginEventData
|
||||
json.NewDecoder(data).Decode(&m)
|
||||
return m
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -17,6 +17,7 @@ type PluginKeyValue struct {
|
||||
PluginId string `json:"plugin_id"`
|
||||
Key string `json:"key" db:"PKey"`
|
||||
Value []byte `json:"value" db:"PValue"`
|
||||
ExpireAt int64 `json:"expire_at"`
|
||||
}
|
||||
|
||||
func (kv *PluginKeyValue) IsValid() *AppError {
|
47
vendor/github.com/mattermost/mattermost-server/v5/model/plugin_kvset_options.go
generated
vendored
Normal file
47
vendor/github.com/mattermost/mattermost-server/v5/model/plugin_kvset_options.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// PluginKVSetOptions contains information on how to store a value in the plugin KV store.
|
||||
type PluginKVSetOptions struct {
|
||||
Atomic bool // Only store the value if the current value matches the oldValue
|
||||
OldValue []byte // The value to compare with the current value. Only used when Atomic is true
|
||||
ExpireInSeconds int64 // Set an expire counter
|
||||
}
|
||||
|
||||
// IsValid returns nil if the chosen options are valid.
|
||||
func (opt *PluginKVSetOptions) IsValid() *AppError {
|
||||
if !opt.Atomic && opt.OldValue != nil {
|
||||
return NewAppError(
|
||||
"PluginKVSetOptions.IsValid",
|
||||
"model.plugin_kvset_options.is_valid.old_value.app_error",
|
||||
nil,
|
||||
"",
|
||||
http.StatusBadRequest,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewPluginKeyValueFromOptions return a PluginKeyValue given a pluginID, a KV pair and options.
|
||||
func NewPluginKeyValueFromOptions(pluginId, key string, value []byte, opt PluginKVSetOptions) (*PluginKeyValue, *AppError) {
|
||||
expireAt := int64(0)
|
||||
if opt.ExpireInSeconds != 0 {
|
||||
expireAt = GetMillis() + (opt.ExpireInSeconds * 1000)
|
||||
}
|
||||
|
||||
kv := &PluginKeyValue{
|
||||
PluginId: pluginId,
|
||||
Key: key,
|
||||
Value: value,
|
||||
ExpireAt: expireAt,
|
||||
}
|
||||
|
||||
return kv, nil
|
||||
}
|
@ -13,7 +13,7 @@ const (
|
||||
PluginStateStarting = 1 // unused by server
|
||||
PluginStateRunning = 2
|
||||
PluginStateFailedToStart = 3
|
||||
PluginStateFailedToStayRunning = 4 // unused by server
|
||||
PluginStateFailedToStayRunning = 4
|
||||
PluginStateStopping = 5 // unused by server
|
||||
)
|
||||
|
39
vendor/github.com/mattermost/mattermost-server/v5/model/plugin_valid.go
generated
vendored
Normal file
39
vendor/github.com/mattermost/mattermost-server/v5/model/plugin_valid.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
MinIdLength = 3
|
||||
MaxIdLength = 190
|
||||
ValidIdRegex = `^[a-zA-Z0-9-_\.]+$`
|
||||
)
|
||||
|
||||
// ValidId constrains the set of valid plugin identifiers:
|
||||
// ^[a-zA-Z0-9-_\.]+
|
||||
var validId *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
validId = regexp.MustCompile(ValidIdRegex)
|
||||
}
|
||||
|
||||
// IsValidPluginId verifies that the plugin id has a minimum length of 3, maximum length of 190, and
|
||||
// contains only alphanumeric characters, dashes, underscores and periods.
|
||||
//
|
||||
// These constraints are necessary since the plugin id is used as part of a filesystem path.
|
||||
func IsValidPluginId(id string) bool {
|
||||
if utf8.RuneCountInString(id) < MinIdLength {
|
||||
return false
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(id) > MaxIdLength {
|
||||
return false
|
||||
}
|
||||
|
||||
return validId.MatchString(id)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
@ -1,17 +1,20 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mattermost/mattermost-server/utils/markdown"
|
||||
"github.com/mattermost/mattermost-server/v5/utils/markdown"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -21,12 +24,14 @@ const (
|
||||
POST_SYSTEM_GENERIC = "system_generic"
|
||||
POST_JOIN_LEAVE = "system_join_leave" // Deprecated, use POST_JOIN_CHANNEL or POST_LEAVE_CHANNEL instead
|
||||
POST_JOIN_CHANNEL = "system_join_channel"
|
||||
POST_GUEST_JOIN_CHANNEL = "system_guest_join_channel"
|
||||
POST_LEAVE_CHANNEL = "system_leave_channel"
|
||||
POST_JOIN_TEAM = "system_join_team"
|
||||
POST_LEAVE_TEAM = "system_leave_team"
|
||||
POST_AUTO_RESPONDER = "system_auto_responder"
|
||||
POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead
|
||||
POST_ADD_TO_CHANNEL = "system_add_to_channel"
|
||||
POST_ADD_GUEST_TO_CHANNEL = "system_add_guest_to_chan"
|
||||
POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel"
|
||||
POST_MOVE_CHANNEL = "system_move_channel"
|
||||
POST_ADD_TO_TEAM = "system_add_to_team"
|
||||
@ -36,8 +41,10 @@ const (
|
||||
POST_CONVERT_CHANNEL = "system_convert_channel"
|
||||
POST_PURPOSE_CHANGE = "system_purpose_change"
|
||||
POST_CHANNEL_DELETED = "system_channel_deleted"
|
||||
POST_CHANNEL_RESTORED = "system_channel_restored"
|
||||
POST_EPHEMERAL = "system_ephemeral"
|
||||
POST_CHANGE_CHANNEL_PRIVACY = "system_change_chan_privacy"
|
||||
POST_ADD_BOT_TEAMS_CHANNELS = "add_bot_teams_channels"
|
||||
POST_FILEIDS_MAX_RUNES = 150
|
||||
POST_FILENAMES_MAX_RUNES = 4000
|
||||
POST_HASHTAGS_MAX_RUNES = 1000
|
||||
@ -47,13 +54,20 @@ const (
|
||||
POST_PROPS_MAX_RUNES = 8000
|
||||
POST_PROPS_MAX_USER_RUNES = POST_PROPS_MAX_RUNES - 400 // Leave some room for system / pre-save modifications
|
||||
POST_CUSTOM_TYPE_PREFIX = "custom_"
|
||||
POST_ME = "me"
|
||||
PROPS_ADD_CHANNEL_MEMBER = "add_channel_member"
|
||||
POST_PROPS_ADDED_USER_ID = "addedUserId"
|
||||
POST_PROPS_DELETE_BY = "deleteBy"
|
||||
POST_ACTION_TYPE_BUTTON = "button"
|
||||
POST_ACTION_TYPE_SELECT = "select"
|
||||
|
||||
POST_PROPS_ADDED_USER_ID = "addedUserId"
|
||||
POST_PROPS_DELETE_BY = "deleteBy"
|
||||
POST_PROPS_OVERRIDE_ICON_URL = "override_icon_url"
|
||||
POST_PROPS_OVERRIDE_ICON_EMOJI = "override_icon_emoji"
|
||||
|
||||
POST_PROPS_MENTION_HIGHLIGHT_DISABLED = "mentionHighlightDisabled"
|
||||
POST_PROPS_GROUP_HIGHLIGHT_DISABLED = "disable_group_highlight"
|
||||
)
|
||||
|
||||
var AT_MENTION_PATTEN = regexp.MustCompile(`\B@`)
|
||||
|
||||
type Post struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
@ -68,19 +82,23 @@ type Post struct {
|
||||
OriginalId string `json:"original_id"`
|
||||
|
||||
Message string `json:"message"`
|
||||
|
||||
// MessageSource will contain the message as submitted by the user if Message has been modified
|
||||
// by Mattermost for presentation (e.g if an image proxy is being used). It should be used to
|
||||
// populate edit boxes if present.
|
||||
MessageSource string `json:"message_source,omitempty" db:"-"`
|
||||
|
||||
Type string `json:"type"`
|
||||
Props StringInterface `json:"props"`
|
||||
propsMu sync.RWMutex `db:"-"` // Unexported mutex used to guard Post.Props.
|
||||
Props StringInterface `json:"props"` // Deprecated: use GetProps()
|
||||
Hashtags string `json:"hashtags"`
|
||||
Filenames StringArray `json:"filenames,omitempty"` // Deprecated, do not use this field any more
|
||||
FileIds StringArray `json:"file_ids,omitempty"`
|
||||
PendingPostId string `json:"pending_post_id" db:"-"`
|
||||
HasReactions bool `json:"has_reactions,omitempty"`
|
||||
|
||||
// Transient data populated before sending a post to the client
|
||||
ReplyCount int64 `json:"reply_count" db:"-"`
|
||||
Metadata *PostMetadata `json:"metadata,omitempty" db:"-"`
|
||||
}
|
||||
|
||||
type PostEphemeral struct {
|
||||
@ -105,6 +123,12 @@ type SearchParameter struct {
|
||||
IncludeDeletedChannels *bool `json:"include_deleted_channels"`
|
||||
}
|
||||
|
||||
type AnalyticsPostCountsOptions struct {
|
||||
TeamId string
|
||||
BotsOnly bool
|
||||
YesterdayOnly bool
|
||||
}
|
||||
|
||||
func (o *PostPatch) WithRewrittenImageURLs(f func(string) string) *PostPatch {
|
||||
copy := *o
|
||||
if copy.Message != nil {
|
||||
@ -121,6 +145,12 @@ type PostForExport struct {
|
||||
ReplyCount int
|
||||
}
|
||||
|
||||
type DirectPostForExport struct {
|
||||
Post
|
||||
User string
|
||||
ChannelMembers *[]string
|
||||
}
|
||||
|
||||
type ReplyForExport struct {
|
||||
Post
|
||||
Username string
|
||||
@ -132,48 +162,52 @@ type PostForIndexing struct {
|
||||
ParentCreateAt *int64 `json:"parent_create_at"`
|
||||
}
|
||||
|
||||
type DoPostActionRequest struct {
|
||||
SelectedOption string `json:"selected_option"`
|
||||
// ShallowCopy is an utility function to shallow copy a Post to the given
|
||||
// destination without touching the internal RWMutex.
|
||||
func (o *Post) ShallowCopy(dst *Post) error {
|
||||
if dst == nil {
|
||||
return errors.New("dst cannot be nil")
|
||||
}
|
||||
o.propsMu.RLock()
|
||||
defer o.propsMu.RUnlock()
|
||||
dst.propsMu.Lock()
|
||||
defer dst.propsMu.Unlock()
|
||||
dst.Id = o.Id
|
||||
dst.CreateAt = o.CreateAt
|
||||
dst.UpdateAt = o.UpdateAt
|
||||
dst.EditAt = o.EditAt
|
||||
dst.DeleteAt = o.DeleteAt
|
||||
dst.IsPinned = o.IsPinned
|
||||
dst.UserId = o.UserId
|
||||
dst.ChannelId = o.ChannelId
|
||||
dst.RootId = o.RootId
|
||||
dst.ParentId = o.ParentId
|
||||
dst.OriginalId = o.OriginalId
|
||||
dst.Message = o.Message
|
||||
dst.MessageSource = o.MessageSource
|
||||
dst.Type = o.Type
|
||||
dst.Props = o.Props
|
||||
dst.Hashtags = o.Hashtags
|
||||
dst.Filenames = o.Filenames
|
||||
dst.FileIds = o.FileIds
|
||||
dst.PendingPostId = o.PendingPostId
|
||||
dst.HasReactions = o.HasReactions
|
||||
dst.ReplyCount = o.ReplyCount
|
||||
dst.Metadata = o.Metadata
|
||||
return nil
|
||||
}
|
||||
|
||||
type PostAction struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
DataSource string `json:"data_source"`
|
||||
Options []*PostActionOptions `json:"options"`
|
||||
Integration *PostActionIntegration `json:"integration,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionOptions struct {
|
||||
Text string `json:"text"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type PostActionIntegration struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
Context StringInterface `json:"context,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionIntegrationRequest struct {
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
PostId string `json:"post_id"`
|
||||
Type string `json:"type"`
|
||||
DataSource string `json:"data_source"`
|
||||
Context StringInterface `json:"context,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionIntegrationResponse struct {
|
||||
Update *Post `json:"update"`
|
||||
EphemeralText string `json:"ephemeral_text"`
|
||||
// Clone shallowly copies the post and returns the copy.
|
||||
func (o *Post) Clone() *Post {
|
||||
copy := &Post{}
|
||||
o.ShallowCopy(copy)
|
||||
return copy
|
||||
}
|
||||
|
||||
func (o *Post) ToJson() string {
|
||||
copy := *o
|
||||
copy := o.Clone()
|
||||
copy.StripActionIntegrations()
|
||||
b, _ := json.Marshal(©)
|
||||
b, _ := json.Marshal(copy)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
@ -182,6 +216,20 @@ func (o *Post) ToUnsanitizedJson() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
type GetPostsSinceOptions struct {
|
||||
ChannelId string
|
||||
Time int64
|
||||
SkipFetchThreads bool
|
||||
}
|
||||
|
||||
type GetPostsOptions struct {
|
||||
ChannelId string
|
||||
PostId string
|
||||
Page int
|
||||
PerPage int
|
||||
SkipFetchThreads bool
|
||||
}
|
||||
|
||||
func PostFromJson(data io.Reader) *Post {
|
||||
var o *Post
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
@ -193,8 +241,7 @@ func (o *Post) Etag() string {
|
||||
}
|
||||
|
||||
func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
if !IsValidId(o.Id) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -206,19 +253,19 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
if !IsValidId(o.UserId) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
if !IsValidId(o.ChannelId) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(len(o.RootId) == 26 || len(o.RootId) == 0) {
|
||||
if !(IsValidId(o.RootId) || len(o.RootId) == 0) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.root_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(len(o.ParentId) == 26 || len(o.ParentId) == 0) {
|
||||
if !(IsValidId(o.ParentId) || len(o.ParentId) == 0) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.parent_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -241,14 +288,17 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
switch o.Type {
|
||||
case
|
||||
POST_DEFAULT,
|
||||
POST_SYSTEM_GENERIC,
|
||||
POST_JOIN_LEAVE,
|
||||
POST_AUTO_RESPONDER,
|
||||
POST_ADD_REMOVE,
|
||||
POST_JOIN_CHANNEL,
|
||||
POST_GUEST_JOIN_CHANNEL,
|
||||
POST_LEAVE_CHANNEL,
|
||||
POST_JOIN_TEAM,
|
||||
POST_LEAVE_TEAM,
|
||||
POST_ADD_TO_CHANNEL,
|
||||
POST_ADD_GUEST_TO_CHANNEL,
|
||||
POST_REMOVE_FROM_CHANNEL,
|
||||
POST_MOVE_CHANNEL,
|
||||
POST_ADD_TO_TEAM,
|
||||
@ -259,7 +309,10 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
POST_DISPLAYNAME_CHANGE,
|
||||
POST_CONVERT_CHANNEL,
|
||||
POST_CHANNEL_DELETED,
|
||||
POST_CHANGE_CHANNEL_PRIVACY:
|
||||
POST_CHANNEL_RESTORED,
|
||||
POST_CHANGE_CHANNEL_PRIVACY,
|
||||
POST_ME,
|
||||
POST_ADD_BOT_TEAMS_CHANNELS:
|
||||
default:
|
||||
if !strings.HasPrefix(o.Type, POST_CUSTOM_TYPE_PREFIX) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.type.app_error", nil, "id="+o.Type, http.StatusBadRequest)
|
||||
@ -274,7 +327,7 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.file_ids.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(StringInterfaceToJson(o.Props)) > POST_PROPS_MAX_RUNES {
|
||||
if utf8.RuneCountInString(StringInterfaceToJson(o.GetProps())) > POST_PROPS_MAX_RUNES {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.props.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -287,8 +340,8 @@ func (o *Post) SanitizeProps() {
|
||||
}
|
||||
|
||||
for _, member := range membersToSanitize {
|
||||
if _, ok := o.Props[member]; ok {
|
||||
delete(o.Props, member)
|
||||
if _, ok := o.GetProps()[member]; ok {
|
||||
o.DelProp(member)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,8 +362,8 @@ func (o *Post) PreSave() {
|
||||
}
|
||||
|
||||
func (o *Post) PreCommit() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
if o.GetProps() == nil {
|
||||
o.SetProps(make(map[string]interface{}))
|
||||
}
|
||||
|
||||
if o.Filenames == nil {
|
||||
@ -322,44 +375,94 @@ func (o *Post) PreCommit() {
|
||||
}
|
||||
|
||||
o.GenerateActionIds()
|
||||
|
||||
// There's a rare bug where the client sends up duplicate FileIds so protect against that
|
||||
o.FileIds = RemoveDuplicateStrings(o.FileIds)
|
||||
}
|
||||
|
||||
func (o *Post) MakeNonNil() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
if o.GetProps() == nil {
|
||||
o.SetProps(make(map[string]interface{}))
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Post) DelProp(key string) {
|
||||
o.propsMu.Lock()
|
||||
defer o.propsMu.Unlock()
|
||||
propsCopy := make(map[string]interface{}, len(o.Props)-1)
|
||||
for k, v := range o.Props {
|
||||
propsCopy[k] = v
|
||||
}
|
||||
delete(propsCopy, key)
|
||||
o.Props = propsCopy
|
||||
}
|
||||
|
||||
func (o *Post) AddProp(key string, value interface{}) {
|
||||
o.propsMu.Lock()
|
||||
defer o.propsMu.Unlock()
|
||||
propsCopy := make(map[string]interface{}, len(o.Props)+1)
|
||||
for k, v := range o.Props {
|
||||
propsCopy[k] = v
|
||||
}
|
||||
propsCopy[key] = value
|
||||
o.Props = propsCopy
|
||||
}
|
||||
|
||||
o.MakeNonNil()
|
||||
func (o *Post) GetProps() StringInterface {
|
||||
o.propsMu.RLock()
|
||||
defer o.propsMu.RUnlock()
|
||||
return o.Props
|
||||
}
|
||||
|
||||
o.Props[key] = value
|
||||
func (o *Post) SetProps(props StringInterface) {
|
||||
o.propsMu.Lock()
|
||||
defer o.propsMu.Unlock()
|
||||
o.Props = props
|
||||
}
|
||||
|
||||
func (o *Post) GetProp(key string) interface{} {
|
||||
o.propsMu.RLock()
|
||||
defer o.propsMu.RUnlock()
|
||||
return o.Props[key]
|
||||
}
|
||||
|
||||
func (o *Post) IsSystemMessage() bool {
|
||||
return len(o.Type) >= len(POST_SYSTEM_MESSAGE_PREFIX) && o.Type[:len(POST_SYSTEM_MESSAGE_PREFIX)] == POST_SYSTEM_MESSAGE_PREFIX
|
||||
}
|
||||
|
||||
func (p *Post) Patch(patch *PostPatch) {
|
||||
func (o *Post) IsJoinLeaveMessage() bool {
|
||||
return o.Type == POST_JOIN_LEAVE ||
|
||||
o.Type == POST_ADD_REMOVE ||
|
||||
o.Type == POST_JOIN_CHANNEL ||
|
||||
o.Type == POST_LEAVE_CHANNEL ||
|
||||
o.Type == POST_JOIN_TEAM ||
|
||||
o.Type == POST_LEAVE_TEAM ||
|
||||
o.Type == POST_ADD_TO_CHANNEL ||
|
||||
o.Type == POST_REMOVE_FROM_CHANNEL ||
|
||||
o.Type == POST_ADD_TO_TEAM ||
|
||||
o.Type == POST_REMOVE_FROM_TEAM
|
||||
}
|
||||
|
||||
func (o *Post) Patch(patch *PostPatch) {
|
||||
if patch.IsPinned != nil {
|
||||
p.IsPinned = *patch.IsPinned
|
||||
o.IsPinned = *patch.IsPinned
|
||||
}
|
||||
|
||||
if patch.Message != nil {
|
||||
p.Message = *patch.Message
|
||||
o.Message = *patch.Message
|
||||
}
|
||||
|
||||
if patch.Props != nil {
|
||||
p.Props = *patch.Props
|
||||
newProps := *patch.Props
|
||||
o.SetProps(newProps)
|
||||
}
|
||||
|
||||
if patch.FileIds != nil {
|
||||
p.FileIds = *patch.FileIds
|
||||
o.FileIds = *patch.FileIds
|
||||
}
|
||||
|
||||
if patch.HasReactions != nil {
|
||||
p.HasReactions = *patch.HasReactions
|
||||
o.HasReactions = *patch.HasReactions
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,40 +510,40 @@ func (o *Post) ChannelMentions() []string {
|
||||
return ChannelMentions(o.Message)
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationRequest) ToJson() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PostActionIntegrationRequesteFromJson(data io.Reader) *PostActionIntegrationRequest {
|
||||
var o *PostActionIntegrationRequest
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
// DisableMentionHighlights disables a posts mention highlighting and returns the first channel mention that was present in the message.
|
||||
func (o *Post) DisableMentionHighlights() string {
|
||||
mention, hasMentions := findAtChannelMention(o.Message)
|
||||
if hasMentions {
|
||||
o.AddProp(POST_PROPS_MENTION_HIGHLIGHT_DISABLED, true)
|
||||
}
|
||||
return o
|
||||
return mention
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationResponse) ToJson() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PostActionIntegrationResponseFromJson(data io.Reader) *PostActionIntegrationResponse {
|
||||
var o *PostActionIntegrationResponse
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
// DisableMentionHighlights disables mention highlighting for a post patch if required.
|
||||
func (o *PostPatch) DisableMentionHighlights() {
|
||||
if _, hasMentions := findAtChannelMention(*o.Message); hasMentions {
|
||||
if o.Props == nil {
|
||||
o.Props = &StringInterface{}
|
||||
}
|
||||
(*o.Props)[POST_PROPS_MENTION_HIGHLIGHT_DISABLED] = true
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func findAtChannelMention(message string) (mention string, found bool) {
|
||||
re := regexp.MustCompile(`(?i)\B@(channel|all|here)\b`)
|
||||
matched := re.FindStringSubmatch(message)
|
||||
if found = (len(matched) > 0); found {
|
||||
mention = strings.ToLower(matched[0])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Post) Attachments() []*SlackAttachment {
|
||||
if attachments, ok := o.Props["attachments"].([]*SlackAttachment); ok {
|
||||
if attachments, ok := o.GetProp("attachments").([]*SlackAttachment); ok {
|
||||
return attachments
|
||||
}
|
||||
var ret []*SlackAttachment
|
||||
if attachments, ok := o.Props["attachments"].([]interface{}); ok {
|
||||
if attachments, ok := o.GetProp("attachments").([]interface{}); ok {
|
||||
for _, attachment := range attachments {
|
||||
if enc, err := json.Marshal(attachment); err == nil {
|
||||
var decoded SlackAttachment
|
||||
@ -453,42 +556,21 @@ func (o *Post) Attachments() []*SlackAttachment {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (o *Post) StripActionIntegrations() {
|
||||
func (o *Post) AttachmentsEqual(input *Post) bool {
|
||||
attachments := o.Attachments()
|
||||
if o.Props["attachments"] != nil {
|
||||
o.Props["attachments"] = attachments
|
||||
}
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
action.Integration = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
inputAttachments := input.Attachments()
|
||||
|
||||
func (o *Post) GetAction(id string) *PostAction {
|
||||
for _, attachment := range o.Attachments() {
|
||||
for _, action := range attachment.Actions {
|
||||
if action.Id == id {
|
||||
return action
|
||||
}
|
||||
}
|
||||
if len(attachments) != len(inputAttachments) {
|
||||
return false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Post) GenerateActionIds() {
|
||||
if o.Props["attachments"] != nil {
|
||||
o.Props["attachments"] = o.Attachments()
|
||||
}
|
||||
if attachments, ok := o.Props["attachments"].([]*SlackAttachment); ok {
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
if action.Id == "" {
|
||||
action.Id = NewId()
|
||||
}
|
||||
}
|
||||
for i := range attachments {
|
||||
if !attachments[i].Equals(inputAttachments[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var markdownDestinationEscaper = strings.NewReplacer(
|
||||
@ -502,12 +584,12 @@ var markdownDestinationEscaper = strings.NewReplacer(
|
||||
// WithRewrittenImageURLs returns a new shallow copy of the post where the message has been
|
||||
// rewritten via RewriteImageURLs.
|
||||
func (o *Post) WithRewrittenImageURLs(f func(string) string) *Post {
|
||||
copy := *o
|
||||
copy := o.Clone()
|
||||
copy.Message = RewriteImageURLs(o.Message, f)
|
||||
if copy.MessageSource == "" && copy.Message != o.Message {
|
||||
copy.MessageSource = o.Message
|
||||
}
|
||||
return ©
|
||||
return copy
|
||||
}
|
||||
|
||||
func (o *PostEphemeral) ToUnsanitizedJson() string {
|
||||
@ -515,12 +597,6 @@ func (o *PostEphemeral) ToUnsanitizedJson() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func DoPostActionRequestFromJson(data io.Reader) *DoPostActionRequest {
|
||||
var o *DoPostActionRequest
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
// RewriteImageURLs takes a message and returns a copy that has all of the image URLs replaced
|
||||
// according to the function f. For each image URL, f will be invoked, and the resulting markdown
|
||||
// will contain the URL returned by that invocation instead.
|
23
vendor/github.com/mattermost/mattermost-server/v5/model/post_embed.go
generated
vendored
Normal file
23
vendor/github.com/mattermost/mattermost-server/v5/model/post_embed.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
POST_EMBED_IMAGE PostEmbedType = "image"
|
||||
POST_EMBED_MESSAGE_ATTACHMENT PostEmbedType = "message_attachment"
|
||||
POST_EMBED_OPENGRAPH PostEmbedType = "opengraph"
|
||||
POST_EMBED_LINK PostEmbedType = "link"
|
||||
)
|
||||
|
||||
type PostEmbedType string
|
||||
|
||||
type PostEmbed struct {
|
||||
Type PostEmbedType `json:"type"`
|
||||
|
||||
// The URL of the embedded content. Used for image and OpenGraph embeds.
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// Any additional data for the embedded content. Only used for OpenGraph embeds.
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
@ -10,17 +10,29 @@ import (
|
||||
)
|
||||
|
||||
type PostList struct {
|
||||
Order []string `json:"order"`
|
||||
Posts map[string]*Post `json:"posts"`
|
||||
Order []string `json:"order"`
|
||||
Posts map[string]*Post `json:"posts"`
|
||||
NextPostId string `json:"next_post_id"`
|
||||
PrevPostId string `json:"prev_post_id"`
|
||||
}
|
||||
|
||||
func NewPostList() *PostList {
|
||||
return &PostList{
|
||||
Order: make([]string, 0),
|
||||
Posts: make(map[string]*Post),
|
||||
Order: make([]string, 0),
|
||||
Posts: make(map[string]*Post),
|
||||
NextPostId: "",
|
||||
PrevPostId: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostList) ToSlice() []*Post {
|
||||
var posts []*Post
|
||||
for _, id := range o.Order {
|
||||
posts = append(posts, o.Posts[id])
|
||||
}
|
||||
return posts
|
||||
}
|
||||
|
||||
func (o *PostList) WithRewrittenImageURLs(f func(string) string) *PostList {
|
||||
copy := *o
|
||||
copy.Posts = make(map[string]*Post)
|
||||
@ -34,9 +46,9 @@ func (o *PostList) StripActionIntegrations() {
|
||||
posts := o.Posts
|
||||
o.Posts = make(map[string]*Post)
|
||||
for id, post := range posts {
|
||||
pcopy := *post
|
||||
pcopy := post.Clone()
|
||||
pcopy.StripActionIntegrations()
|
||||
o.Posts[id] = &pcopy
|
||||
o.Posts[id] = pcopy
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,13 +95,29 @@ func (o *PostList) AddPost(post *Post) {
|
||||
o.Posts[post.Id] = post
|
||||
}
|
||||
|
||||
func (o *PostList) Extend(other *PostList) {
|
||||
for _, postId := range other.Order {
|
||||
if _, ok := o.Posts[postId]; !ok {
|
||||
o.AddPost(other.Posts[postId])
|
||||
o.AddOrder(postId)
|
||||
func (o *PostList) UniqueOrder() {
|
||||
keys := make(map[string]bool)
|
||||
order := []string{}
|
||||
for _, postId := range o.Order {
|
||||
if _, value := keys[postId]; !value {
|
||||
keys[postId] = true
|
||||
order = append(order, postId)
|
||||
}
|
||||
}
|
||||
|
||||
o.Order = order
|
||||
}
|
||||
|
||||
func (o *PostList) Extend(other *PostList) {
|
||||
for postId := range other.Posts {
|
||||
o.AddPost(other.Posts[postId])
|
||||
}
|
||||
|
||||
for _, postId := range other.Order {
|
||||
o.AddOrder(postId)
|
||||
}
|
||||
|
||||
o.UniqueOrder()
|
||||
}
|
||||
|
||||
func (o *PostList) SortByCreateAt() {
|
45
vendor/github.com/mattermost/mattermost-server/v5/model/post_metadata.go
generated
vendored
Normal file
45
vendor/github.com/mattermost/mattermost-server/v5/model/post_metadata.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type PostMetadata struct {
|
||||
// Embeds holds information required to render content embedded in the post. This includes the OpenGraph metadata
|
||||
// for links in the post.
|
||||
Embeds []*PostEmbed `json:"embeds,omitempty"`
|
||||
|
||||
// Emojis holds all custom emojis used in the post or used in reaction to the post.
|
||||
Emojis []*Emoji `json:"emojis,omitempty"`
|
||||
|
||||
// Files holds information about the file attachments on the post.
|
||||
Files []*FileInfo `json:"files,omitempty"`
|
||||
|
||||
// Images holds the dimensions of all external images in the post as a map of the image URL to its diemsnions.
|
||||
// This includes image embeds (when the message contains a plaintext link to an image), Markdown images, images
|
||||
// contained in the OpenGraph metadata, and images contained in message attachments. It does not contain
|
||||
// the dimensions of any file attachments as those are stored in FileInfos.
|
||||
Images map[string]*PostImage `json:"images,omitempty"`
|
||||
|
||||
// Reactions holds reactions made to the post.
|
||||
Reactions []*Reaction `json:"reactions,omitempty"`
|
||||
}
|
||||
|
||||
type PostImage struct {
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
|
||||
// Format is the name of the image format as used by image/go such as "png", "gif", or "jpeg".
|
||||
Format string `json:"format"`
|
||||
|
||||
// FrameCount stores the number of frames in this image, if it is an animated gif. It will be 0 for other formats.
|
||||
FrameCount int `json:"frame_count"`
|
||||
}
|
||||
|
||||
func (o *PostImage) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user