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