Team Guardian: Refactor it to remove the bus dependency (#43058)

* Refactor team guardian to avoid to use bus

* Fix lint

* Fix lint
This commit is contained in:
Selene
2022-01-07 13:38:00 +01:00
committed by GitHub
parent f2336fd981
commit 32ed680fc2
10 changed files with 155 additions and 69 deletions
@@ -0,0 +1,22 @@
package database
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
type TeamGuardianStoreImpl struct{}
func ProvideTeamGuardianStore() *TeamGuardianStoreImpl {
return &TeamGuardianStoreImpl{}
}
func (t *TeamGuardianStoreImpl) GetTeamMembers(ctx context.Context, query models.GetTeamMembersQuery) ([]*models.TeamMemberDTO, error) {
if err := sqlstore.GetTeamMembers(ctx, &query); err != nil {
return nil, err
}
return query.Result, nil
}
@@ -0,0 +1,17 @@
package database
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/mock"
)
type TeamGuardianStoreMock struct {
mock.Mock
}
func (t *TeamGuardianStoreMock) GetTeamMembers(ctx context.Context, query models.GetTeamMembersQuery) ([]*models.TeamMemberDTO, error) {
args := t.Called(ctx, query)
return args.Get(0).([]*models.TeamMemberDTO), args.Error(1)
}
@@ -0,0 +1,45 @@
package manager
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/teamguardian"
)
type Service struct {
store teamguardian.Store
}
func ProvideService(store teamguardian.Store) *Service {
return &Service{store: store}
}
func (s *Service) CanAdmin(ctx context.Context, orgId int64, teamId int64, user *models.SignedInUser) error {
if user.OrgRole == models.ROLE_ADMIN {
return nil
}
if user.OrgId != orgId {
return models.ErrNotAllowedToUpdateTeamInDifferentOrg
}
cmd := models.GetTeamMembersQuery{
OrgId: orgId,
TeamId: teamId,
UserId: user.UserId,
}
results, err := s.store.GetTeamMembers(ctx, cmd)
if err != nil {
return err
}
for _, member := range results {
if member.UserId == user.UserId && member.Permission == models.PERMISSION_ADMIN {
return nil
}
}
return models.ErrNotAllowedToUpdateTeam
}
@@ -0,0 +1,17 @@
package manager
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/mock"
)
type TeamGuardianMock struct {
mock.Mock
}
func (t *TeamGuardianMock) CanAdmin(ctx context.Context, orgId int64, teamId int64, user *models.SignedInUser) error {
args := t.Called(ctx, orgId, teamId, user)
return args.Error(0)
}
@@ -1,19 +1,20 @@
package teamguardian
package manager
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/teamguardian/database"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func TestUpdateTeam(t *testing.T) {
t.Run("Updating a team", func(t *testing.T) {
bus.ClearBusHandlers()
store := new(database.TeamGuardianStoreMock)
teamGuardianService := ProvideService(store)
t.Run("Updating a team", func(t *testing.T) {
admin := models.SignedInUser{
UserId: 1,
OrgId: 1,
@@ -31,58 +32,55 @@ func TestUpdateTeam(t *testing.T) {
t.Run("Given an editor and a team he isn't a member of", func(t *testing.T) {
t.Run("Should not be able to update the team", func(t *testing.T) {
bus.AddHandler("test", func(ctx context.Context, cmd *models.GetTeamMembersQuery) error {
cmd.Result = []*models.TeamMemberDTO{}
return nil
})
err := CanAdmin(context.Background(), bus.GetBus(), testTeam.OrgId, testTeam.Id, &editor)
ctx := context.Background()
store.On("GetTeamMembers", ctx, mock.Anything).Return([]*models.TeamMemberDTO{}, nil).Once()
err := teamGuardianService.CanAdmin(ctx, testTeam.OrgId, testTeam.Id, &editor)
require.Equal(t, models.ErrNotAllowedToUpdateTeam, err)
})
})
t.Run("Given an editor and a team he is an admin in", func(t *testing.T) {
t.Run("Should be able to update the team", func(t *testing.T) {
bus.AddHandler("test", func(ctx context.Context, cmd *models.GetTeamMembersQuery) error {
cmd.Result = []*models.TeamMemberDTO{{
OrgId: testTeam.OrgId,
TeamId: testTeam.Id,
UserId: editor.UserId,
Permission: models.PERMISSION_ADMIN,
}}
return nil
})
ctx := context.Background()
err := CanAdmin(context.Background(), bus.GetBus(), testTeam.OrgId, testTeam.Id, &editor)
result := []*models.TeamMemberDTO{{
OrgId: testTeam.OrgId,
TeamId: testTeam.Id,
UserId: editor.UserId,
Permission: models.PERMISSION_ADMIN,
}}
store.On("GetTeamMembers", ctx, mock.Anything).Return(result, nil).Once()
err := teamGuardianService.CanAdmin(ctx, testTeam.OrgId, testTeam.Id, &editor)
require.NoError(t, err)
})
})
t.Run("Given an editor and a team in another org", func(t *testing.T) {
ctx := context.Background()
testTeamOtherOrg := models.Team{
Id: 1,
OrgId: 2,
}
t.Run("Shouldn't be able to update the team", func(t *testing.T) {
bus.AddHandler("test", func(ctx context.Context, cmd *models.GetTeamMembersQuery) error {
cmd.Result = []*models.TeamMemberDTO{{
OrgId: testTeamOtherOrg.OrgId,
TeamId: testTeamOtherOrg.Id,
UserId: editor.UserId,
Permission: models.PERMISSION_ADMIN,
}}
return nil
})
result := []*models.TeamMemberDTO{{
OrgId: testTeamOtherOrg.OrgId,
TeamId: testTeamOtherOrg.Id,
UserId: editor.UserId,
Permission: models.PERMISSION_ADMIN,
}}
err := CanAdmin(context.Background(), bus.GetBus(), testTeamOtherOrg.OrgId, testTeamOtherOrg.Id, &editor)
store.On("GetTeamMembers", ctx, mock.Anything).Return(result, nil).Once()
err := teamGuardianService.CanAdmin(ctx, testTeamOtherOrg.OrgId, testTeamOtherOrg.Id, &editor)
require.Equal(t, models.ErrNotAllowedToUpdateTeamInDifferentOrg, err)
})
})
t.Run("Given an org admin and a team", func(t *testing.T) {
t.Run("Should be able to update the team", func(t *testing.T) {
err := CanAdmin(context.Background(), bus.GetBus(), testTeam.OrgId, testTeam.Id, &admin)
err := teamGuardianService.CanAdmin(context.Background(), testTeam.OrgId, testTeam.Id, &admin)
require.NoError(t, err)
})
})
+5 -26
View File
@@ -3,34 +3,13 @@ package teamguardian
import (
"context"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models"
)
func CanAdmin(ctx context.Context, bus bus.Bus, orgId int64, teamId int64, user *models.SignedInUser) error {
if user.OrgRole == models.ROLE_ADMIN {
return nil
}
type TeamGuardian interface {
CanAdmin(ctx context.Context, orgId int64, teamId int64, user *models.SignedInUser) error
}
if user.OrgId != orgId {
return models.ErrNotAllowedToUpdateTeamInDifferentOrg
}
cmd := models.GetTeamMembersQuery{
OrgId: orgId,
TeamId: teamId,
UserId: user.UserId,
}
if err := bus.Dispatch(ctx, &cmd); err != nil {
return err
}
for _, member := range cmd.Result {
if member.UserId == user.UserId && member.Permission == models.PERMISSION_ADMIN {
return nil
}
}
return models.ErrNotAllowedToUpdateTeam
type Store interface {
GetTeamMembers(ctx context.Context, query models.GetTeamMembersQuery) ([]*models.TeamMemberDTO, error)
}