1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2// See LICENSE.txt for license information. 3 4package api4 5 6import ( 7 "encoding/json" 8 "net/http" 9 10 "github.com/mattermost/mattermost-server/v6/audit" 11 "github.com/mattermost/mattermost-server/v6/model" 12 "github.com/mattermost/mattermost-server/v6/shared/mlog" 13) 14 15func getCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 16 c.RequireUserId().RequireTeamId() 17 if c.Err != nil { 18 return 19 } 20 21 if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { 22 c.SetPermissionError(model.PermissionEditOtherUsers) 23 return 24 } 25 26 categories, err := c.App.GetSidebarCategories(c.Params.UserId, c.Params.TeamId) 27 if err != nil { 28 c.Err = err 29 return 30 } 31 32 categoriesJSON, jsonErr := json.Marshal(categories) 33 if jsonErr != nil { 34 c.Err = model.NewAppError("getCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) 35 return 36 } 37 38 w.Write(categoriesJSON) 39} 40 41func createCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 42 c.RequireUserId().RequireTeamId() 43 if c.Err != nil { 44 return 45 } 46 47 if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { 48 c.SetPermissionError(model.PermissionEditOtherUsers) 49 return 50 } 51 52 auditRec := c.MakeAuditRecord("createCategoryForTeamForUser", audit.Fail) 53 defer c.LogAuditRec(auditRec) 54 55 var categoryCreateRequest *model.SidebarCategoryWithChannels 56 err := json.NewDecoder(r.Body).Decode(&categoryCreateRequest) 57 if err != nil || c.Params.UserId != categoryCreateRequest.UserId || c.Params.TeamId != categoryCreateRequest.TeamId { 58 c.SetInvalidParam("category") 59 return 60 } 61 62 if appErr := validateSidebarCategory(c, c.Params.TeamId, c.Params.UserId, categoryCreateRequest); appErr != nil { 63 c.Err = appErr 64 return 65 } 66 67 category, appErr := c.App.CreateSidebarCategory(c.Params.UserId, c.Params.TeamId, categoryCreateRequest) 68 if appErr != nil { 69 c.Err = appErr 70 return 71 } 72 73 categoryJSON, jsonErr := json.Marshal(category) 74 if jsonErr != nil { 75 c.Err = model.NewAppError("createCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) 76 return 77 } 78 79 auditRec.Success() 80 81 w.Write(categoryJSON) 82} 83 84func getCategoryOrderForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 85 c.RequireUserId().RequireTeamId() 86 if c.Err != nil { 87 return 88 } 89 90 if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { 91 c.SetPermissionError(model.PermissionEditOtherUsers) 92 return 93 } 94 95 order, err := c.App.GetSidebarCategoryOrder(c.Params.UserId, c.Params.TeamId) 96 if err != nil { 97 c.Err = err 98 return 99 } 100 101 w.Write([]byte(model.ArrayToJSON(order))) 102} 103 104func updateCategoryOrderForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 105 c.RequireUserId().RequireTeamId() 106 if c.Err != nil { 107 return 108 } 109 110 if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { 111 c.SetPermissionError(model.PermissionEditOtherUsers) 112 return 113 } 114 115 auditRec := c.MakeAuditRecord("updateCategoryOrderForTeamForUser", audit.Fail) 116 defer c.LogAuditRec(auditRec) 117 118 categoryOrder := model.ArrayFromJSON(r.Body) 119 120 for _, categoryId := range categoryOrder { 121 if !c.App.SessionHasPermissionToCategory(*c.AppContext.Session(), c.Params.UserId, c.Params.TeamId, categoryId) { 122 c.SetInvalidParam("category") 123 return 124 } 125 } 126 127 err := c.App.UpdateSidebarCategoryOrder(c.Params.UserId, c.Params.TeamId, categoryOrder) 128 if err != nil { 129 c.Err = err 130 return 131 } 132 133 auditRec.Success() 134 w.Write([]byte(model.ArrayToJSON(categoryOrder))) 135} 136 137func getCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 138 c.RequireUserId().RequireTeamId().RequireCategoryId() 139 if c.Err != nil { 140 return 141 } 142 143 if !c.App.SessionHasPermissionToCategory(*c.AppContext.Session(), c.Params.UserId, c.Params.TeamId, c.Params.CategoryId) { 144 c.SetPermissionError(model.PermissionEditOtherUsers) 145 return 146 } 147 148 categories, err := c.App.GetSidebarCategory(c.Params.CategoryId) 149 if err != nil { 150 c.Err = err 151 return 152 } 153 154 categoriesJSON, jsonErr := json.Marshal(categories) 155 if jsonErr != nil { 156 c.Err = model.NewAppError("getCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) 157 return 158 } 159 160 w.Write(categoriesJSON) 161} 162 163func updateCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 164 c.RequireUserId().RequireTeamId() 165 if c.Err != nil { 166 return 167 } 168 169 if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { 170 c.SetPermissionError(model.PermissionEditOtherUsers) 171 return 172 } 173 174 auditRec := c.MakeAuditRecord("updateCategoriesForTeamForUser", audit.Fail) 175 defer c.LogAuditRec(auditRec) 176 177 var categoriesUpdateRequest []*model.SidebarCategoryWithChannels 178 err := json.NewDecoder(r.Body).Decode(&categoriesUpdateRequest) 179 if err != nil { 180 c.SetInvalidParam("category") 181 return 182 } 183 184 for _, category := range categoriesUpdateRequest { 185 if !c.App.SessionHasPermissionToCategory(*c.AppContext.Session(), c.Params.UserId, c.Params.TeamId, category.Id) { 186 c.SetInvalidParam("category") 187 return 188 } 189 } 190 191 if appErr := validateSidebarCategories(c, c.Params.TeamId, c.Params.UserId, categoriesUpdateRequest); appErr != nil { 192 c.Err = appErr 193 return 194 } 195 196 categories, appErr := c.App.UpdateSidebarCategories(c.Params.UserId, c.Params.TeamId, categoriesUpdateRequest) 197 if appErr != nil { 198 c.Err = appErr 199 return 200 } 201 202 categoriesJSON, jsonErr := json.Marshal(categories) 203 if jsonErr != nil { 204 c.Err = model.NewAppError("updateCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) 205 return 206 } 207 208 auditRec.Success() 209 w.Write(categoriesJSON) 210} 211 212func validateSidebarCategory(c *Context, teamId, userId string, category *model.SidebarCategoryWithChannels) *model.AppError { 213 channels, err := c.App.GetChannelsForUser(teamId, userId, true, 0) 214 if err != nil { 215 return model.NewAppError("validateSidebarCategory", "api.invalid_channel", nil, err.Error(), http.StatusBadRequest) 216 } 217 218 category.Channels = validateSidebarCategoryChannels(userId, category.Channels, channels) 219 220 return nil 221} 222 223func validateSidebarCategories(c *Context, teamId, userId string, categories []*model.SidebarCategoryWithChannels) *model.AppError { 224 channels, err := c.App.GetChannelsForUser(teamId, userId, true, 0) 225 if err != nil { 226 return model.NewAppError("validateSidebarCategory", "api.invalid_channel", nil, err.Error(), http.StatusBadRequest) 227 } 228 229 for _, category := range categories { 230 category.Channels = validateSidebarCategoryChannels(userId, category.Channels, channels) 231 } 232 233 return nil 234} 235 236func validateSidebarCategoryChannels(userId string, channelIds []string, channels model.ChannelList) []string { 237 var filtered []string 238 239 for _, channelId := range channelIds { 240 found := false 241 for _, channel := range channels { 242 if channel.Id == channelId { 243 found = true 244 break 245 } 246 } 247 248 if found { 249 filtered = append(filtered, channelId) 250 } else { 251 mlog.Info("Stopping user from adding channel to their sidebar when they are not a member", mlog.String("user_id", userId), mlog.String("channel_id", channelId)) 252 } 253 } 254 255 return filtered 256} 257 258func updateCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 259 c.RequireUserId().RequireTeamId().RequireCategoryId() 260 if c.Err != nil { 261 return 262 } 263 264 if !c.App.SessionHasPermissionToCategory(*c.AppContext.Session(), c.Params.UserId, c.Params.TeamId, c.Params.CategoryId) { 265 c.SetPermissionError(model.PermissionEditOtherUsers) 266 return 267 } 268 269 auditRec := c.MakeAuditRecord("updateCategoryForTeamForUser", audit.Fail) 270 defer c.LogAuditRec(auditRec) 271 272 var categoryUpdateRequest *model.SidebarCategoryWithChannels 273 err := json.NewDecoder(r.Body).Decode(&categoryUpdateRequest) 274 if err != nil || categoryUpdateRequest.TeamId != c.Params.TeamId || categoryUpdateRequest.UserId != c.Params.UserId { 275 c.SetInvalidParam("category") 276 return 277 } 278 279 if appErr := validateSidebarCategory(c, c.Params.TeamId, c.Params.UserId, categoryUpdateRequest); appErr != nil { 280 c.Err = appErr 281 return 282 } 283 284 categoryUpdateRequest.Id = c.Params.CategoryId 285 286 categories, appErr := c.App.UpdateSidebarCategories(c.Params.UserId, c.Params.TeamId, []*model.SidebarCategoryWithChannels{categoryUpdateRequest}) 287 if appErr != nil { 288 c.Err = appErr 289 return 290 } 291 292 categoryJSON, jsonErr := json.Marshal(categories[0]) 293 if jsonErr != nil { 294 c.Err = model.NewAppError("updateCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) 295 return 296 } 297 298 auditRec.Success() 299 w.Write(categoryJSON) 300} 301 302func deleteCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { 303 c.RequireUserId().RequireTeamId().RequireCategoryId() 304 if c.Err != nil { 305 return 306 } 307 308 if !c.App.SessionHasPermissionToCategory(*c.AppContext.Session(), c.Params.UserId, c.Params.TeamId, c.Params.CategoryId) { 309 c.SetPermissionError(model.PermissionEditOtherUsers) 310 return 311 } 312 313 auditRec := c.MakeAuditRecord("deleteCategoryForTeamForUser", audit.Fail) 314 defer c.LogAuditRec(auditRec) 315 316 appErr := c.App.DeleteSidebarCategory(c.Params.UserId, c.Params.TeamId, c.Params.CategoryId) 317 if appErr != nil { 318 c.Err = appErr 319 return 320 } 321 322 auditRec.Success() 323 ReturnStatusOK(w) 324} 325