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