github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/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/vnforks/kid/v5/mlog"
    11  	"github.com/vnforks/kid/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  	return a.RolesGrantPermission(session.GetUserRoles(), permission.Id)
    20  }
    21  
    22  func (a *App) SessionHasPermissionToBranch(session model.Session, branchId string, permission *model.Permission) bool {
    23  	if branchId == "" {
    24  		return false
    25  	}
    26  
    27  	branchMember := session.GetBranchByBranchId(branchId)
    28  	if branchMember != nil {
    29  		if a.RolesGrantPermission(branchMember.GetRoles(), permission.Id) {
    30  			return true
    31  		}
    32  	}
    33  
    34  	return a.RolesGrantPermission(session.GetUserRoles(), permission.Id)
    35  }
    36  
    37  func (a *App) SessionHasPermissionToClass(session model.Session, classId string, permission *model.Permission) bool {
    38  	if classId == "" {
    39  		return false
    40  	}
    41  
    42  	ids, err := a.Srv().Store.Class().GetAllClassMembersForUser(session.UserId, true, true)
    43  
    44  	var classRoles []string
    45  	if err == nil {
    46  		if roles, ok := ids[classId]; ok {
    47  			classRoles = strings.Fields(roles)
    48  			if a.RolesGrantPermission(classRoles, permission.Id) {
    49  				return true
    50  			}
    51  		}
    52  	}
    53  
    54  	class, err := a.GetClass(classId)
    55  	if err == nil && class.BranchId != "" {
    56  		return a.SessionHasPermissionToBranch(session, class.BranchId, permission)
    57  	}
    58  
    59  	if err != nil && err.StatusCode == http.StatusNotFound {
    60  		return false
    61  	}
    62  
    63  	return a.SessionHasPermissionTo(session, permission)
    64  }
    65  
    66  func (a *App) SessionHasPermissionToClassByPost(session model.Session, postId string, permission *model.Permission) bool {
    67  	if classMember, err := a.Srv().Store.Class().GetMemberForPost(postId, session.UserId); err == nil {
    68  
    69  		if a.RolesGrantPermission(classMember.GetRoles(), permission.Id) {
    70  			return true
    71  		}
    72  	}
    73  
    74  	if class, err := a.Srv().Store.Class().GetForPost(postId); err == nil {
    75  		if class.BranchId != "" {
    76  			return a.SessionHasPermissionToBranch(session, class.BranchId, permission)
    77  		}
    78  	}
    79  
    80  	return a.SessionHasPermissionTo(session, permission)
    81  }
    82  
    83  func (a *App) SessionHasPermissionToUser(session model.Session, userId string) bool {
    84  	if userId == "" {
    85  		return false
    86  	}
    87  
    88  	if session.UserId == userId {
    89  		return true
    90  	}
    91  
    92  	if a.SessionHasPermissionTo(session, model.PERMISSION_EDIT_OTHER_USERS) {
    93  		return true
    94  	}
    95  
    96  	return false
    97  }
    98  
    99  func (a *App) HasPermissionTo(askingUserId string, permission *model.Permission) bool {
   100  	user, err := a.GetUser(askingUserId)
   101  	if err != nil {
   102  		return false
   103  	}
   104  
   105  	roles := user.GetRoles()
   106  
   107  	return a.RolesGrantPermission(roles, permission.Id)
   108  }
   109  
   110  func (a *App) HasPermissionToBranch(askingUserId string, branchId string, permission *model.Permission) bool {
   111  	if branchId == "" || askingUserId == "" {
   112  		return false
   113  	}
   114  
   115  	branchMember, err := a.GetBranchMember(branchId, askingUserId)
   116  	if err != nil {
   117  		return false
   118  	}
   119  
   120  	roles := branchMember.GetRoles()
   121  
   122  	if a.RolesGrantPermission(roles, permission.Id) {
   123  		return true
   124  	}
   125  
   126  	return a.HasPermissionTo(askingUserId, permission)
   127  }
   128  
   129  func (a *App) HasPermissionToClass(askingUserId string, classId string, permission *model.Permission) bool {
   130  	if classId == "" || askingUserId == "" {
   131  		return false
   132  	}
   133  
   134  	classMember, err := a.GetClassMember(classId, askingUserId)
   135  	if err == nil {
   136  		roles := classMember.GetRoles()
   137  		if a.RolesGrantPermission(roles, permission.Id) {
   138  			return true
   139  		}
   140  	}
   141  
   142  	var class *model.Class
   143  	class, err = a.GetClass(classId)
   144  	if err == nil {
   145  		return a.HasPermissionToBranch(askingUserId, class.BranchId, permission)
   146  	}
   147  
   148  	return a.HasPermissionTo(askingUserId, permission)
   149  }
   150  
   151  func (a *App) HasPermissionToUser(askingUserId string, userId string) bool {
   152  	if askingUserId == userId {
   153  		return true
   154  	}
   155  
   156  	if a.HasPermissionTo(askingUserId, model.PERMISSION_EDIT_OTHER_USERS) {
   157  		return true
   158  	}
   159  
   160  	return false
   161  }
   162  
   163  func (a *App) RolesGrantPermission(roleNames []string, permissionId string) bool {
   164  	roles, err := a.GetRolesByNames(roleNames)
   165  	if err != nil {
   166  		// This should only happen if something is very broken. We can't realistically
   167  		// recover the situation, so deny permission and log an error.
   168  		mlog.Error("Failed to get roles from database with role names: "+strings.Join(roleNames, ",")+" ", mlog.Err(err))
   169  		return false
   170  	}
   171  
   172  	for _, role := range roles {
   173  		if role.DeleteAt != 0 {
   174  			continue
   175  		}
   176  
   177  		permissions := role.Permissions
   178  		for _, permission := range permissions {
   179  			if permission == permissionId {
   180  				return true
   181  			}
   182  		}
   183  	}
   184  
   185  	return false
   186  }