1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2// See LICENSE.txt for license information. 3 4package app 5 6import ( 7 "context" 8 "net/http" 9 "strings" 10 11 "github.com/mattermost/mattermost-server/v6/model" 12 "github.com/mattermost/mattermost-server/v6/shared/mlog" 13) 14 15func (a *App) MakePermissionError(s *model.Session, permissions []*model.Permission) *model.AppError { 16 permissionsStr := "permission=" 17 for _, permission := range permissions { 18 permissionsStr += permission.Id 19 permissionsStr += "," 20 } 21 return model.NewAppError("Permissions", "api.context.permissions.app_error", nil, "userId="+s.UserId+", "+permissionsStr, http.StatusForbidden) 22} 23 24func (a *App) SessionHasPermissionTo(session model.Session, permission *model.Permission) bool { 25 if session.IsUnrestricted() { 26 return true 27 } 28 return a.RolesGrantPermission(session.GetUserRoles(), permission.Id) 29} 30 31func (a *App) SessionHasPermissionToAny(session model.Session, permissions []*model.Permission) bool { 32 for _, perm := range permissions { 33 if a.SessionHasPermissionTo(session, perm) { 34 return true 35 } 36 } 37 return false 38} 39 40func (a *App) SessionHasPermissionToTeam(session model.Session, teamID string, permission *model.Permission) bool { 41 if teamID == "" { 42 return false 43 } 44 if session.IsUnrestricted() { 45 return true 46 } 47 48 teamMember := session.GetTeamByTeamId(teamID) 49 if teamMember != nil { 50 if a.RolesGrantPermission(teamMember.GetRoles(), permission.Id) { 51 return true 52 } 53 } 54 55 return a.RolesGrantPermission(session.GetUserRoles(), permission.Id) 56} 57 58func (a *App) SessionHasPermissionToChannel(session model.Session, channelID string, permission *model.Permission) bool { 59 if channelID == "" { 60 return false 61 } 62 63 ids, err := a.Srv().Store.Channel().GetAllChannelMembersForUser(session.UserId, true, true) 64 65 var channelRoles []string 66 if err == nil { 67 if roles, ok := ids[channelID]; ok { 68 channelRoles = strings.Fields(roles) 69 if a.RolesGrantPermission(channelRoles, permission.Id) { 70 return true 71 } 72 } 73 } 74 75 channel, appErr := a.GetChannel(channelID) 76 if appErr != nil && appErr.StatusCode == http.StatusNotFound { 77 return false 78 } 79 80 if session.IsUnrestricted() { 81 return true 82 } 83 84 if appErr == nil && channel.TeamId != "" { 85 return a.SessionHasPermissionToTeam(session, channel.TeamId, permission) 86 } 87 88 return a.SessionHasPermissionTo(session, permission) 89} 90 91func (a *App) SessionHasPermissionToChannelByPost(session model.Session, postID string, permission *model.Permission) bool { 92 if channelMember, err := a.Srv().Store.Channel().GetMemberForPost(postID, session.UserId); err == nil { 93 94 if a.RolesGrantPermission(channelMember.GetRoles(), permission.Id) { 95 return true 96 } 97 } 98 99 if channel, err := a.Srv().Store.Channel().GetForPost(postID); err == nil { 100 if channel.TeamId != "" { 101 return a.SessionHasPermissionToTeam(session, channel.TeamId, permission) 102 } 103 } 104 105 return a.SessionHasPermissionTo(session, permission) 106} 107 108func (a *App) SessionHasPermissionToCategory(session model.Session, userID, teamID, categoryId string) bool { 109 if a.SessionHasPermissionTo(session, model.PermissionEditOtherUsers) { 110 return true 111 } 112 category, err := a.GetSidebarCategory(categoryId) 113 return err == nil && category != nil && category.UserId == session.UserId && category.UserId == userID && category.TeamId == teamID 114} 115 116func (a *App) SessionHasPermissionToUser(session model.Session, userID string) bool { 117 if userID == "" { 118 return false 119 } 120 if session.IsUnrestricted() { 121 return true 122 } 123 124 if session.UserId == userID { 125 return true 126 } 127 128 if a.SessionHasPermissionTo(session, model.PermissionEditOtherUsers) { 129 return true 130 } 131 132 return false 133} 134 135func (a *App) SessionHasPermissionToUserOrBot(session model.Session, userID string) bool { 136 if session.IsUnrestricted() { 137 return true 138 } 139 if a.SessionHasPermissionToUser(session, userID) { 140 return true 141 } 142 143 if err := a.SessionHasPermissionToManageBot(session, userID); err == nil { 144 return true 145 } 146 147 return false 148} 149 150func (a *App) HasPermissionTo(askingUserId string, permission *model.Permission) bool { 151 user, err := a.GetUser(askingUserId) 152 if err != nil { 153 return false 154 } 155 156 roles := user.GetRoles() 157 158 return a.RolesGrantPermission(roles, permission.Id) 159} 160 161func (a *App) HasPermissionToTeam(askingUserId string, teamID string, permission *model.Permission) bool { 162 if teamID == "" || askingUserId == "" { 163 return false 164 } 165 teamMember, _ := a.GetTeamMember(teamID, askingUserId) 166 if teamMember != nil && teamMember.DeleteAt == 0 { 167 if a.RolesGrantPermission(teamMember.GetRoles(), permission.Id) { 168 return true 169 } 170 } 171 return a.HasPermissionTo(askingUserId, permission) 172} 173 174func (a *App) HasPermissionToChannel(askingUserId string, channelID string, permission *model.Permission) bool { 175 if channelID == "" || askingUserId == "" { 176 return false 177 } 178 179 channelMember, err := a.GetChannelMember(context.Background(), channelID, askingUserId) 180 if err == nil { 181 roles := channelMember.GetRoles() 182 if a.RolesGrantPermission(roles, permission.Id) { 183 return true 184 } 185 } 186 187 var channel *model.Channel 188 channel, err = a.GetChannel(channelID) 189 if err == nil { 190 return a.HasPermissionToTeam(askingUserId, channel.TeamId, permission) 191 } 192 193 return a.HasPermissionTo(askingUserId, permission) 194} 195 196func (a *App) HasPermissionToChannelByPost(askingUserId string, postID string, permission *model.Permission) bool { 197 if channelMember, err := a.Srv().Store.Channel().GetMemberForPost(postID, askingUserId); err == nil { 198 if a.RolesGrantPermission(channelMember.GetRoles(), permission.Id) { 199 return true 200 } 201 } 202 203 if channel, err := a.Srv().Store.Channel().GetForPost(postID); err == nil { 204 return a.HasPermissionToTeam(askingUserId, channel.TeamId, permission) 205 } 206 207 return a.HasPermissionTo(askingUserId, permission) 208} 209 210func (a *App) HasPermissionToUser(askingUserId string, userID string) bool { 211 if askingUserId == userID { 212 return true 213 } 214 215 if a.HasPermissionTo(askingUserId, model.PermissionEditOtherUsers) { 216 return true 217 } 218 219 return false 220} 221 222func (a *App) RolesGrantPermission(roleNames []string, permissionId string) bool { 223 roles, err := a.GetRolesByNames(roleNames) 224 if err != nil { 225 // This should only happen if something is very broken. We can't realistically 226 // recover the situation, so deny permission and log an error. 227 mlog.Error("Failed to get roles from database with role names: "+strings.Join(roleNames, ",")+" ", mlog.Err(err)) 228 return false 229 } 230 231 for _, role := range roles { 232 if role.DeleteAt != 0 { 233 continue 234 } 235 236 permissions := role.Permissions 237 for _, permission := range permissions { 238 if permission == permissionId { 239 return true 240 } 241 } 242 } 243 244 return false 245} 246 247// SessionHasPermissionToManageBot returns nil if the session has access to manage the given bot. 248// This function deviates from other authorization checks in returning an error instead of just 249// a boolean, allowing the permission failure to be exposed with more granularity. 250func (a *App) SessionHasPermissionToManageBot(session model.Session, botUserId string) *model.AppError { 251 existingBot, err := a.GetBot(botUserId, true) 252 if err != nil { 253 return err 254 } 255 if session.IsUnrestricted() { 256 return nil 257 } 258 259 if existingBot.OwnerId == session.UserId { 260 if !a.SessionHasPermissionTo(session, model.PermissionManageBots) { 261 if !a.SessionHasPermissionTo(session, model.PermissionReadBots) { 262 // If the user doesn't have permission to read bots, pretend as if 263 // the bot doesn't exist at all. 264 return model.MakeBotNotFoundError(botUserId) 265 } 266 return a.MakePermissionError(&session, []*model.Permission{model.PermissionManageBots}) 267 } 268 } else { 269 if !a.SessionHasPermissionTo(session, model.PermissionManageOthersBots) { 270 if !a.SessionHasPermissionTo(session, model.PermissionReadOthersBots) { 271 // If the user doesn't have permission to read others' bots, 272 // pretend as if the bot doesn't exist at all. 273 return model.MakeBotNotFoundError(botUserId) 274 } 275 return a.MakePermissionError(&session, []*model.Permission{model.PermissionManageOthersBots}) 276 } 277 } 278 279 return nil 280} 281 282func (a *App) HasPermissionToReadChannel(userID string, channel *model.Channel) bool { 283 return a.HasPermissionToChannel(userID, channel.Id, model.PermissionReadChannel) || (channel.Type == model.ChannelTypeOpen && a.HasPermissionToTeam(userID, channel.TeamId, model.PermissionReadPublicChannel)) 284} 285