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