Mono repo -> Master (#22553)
Combines the following repositories into one: https://github.com/mattermost/mattermost-server https://github.com/mattermost/mattermost-webapp https://github.com/mattermost/focalboard https://github.com/mattermost/mattermost-plugin-playbooks
Этот коммит содержится в:
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package localpermissions
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
permissionsMocks "github.com/mattermost/mattermost-server/v6/server/boards/services/permissions/mocks"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
t *testing.T
|
||||
ctrl *gomock.Controller
|
||||
store *permissionsMocks.MockStore
|
||||
permissions *Service
|
||||
}
|
||||
|
||||
func SetupTestHelper(t *testing.T) *TestHelper {
|
||||
ctrl := gomock.NewController(t)
|
||||
mockStore := permissionsMocks.NewMockStore(ctrl)
|
||||
return &TestHelper{
|
||||
t: t,
|
||||
ctrl: ctrl,
|
||||
store: mockStore,
|
||||
permissions: New(mockStore, mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)),
|
||||
}
|
||||
}
|
||||
|
||||
func (th *TestHelper) checkBoardPermissions(roleName string, member *model.BoardMember, hasPermissionTo, hasNotPermissionTo []*mm_model.Permission) {
|
||||
for _, p := range hasPermissionTo {
|
||||
th.t.Run(roleName+" "+p.Id, func(t *testing.T) {
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(member.BoardID, member.UserID).
|
||||
Return(member, nil).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(member.UserID, member.BoardID, p)
|
||||
assert.True(t, hasPermission)
|
||||
})
|
||||
}
|
||||
|
||||
for _, p := range hasNotPermissionTo {
|
||||
th.t.Run(roleName+" "+p.Id, func(t *testing.T) {
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(member.BoardID, member.UserID).
|
||||
Return(member, nil).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(member.UserID, member.BoardID, p)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package localpermissions
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/permissions"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
store permissions.Store
|
||||
logger mlog.LoggerIFace
|
||||
}
|
||||
|
||||
func New(store permissions.Store, logger mlog.LoggerIFace) *Service {
|
||||
return &Service{
|
||||
store: store,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionTo(userID string, permission *mm_model.Permission) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionToTeam(userID, teamID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || teamID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
if permission.Id == model.PermissionManageTeam.Id {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionToChannel(userID, channelID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || channelID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || boardID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
member, err := s.store.GetMemberForBoard(boardID, userID)
|
||||
if model.IsErrNotFound(err) {
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
s.logger.Error("error getting member for board",
|
||||
mlog.String("boardID", boardID),
|
||||
mlog.String("userID", userID),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
switch member.MinimumRole {
|
||||
case "admin":
|
||||
member.SchemeAdmin = true
|
||||
case "editor":
|
||||
member.SchemeEditor = true
|
||||
case "commenter":
|
||||
member.SchemeCommenter = true
|
||||
case "viewer":
|
||||
member.SchemeViewer = true
|
||||
}
|
||||
|
||||
switch permission {
|
||||
case model.PermissionManageBoardType, model.PermissionDeleteBoard, model.PermissionManageBoardRoles, model.PermissionShareBoard, model.PermissionDeleteOthersComments:
|
||||
return member.SchemeAdmin
|
||||
case model.PermissionManageBoardCards, model.PermissionManageBoardProperties:
|
||||
return member.SchemeAdmin || member.SchemeEditor
|
||||
case model.PermissionCommentBoardCards:
|
||||
return member.SchemeAdmin || member.SchemeEditor || member.SchemeCommenter
|
||||
case model.PermissionViewBoard:
|
||||
return member.SchemeAdmin || member.SchemeEditor || member.SchemeCommenter || member.SchemeViewer
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package localpermissions
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHasPermissionToTeam(t *testing.T) {
|
||||
th := SetupTestHelper(t)
|
||||
|
||||
t.Run("empty input should always unauthorize", func(t *testing.T) {
|
||||
assert.False(t, th.permissions.HasPermissionToTeam("", "team-id", model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToTeam("user-id", "", model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToTeam("user-id", "team-id", nil))
|
||||
})
|
||||
|
||||
t.Run("all users have all permissions on teams", func(t *testing.T) {
|
||||
hasPermission := th.permissions.HasPermissionToTeam("user-id", "team-id", model.PermissionManageBoardCards)
|
||||
assert.True(t, hasPermission)
|
||||
})
|
||||
|
||||
t.Run("no users have PermissionManageTeam on teams", func(t *testing.T) {
|
||||
hasPermission := th.permissions.HasPermissionToTeam("user-id", "team-id", model.PermissionManageTeam)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHasPermissionToBoard(t *testing.T) {
|
||||
th := SetupTestHelper(t)
|
||||
|
||||
t.Run("empty input should always unauthorize", func(t *testing.T) {
|
||||
assert.False(t, th.permissions.HasPermissionToBoard("", "board-id", model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToBoard("user-id", "", model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToBoard("user-id", "board-id", nil))
|
||||
})
|
||||
|
||||
t.Run("nonexistent user", func(t *testing.T) {
|
||||
userID := "user-id"
|
||||
boardID := "board-id"
|
||||
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(boardID, userID).
|
||||
Return(nil, sql.ErrNoRows).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(userID, boardID, model.PermissionManageBoardCards)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
|
||||
t.Run("board admin", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: "user-id",
|
||||
BoardID: "board-id",
|
||||
SchemeAdmin: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionViewBoard,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{}
|
||||
|
||||
th.checkBoardPermissions("admin", member, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("board editor", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: "user-id",
|
||||
BoardID: "board-id",
|
||||
SchemeEditor: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionViewBoard,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("editor", member, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("board commenter", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: "user-id",
|
||||
BoardID: "board-id",
|
||||
SchemeCommenter: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionViewBoard,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("commenter", member, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("board viewer", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: "user-id",
|
||||
BoardID: "board-id",
|
||||
SchemeViewer: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionViewBoard,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("viewer", member, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("Manage Team Permission ", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: "user-id",
|
||||
BoardID: "board-id",
|
||||
SchemeViewer: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionViewBoard,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("viewer", member, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
}
|
||||
101
server/boards/services/permissions/mmpermissions/helpers_test.go
Обычный файл
101
server/boards/services/permissions/mmpermissions/helpers_test.go
Обычный файл
@@ -0,0 +1,101 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mmpermissions
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
mmpermissionsMocks "github.com/mattermost/mattermost-server/v6/server/boards/services/permissions/mmpermissions/mocks"
|
||||
permissionsMocks "github.com/mattermost/mattermost-server/v6/server/boards/services/permissions/mocks"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
t *testing.T
|
||||
ctrl *gomock.Controller
|
||||
store *permissionsMocks.MockStore
|
||||
api *mmpermissionsMocks.MockAPI
|
||||
permissions *Service
|
||||
}
|
||||
|
||||
func SetupTestHelper(t *testing.T) *TestHelper {
|
||||
ctrl := gomock.NewController(t)
|
||||
mockStore := permissionsMocks.NewMockStore(ctrl)
|
||||
mockAPI := mmpermissionsMocks.NewMockAPI(ctrl)
|
||||
|
||||
return &TestHelper{
|
||||
t: t,
|
||||
ctrl: ctrl,
|
||||
store: mockStore,
|
||||
api: mockAPI,
|
||||
permissions: New(mockStore, mockAPI, mlog.CreateConsoleTestLogger(true, mlog.LvlError)),
|
||||
}
|
||||
}
|
||||
|
||||
func (th *TestHelper) checkBoardPermissions(roleName string, member *model.BoardMember, teamID string,
|
||||
hasPermissionTo, hasNotPermissionTo []*mm_model.Permission) {
|
||||
for _, p := range hasPermissionTo {
|
||||
th.t.Run(roleName+" "+p.Id, func(t *testing.T) {
|
||||
th.store.EXPECT().
|
||||
GetBoard(member.BoardID).
|
||||
Return(&model.Board{ID: member.BoardID, TeamID: teamID}, nil).
|
||||
Times(1)
|
||||
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(member.UserID, teamID, model.PermissionViewTeam).
|
||||
Return(true).
|
||||
Times(1)
|
||||
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(member.BoardID, member.UserID).
|
||||
Return(member, nil).
|
||||
Times(1)
|
||||
|
||||
if !member.SchemeAdmin {
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(member.UserID, teamID, model.PermissionManageTeam).
|
||||
Return(roleName == "elevated-admin").
|
||||
Times(1)
|
||||
}
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(member.UserID, member.BoardID, p)
|
||||
assert.True(t, hasPermission)
|
||||
})
|
||||
}
|
||||
|
||||
for _, p := range hasNotPermissionTo {
|
||||
th.t.Run(roleName+" "+p.Id, func(t *testing.T) {
|
||||
th.store.EXPECT().
|
||||
GetBoard(member.BoardID).
|
||||
Return(&model.Board{ID: member.BoardID, TeamID: teamID}, nil).
|
||||
Times(1)
|
||||
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(member.UserID, teamID, model.PermissionViewTeam).
|
||||
Return(true).
|
||||
Times(1)
|
||||
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(member.BoardID, member.UserID).
|
||||
Return(member, nil).
|
||||
Times(1)
|
||||
|
||||
if !member.SchemeAdmin {
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(member.UserID, teamID, model.PermissionManageTeam).
|
||||
Return(roleName == "elevated-admin").
|
||||
Times(1)
|
||||
}
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(member.UserID, member.BoardID, p)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
}
|
||||
}
|
||||
128
server/boards/services/permissions/mmpermissions/mmpermissions.go
Обычный файл
128
server/boards/services/permissions/mmpermissions/mmpermissions.go
Обычный файл
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mmpermissions
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/permissions"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
)
|
||||
|
||||
type APIInterface interface {
|
||||
HasPermissionTo(userID string, permission *mm_model.Permission) bool
|
||||
HasPermissionToTeam(userID string, teamID string, permission *mm_model.Permission) bool
|
||||
HasPermissionToChannel(userID string, channelID string, permission *mm_model.Permission) bool
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
store permissions.Store
|
||||
api APIInterface
|
||||
logger mlog.LoggerIFace
|
||||
}
|
||||
|
||||
func New(store permissions.Store, api APIInterface, logger mlog.LoggerIFace) *Service {
|
||||
return &Service{
|
||||
store: store,
|
||||
api: api,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionTo(userID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
return s.api.HasPermissionTo(userID, permission)
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionToTeam(userID, teamID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || teamID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
return s.api.HasPermissionToTeam(userID, teamID, permission)
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionToChannel(userID, channelID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || channelID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
return s.api.HasPermissionToChannel(userID, channelID, permission)
|
||||
}
|
||||
|
||||
func (s *Service) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
|
||||
if userID == "" || boardID == "" || permission == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
board, err := s.store.GetBoard(boardID)
|
||||
if model.IsErrNotFound(err) {
|
||||
var boards []*model.Board
|
||||
boards, err = s.store.GetBoardHistory(boardID, model.QueryBoardHistoryOptions{Limit: 1, Descending: true})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if len(boards) == 0 {
|
||||
return false
|
||||
}
|
||||
board = boards[0]
|
||||
} else if err != nil {
|
||||
s.logger.Error("error getting board",
|
||||
mlog.String("boardID", boardID),
|
||||
mlog.String("userID", userID),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
// we need to check that the user has permission to see the team
|
||||
// regardless of its local permissions to the board
|
||||
if !s.HasPermissionToTeam(userID, board.TeamID, model.PermissionViewTeam) {
|
||||
return false
|
||||
}
|
||||
member, err := s.store.GetMemberForBoard(boardID, userID)
|
||||
if model.IsErrNotFound(err) {
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
s.logger.Error("error getting member for board",
|
||||
mlog.String("boardID", boardID),
|
||||
mlog.String("userID", userID),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
switch member.MinimumRole {
|
||||
case "admin":
|
||||
member.SchemeAdmin = true
|
||||
case "editor":
|
||||
member.SchemeEditor = true
|
||||
case "commenter":
|
||||
member.SchemeCommenter = true
|
||||
case "viewer":
|
||||
member.SchemeViewer = true
|
||||
}
|
||||
|
||||
// Admins become member of boards, but get minimal role
|
||||
// if they are a System/Team Admin (model.PermissionManageTeam)
|
||||
// elevate their permissions
|
||||
if !member.SchemeAdmin && s.HasPermissionToTeam(userID, board.TeamID, model.PermissionManageTeam) {
|
||||
return true
|
||||
}
|
||||
|
||||
switch permission {
|
||||
case model.PermissionManageBoardType, model.PermissionDeleteBoard, model.PermissionManageBoardRoles, model.PermissionShareBoard, model.PermissionDeleteOthersComments:
|
||||
return member.SchemeAdmin
|
||||
case model.PermissionManageBoardCards, model.PermissionManageBoardProperties:
|
||||
return member.SchemeAdmin || member.SchemeEditor
|
||||
case model.PermissionCommentBoardCards:
|
||||
return member.SchemeAdmin || member.SchemeEditor || member.SchemeCommenter
|
||||
case model.PermissionViewBoard:
|
||||
return member.SchemeAdmin || member.SchemeEditor || member.SchemeCommenter || member.SchemeViewer
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
//go:generate mockgen -copyright_file=../../../../copyright.txt -destination=mocks/mockpluginapi.go -package mocks github.com/mattermost/mattermost-server/v6/plugin API
|
||||
package mmpermissions
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
testTeamID = "team-id"
|
||||
testBoardID = "board-id"
|
||||
testUserID = "user-id"
|
||||
)
|
||||
|
||||
func TestHasPermissionsToTeam(t *testing.T) {
|
||||
th := SetupTestHelper(t)
|
||||
|
||||
t.Run("empty input should always unauthorize", func(t *testing.T) {
|
||||
assert.False(t, th.permissions.HasPermissionToTeam("", testTeamID, model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToTeam(testUserID, "", model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToTeam(testUserID, testTeamID, nil))
|
||||
})
|
||||
|
||||
t.Run("should authorize if the plugin API does", func(t *testing.T) {
|
||||
userID := testUserID
|
||||
teamID := testTeamID
|
||||
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(userID, teamID, model.PermissionViewTeam).
|
||||
Return(true).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToTeam(userID, teamID, model.PermissionViewTeam)
|
||||
assert.True(t, hasPermission)
|
||||
})
|
||||
|
||||
t.Run("should not authorize if the plugin API doesn't", func(t *testing.T) {
|
||||
userID := testUserID
|
||||
teamID := testTeamID
|
||||
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(userID, teamID, model.PermissionViewTeam).
|
||||
Return(false).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToTeam(userID, teamID, model.PermissionViewTeam)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
}
|
||||
|
||||
// test case for user removed.
|
||||
func TestHasPermissionToBoard(t *testing.T) {
|
||||
th := SetupTestHelper(t)
|
||||
|
||||
t.Run("empty input should always unauthorize", func(t *testing.T) {
|
||||
assert.False(t, th.permissions.HasPermissionToBoard("", testBoardID, model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToBoard(testUserID, "", model.PermissionManageBoardCards))
|
||||
assert.False(t, th.permissions.HasPermissionToBoard(testUserID, testBoardID, nil))
|
||||
})
|
||||
|
||||
userID := testUserID
|
||||
boardID := testBoardID
|
||||
teamID := testTeamID
|
||||
|
||||
t.Run("nonexistent member", func(t *testing.T) {
|
||||
th.store.EXPECT().
|
||||
GetBoard(boardID).
|
||||
Return(&model.Board{ID: boardID, TeamID: teamID}, nil).
|
||||
Times(1)
|
||||
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(userID, teamID, model.PermissionViewTeam).
|
||||
Return(true).
|
||||
Times(1)
|
||||
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(boardID, userID).
|
||||
Return(nil, sql.ErrNoRows).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(userID, boardID, model.PermissionManageBoardCards)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
|
||||
t.Run("nonexistent board", func(t *testing.T) {
|
||||
th.store.EXPECT().
|
||||
GetBoard(boardID).
|
||||
Return(nil, sql.ErrNoRows).
|
||||
Times(1)
|
||||
|
||||
th.store.EXPECT().
|
||||
GetBoardHistory(boardID, model.QueryBoardHistoryOptions{Limit: 1, Descending: true}).
|
||||
Return(nil, sql.ErrNoRows).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(userID, boardID, model.PermissionManageBoardCards)
|
||||
assert.False(t, hasPermission)
|
||||
})
|
||||
|
||||
t.Run("user that has been removed from the team", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: userID,
|
||||
BoardID: boardID,
|
||||
SchemeAdmin: true,
|
||||
}
|
||||
|
||||
th.store.EXPECT().
|
||||
GetBoard(boardID).
|
||||
Return(&model.Board{ID: boardID, TeamID: teamID}, nil).
|
||||
Times(1)
|
||||
|
||||
th.api.EXPECT().
|
||||
HasPermissionToTeam(userID, teamID, model.PermissionViewTeam).
|
||||
Return(true).
|
||||
Times(1)
|
||||
|
||||
th.store.EXPECT().
|
||||
GetMemberForBoard(member.BoardID, member.UserID).
|
||||
Return(member, nil).
|
||||
Times(1)
|
||||
|
||||
hasPermission := th.permissions.HasPermissionToBoard(member.UserID, member.BoardID, model.PermissionViewBoard)
|
||||
assert.True(t, hasPermission)
|
||||
})
|
||||
|
||||
t.Run("board admin", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: userID,
|
||||
BoardID: boardID,
|
||||
SchemeAdmin: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionViewBoard,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{}
|
||||
|
||||
th.checkBoardPermissions("admin", member, teamID, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("board editor", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: userID,
|
||||
BoardID: boardID,
|
||||
SchemeEditor: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionViewBoard,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("editor", member, teamID, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("board commenter", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: userID,
|
||||
BoardID: boardID,
|
||||
SchemeCommenter: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionViewBoard,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("commenter", member, teamID, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("board viewer", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: userID,
|
||||
BoardID: boardID,
|
||||
SchemeViewer: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionViewBoard,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
th.checkBoardPermissions("viewer", member, teamID, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
|
||||
t.Run("elevate board viewer permissions", func(t *testing.T) {
|
||||
member := &model.BoardMember{
|
||||
UserID: userID,
|
||||
BoardID: boardID,
|
||||
SchemeViewer: true,
|
||||
}
|
||||
|
||||
hasPermissionTo := []*mm_model.Permission{
|
||||
model.PermissionManageBoardType,
|
||||
model.PermissionDeleteBoard,
|
||||
model.PermissionManageBoardRoles,
|
||||
model.PermissionShareBoard,
|
||||
model.PermissionManageBoardCards,
|
||||
model.PermissionViewBoard,
|
||||
model.PermissionManageBoardProperties,
|
||||
}
|
||||
|
||||
hasNotPermissionTo := []*mm_model.Permission{}
|
||||
th.checkBoardPermissions("elevated-admin", member, teamID, hasPermissionTo, hasNotPermissionTo)
|
||||
})
|
||||
}
|
||||
2659
server/boards/services/permissions/mmpermissions/mocks/mockpluginapi.go
Обычный файл
2659
server/boards/services/permissions/mmpermissions/mocks/mockpluginapi.go
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
83
server/boards/services/permissions/mocks/mockstore.go
Обычный файл
83
server/boards/services/permissions/mocks/mockstore.go
Обычный файл
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/mattermost/mattermost-server/v6/server/boards/services/permissions (interfaces: Store)
|
||||
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
model "github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
)
|
||||
|
||||
// MockStore is a mock of Store interface.
|
||||
type MockStore struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockStoreMockRecorder
|
||||
}
|
||||
|
||||
// MockStoreMockRecorder is the mock recorder for MockStore.
|
||||
type MockStoreMockRecorder struct {
|
||||
mock *MockStore
|
||||
}
|
||||
|
||||
// NewMockStore creates a new mock instance.
|
||||
func NewMockStore(ctrl *gomock.Controller) *MockStore {
|
||||
mock := &MockStore{ctrl: ctrl}
|
||||
mock.recorder = &MockStoreMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockStore) EXPECT() *MockStoreMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetBoard mocks base method.
|
||||
func (m *MockStore) GetBoard(arg0 string) (*model.Board, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBoard", arg0)
|
||||
ret0, _ := ret[0].(*model.Board)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetBoard indicates an expected call of GetBoard.
|
||||
func (mr *MockStoreMockRecorder) GetBoard(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBoard", reflect.TypeOf((*MockStore)(nil).GetBoard), arg0)
|
||||
}
|
||||
|
||||
// GetBoardHistory mocks base method.
|
||||
func (m *MockStore) GetBoardHistory(arg0 string, arg1 model.QueryBoardHistoryOptions) ([]*model.Board, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBoardHistory", arg0, arg1)
|
||||
ret0, _ := ret[0].([]*model.Board)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetBoardHistory indicates an expected call of GetBoardHistory.
|
||||
func (mr *MockStoreMockRecorder) GetBoardHistory(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBoardHistory", reflect.TypeOf((*MockStore)(nil).GetBoardHistory), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetMemberForBoard mocks base method.
|
||||
func (m *MockStore) GetMemberForBoard(arg0, arg1 string) (*model.BoardMember, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMemberForBoard", arg0, arg1)
|
||||
ret0, _ := ret[0].(*model.BoardMember)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetMemberForBoard indicates an expected call of GetMemberForBoard.
|
||||
func (mr *MockStoreMockRecorder) GetMemberForBoard(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMemberForBoard", reflect.TypeOf((*MockStore)(nil).GetMemberForBoard), arg0, arg1)
|
||||
}
|
||||
25
server/boards/services/permissions/permissions.go
Обычный файл
25
server/boards/services/permissions/permissions.go
Обычный файл
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
//go:generate mockgen -copyright_file=../../../copyright.txt -destination=mocks/mockstore.go -package mocks . Store
|
||||
|
||||
package permissions
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type PermissionsService interface {
|
||||
HasPermissionTo(userID string, permission *mm_model.Permission) bool
|
||||
HasPermissionToTeam(userID, teamID string, permission *mm_model.Permission) bool
|
||||
HasPermissionToChannel(userID, channelID string, permission *mm_model.Permission) bool
|
||||
HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
GetBoard(boardID string) (*model.Board, error)
|
||||
GetMemberForBoard(boardID, userID string) (*model.BoardMember, error)
|
||||
GetBoardHistory(boardID string, opts model.QueryBoardHistoryOptions) ([]*model.Board, error)
|
||||
}
|
||||
Ссылка в новой задаче
Block a user