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  }