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