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  }