github.com/wgh-/mattermost-server@v4.8.0-rc2+incompatible/model/channel.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package model 5 6 import ( 7 "crypto/sha1" 8 "encoding/hex" 9 "encoding/json" 10 "io" 11 "net/http" 12 "sort" 13 "strings" 14 "unicode/utf8" 15 ) 16 17 const ( 18 CHANNEL_OPEN = "O" 19 CHANNEL_PRIVATE = "P" 20 CHANNEL_DIRECT = "D" 21 CHANNEL_GROUP = "G" 22 CHANNEL_GROUP_MAX_USERS = 8 23 CHANNEL_GROUP_MIN_USERS = 3 24 DEFAULT_CHANNEL = "town-square" 25 CHANNEL_DISPLAY_NAME_MAX_RUNES = 64 26 CHANNEL_NAME_MIN_LENGTH = 2 27 CHANNEL_NAME_MAX_LENGTH = 64 28 CHANNEL_NAME_UI_MAX_LENGTH = 22 29 CHANNEL_HEADER_MAX_RUNES = 1024 30 CHANNEL_PURPOSE_MAX_RUNES = 250 31 CHANNEL_CACHE_SIZE = 25000 32 ) 33 34 type Channel struct { 35 Id string `json:"id"` 36 CreateAt int64 `json:"create_at"` 37 UpdateAt int64 `json:"update_at"` 38 DeleteAt int64 `json:"delete_at"` 39 TeamId string `json:"team_id"` 40 Type string `json:"type"` 41 DisplayName string `json:"display_name"` 42 Name string `json:"name"` 43 Header string `json:"header"` 44 Purpose string `json:"purpose"` 45 LastPostAt int64 `json:"last_post_at"` 46 TotalMsgCount int64 `json:"total_msg_count"` 47 ExtraUpdateAt int64 `json:"extra_update_at"` 48 CreatorId string `json:"creator_id"` 49 } 50 51 type ChannelPatch struct { 52 DisplayName *string `json:"display_name"` 53 Name *string `json:"name"` 54 Header *string `json:"header"` 55 Purpose *string `json:"purpose"` 56 } 57 58 func (o *Channel) DeepCopy() *Channel { 59 copy := *o 60 return © 61 } 62 63 func (o *Channel) ToJson() string { 64 b, _ := json.Marshal(o) 65 return string(b) 66 } 67 68 func (o *ChannelPatch) ToJson() string { 69 b, _ := json.Marshal(o) 70 return string(b) 71 } 72 73 func ChannelFromJson(data io.Reader) *Channel { 74 var o *Channel 75 json.NewDecoder(data).Decode(&o) 76 return o 77 } 78 79 func ChannelPatchFromJson(data io.Reader) *ChannelPatch { 80 var o *ChannelPatch 81 json.NewDecoder(data).Decode(&o) 82 return o 83 } 84 85 func (o *Channel) Etag() string { 86 return Etag(o.Id, o.UpdateAt) 87 } 88 89 func (o *Channel) StatsEtag() string { 90 return Etag(o.Id, o.ExtraUpdateAt) 91 } 92 93 func (o *Channel) IsValid() *AppError { 94 95 if len(o.Id) != 26 { 96 return NewAppError("Channel.IsValid", "model.channel.is_valid.id.app_error", nil, "", http.StatusBadRequest) 97 } 98 99 if o.CreateAt == 0 { 100 return NewAppError("Channel.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) 101 } 102 103 if o.UpdateAt == 0 { 104 return NewAppError("Channel.IsValid", "model.channel.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) 105 } 106 107 if utf8.RuneCountInString(o.DisplayName) > CHANNEL_DISPLAY_NAME_MAX_RUNES { 108 return NewAppError("Channel.IsValid", "model.channel.is_valid.display_name.app_error", nil, "id="+o.Id, http.StatusBadRequest) 109 } 110 111 if !IsValidChannelIdentifier(o.Name) { 112 return NewAppError("Channel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+o.Id, http.StatusBadRequest) 113 } 114 115 if !(o.Type == CHANNEL_OPEN || o.Type == CHANNEL_PRIVATE || o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP) { 116 return NewAppError("Channel.IsValid", "model.channel.is_valid.type.app_error", nil, "id="+o.Id, http.StatusBadRequest) 117 } 118 119 if utf8.RuneCountInString(o.Header) > CHANNEL_HEADER_MAX_RUNES { 120 return NewAppError("Channel.IsValid", "model.channel.is_valid.header.app_error", nil, "id="+o.Id, http.StatusBadRequest) 121 } 122 123 if utf8.RuneCountInString(o.Purpose) > CHANNEL_PURPOSE_MAX_RUNES { 124 return NewAppError("Channel.IsValid", "model.channel.is_valid.purpose.app_error", nil, "id="+o.Id, http.StatusBadRequest) 125 } 126 127 if len(o.CreatorId) > 26 { 128 return NewAppError("Channel.IsValid", "model.channel.is_valid.creator_id.app_error", nil, "", http.StatusBadRequest) 129 } 130 131 return nil 132 } 133 134 func (o *Channel) PreSave() { 135 if o.Id == "" { 136 o.Id = NewId() 137 } 138 139 o.CreateAt = GetMillis() 140 o.UpdateAt = o.CreateAt 141 o.ExtraUpdateAt = o.CreateAt 142 } 143 144 func (o *Channel) PreUpdate() { 145 o.UpdateAt = GetMillis() 146 } 147 148 func (o *Channel) ExtraUpdated() { 149 o.ExtraUpdateAt = GetMillis() 150 } 151 152 func (o *Channel) IsGroupOrDirect() bool { 153 return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP 154 } 155 156 func (o *Channel) Patch(patch *ChannelPatch) { 157 if patch.DisplayName != nil { 158 o.DisplayName = *patch.DisplayName 159 } 160 161 if patch.Name != nil { 162 o.Name = *patch.Name 163 } 164 165 if patch.Header != nil { 166 o.Header = *patch.Header 167 } 168 169 if patch.Purpose != nil { 170 o.Purpose = *patch.Purpose 171 } 172 } 173 174 func GetDMNameFromIds(userId1, userId2 string) string { 175 if userId1 > userId2 { 176 return userId2 + "__" + userId1 177 } else { 178 return userId1 + "__" + userId2 179 } 180 } 181 182 func GetGroupDisplayNameFromUsers(users []*User, truncate bool) string { 183 usernames := make([]string, len(users)) 184 for index, user := range users { 185 usernames[index] = user.Username 186 } 187 188 sort.Strings(usernames) 189 190 name := strings.Join(usernames, ", ") 191 192 if truncate && len(name) > CHANNEL_NAME_MAX_LENGTH { 193 name = name[:CHANNEL_NAME_MAX_LENGTH] 194 } 195 196 return name 197 } 198 199 func GetGroupNameFromUserIds(userIds []string) string { 200 sort.Strings(userIds) 201 202 h := sha1.New() 203 for _, id := range userIds { 204 io.WriteString(h, id) 205 } 206 207 return hex.EncodeToString(h.Sum(nil)) 208 }