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  }