github.com/mattermost/mattermost-server/v5@v5.39.3/api4/emoji.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package api4 5 6 import ( 7 "io" 8 "io/ioutil" 9 "net/http" 10 "strings" 11 12 "github.com/mattermost/mattermost-server/v5/app" 13 "github.com/mattermost/mattermost-server/v5/audit" 14 "github.com/mattermost/mattermost-server/v5/model" 15 "github.com/mattermost/mattermost-server/v5/web" 16 ) 17 18 const ( 19 EmojiMaxAutocompleteItems = 100 20 ) 21 22 func (api *API) InitEmoji() { 23 api.BaseRoutes.Emojis.Handle("", api.ApiSessionRequired(createEmoji)).Methods("POST") 24 api.BaseRoutes.Emojis.Handle("", api.ApiSessionRequired(getEmojiList)).Methods("GET") 25 api.BaseRoutes.Emojis.Handle("/search", api.ApiSessionRequired(searchEmojis)).Methods("POST") 26 api.BaseRoutes.Emojis.Handle("/autocomplete", api.ApiSessionRequired(autocompleteEmojis)).Methods("GET") 27 api.BaseRoutes.Emoji.Handle("", api.ApiSessionRequired(deleteEmoji)).Methods("DELETE") 28 api.BaseRoutes.Emoji.Handle("", api.ApiSessionRequired(getEmoji)).Methods("GET") 29 api.BaseRoutes.EmojiByName.Handle("", api.ApiSessionRequired(getEmojiByName)).Methods("GET") 30 api.BaseRoutes.Emoji.Handle("/image", api.ApiSessionRequiredTrustRequester(getEmojiImage)).Methods("GET") 31 } 32 33 func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) { 34 defer io.Copy(ioutil.Discard, r.Body) 35 36 if !*c.App.Config().ServiceSettings.EnableCustomEmoji { 37 c.Err = model.NewAppError("createEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) 38 return 39 } 40 41 if r.ContentLength > app.MaxEmojiFileSize { 42 c.Err = model.NewAppError("createEmoji", "api.emoji.create.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge) 43 return 44 } 45 46 if err := r.ParseMultipartForm(app.MaxEmojiFileSize); err != nil { 47 c.Err = model.NewAppError("createEmoji", "api.emoji.create.parse.app_error", nil, err.Error(), http.StatusBadRequest) 48 return 49 } 50 51 auditRec := c.MakeAuditRecord("createEmoji", audit.Fail) 52 defer c.LogAuditRec(auditRec) 53 54 // Allow any user with CREATE_EMOJIS permission at Team level to create emojis at system level 55 memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId) 56 57 if err != nil { 58 c.Err = err 59 return 60 } 61 62 if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_CREATE_EMOJIS) { 63 hasPermission := false 64 for _, membership := range memberships { 65 if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), membership.TeamId, model.PERMISSION_CREATE_EMOJIS) { 66 hasPermission = true 67 break 68 } 69 } 70 if !hasPermission { 71 c.SetPermissionError(model.PERMISSION_CREATE_EMOJIS) 72 return 73 } 74 } 75 76 m := r.MultipartForm 77 props := m.Value 78 79 if len(props["emoji"]) == 0 { 80 c.SetInvalidParam("emoji") 81 return 82 } 83 84 emoji := model.EmojiFromJson(strings.NewReader(props["emoji"][0])) 85 if emoji == nil { 86 c.SetInvalidParam("emoji") 87 return 88 } 89 90 auditRec.AddMeta("emoji", emoji) 91 92 newEmoji, err := c.App.CreateEmoji(c.AppContext.Session().UserId, emoji, m) 93 if err != nil { 94 c.Err = err 95 return 96 } 97 98 auditRec.Success() 99 w.Write([]byte(newEmoji.ToJson())) 100 } 101 102 func getEmojiList(c *Context, w http.ResponseWriter, r *http.Request) { 103 if !*c.App.Config().ServiceSettings.EnableCustomEmoji { 104 c.Err = model.NewAppError("getEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) 105 return 106 } 107 108 sort := r.URL.Query().Get("sort") 109 if sort != "" && sort != model.EMOJI_SORT_BY_NAME { 110 c.SetInvalidUrlParam("sort") 111 return 112 } 113 114 listEmoji, err := c.App.GetEmojiList(c.Params.Page, c.Params.PerPage, sort) 115 if err != nil { 116 c.Err = err 117 return 118 } 119 120 w.Write([]byte(model.EmojiListToJson(listEmoji))) 121 } 122 123 func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) { 124 c.RequireEmojiId() 125 if c.Err != nil { 126 return 127 } 128 129 auditRec := c.MakeAuditRecord("deleteEmoji", audit.Fail) 130 defer c.LogAuditRec(auditRec) 131 132 emoji, err := c.App.GetEmoji(c.Params.EmojiId) 133 if err != nil { 134 auditRec.AddMeta("emoji_id", c.Params.EmojiId) 135 c.Err = err 136 return 137 } 138 auditRec.AddMeta("emoji", emoji) 139 140 // Allow any user with DELETE_EMOJIS permission at Team level to delete emojis at system level 141 memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId) 142 143 if err != nil { 144 c.Err = err 145 return 146 } 147 148 if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_DELETE_EMOJIS) { 149 hasPermission := false 150 for _, membership := range memberships { 151 if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), membership.TeamId, model.PERMISSION_DELETE_EMOJIS) { 152 hasPermission = true 153 break 154 } 155 } 156 if !hasPermission { 157 c.SetPermissionError(model.PERMISSION_DELETE_EMOJIS) 158 return 159 } 160 } 161 162 if c.AppContext.Session().UserId != emoji.CreatorId { 163 if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_DELETE_OTHERS_EMOJIS) { 164 hasPermission := false 165 for _, membership := range memberships { 166 if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), membership.TeamId, model.PERMISSION_DELETE_OTHERS_EMOJIS) { 167 hasPermission = true 168 break 169 } 170 } 171 172 if !hasPermission { 173 c.SetPermissionError(model.PERMISSION_DELETE_OTHERS_EMOJIS) 174 return 175 } 176 } 177 } 178 179 err = c.App.DeleteEmoji(emoji) 180 if err != nil { 181 c.Err = err 182 return 183 } 184 185 auditRec.Success() 186 187 ReturnStatusOK(w) 188 } 189 190 func getEmoji(c *Context, w http.ResponseWriter, r *http.Request) { 191 c.RequireEmojiId() 192 if c.Err != nil { 193 return 194 } 195 196 if !*c.App.Config().ServiceSettings.EnableCustomEmoji { 197 c.Err = model.NewAppError("getEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) 198 return 199 } 200 201 emoji, err := c.App.GetEmoji(c.Params.EmojiId) 202 if err != nil { 203 c.Err = err 204 return 205 } 206 207 w.Write([]byte(emoji.ToJson())) 208 } 209 210 func getEmojiByName(c *Context, w http.ResponseWriter, r *http.Request) { 211 c.RequireEmojiName() 212 if c.Err != nil { 213 return 214 } 215 216 emoji, err := c.App.GetEmojiByName(c.Params.EmojiName) 217 if err != nil { 218 c.Err = err 219 return 220 } 221 222 w.Write([]byte(emoji.ToJson())) 223 } 224 225 func getEmojiImage(c *Context, w http.ResponseWriter, r *http.Request) { 226 c.RequireEmojiId() 227 if c.Err != nil { 228 return 229 } 230 231 if !*c.App.Config().ServiceSettings.EnableCustomEmoji { 232 c.Err = model.NewAppError("getEmojiImage", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) 233 return 234 } 235 236 image, imageType, err := c.App.GetEmojiImage(c.Params.EmojiId) 237 if err != nil { 238 c.Err = err 239 return 240 } 241 242 w.Header().Set("Content-Type", "image/"+imageType) 243 w.Header().Set("Cache-Control", "max-age=2592000, private") 244 w.Write(image) 245 } 246 247 func searchEmojis(c *Context, w http.ResponseWriter, r *http.Request) { 248 emojiSearch := model.EmojiSearchFromJson(r.Body) 249 if emojiSearch == nil { 250 c.SetInvalidParam("term") 251 return 252 } 253 254 if emojiSearch.Term == "" { 255 c.SetInvalidParam("term") 256 return 257 } 258 259 emojis, err := c.App.SearchEmoji(emojiSearch.Term, emojiSearch.PrefixOnly, web.PerPageMaximum) 260 if err != nil { 261 c.Err = err 262 return 263 } 264 265 w.Write([]byte(model.EmojiListToJson(emojis))) 266 } 267 268 func autocompleteEmojis(c *Context, w http.ResponseWriter, r *http.Request) { 269 name := r.URL.Query().Get("name") 270 271 if name == "" { 272 c.SetInvalidUrlParam("name") 273 return 274 } 275 276 emojis, err := c.App.SearchEmoji(name, true, EmojiMaxAutocompleteItems) 277 if err != nil { 278 c.Err = err 279 return 280 } 281 282 w.Write([]byte(model.EmojiListToJson(emojis))) 283 }