Chore: Remove bus from team (#44218)

* Remove bus from team

* Fix api team test

* Remove bus from team members
This commit is contained in:
idafurjes
2022-01-24 11:52:35 +01:00
committed by GitHub
parent c8406baac2
commit 00c389933b
12 changed files with 126 additions and 123 deletions

View File

@ -149,8 +149,8 @@ func (hs *HTTPServer) registerRoutes() {
userRoute.Get("/orgs", routing.Wrap(GetSignedInUserOrgList)) userRoute.Get("/orgs", routing.Wrap(GetSignedInUserOrgList))
userRoute.Get("/teams", routing.Wrap(GetSignedInUserTeamList)) userRoute.Get("/teams", routing.Wrap(GetSignedInUserTeamList))
userRoute.Post("/stars/dashboard/:id", routing.Wrap(StarDashboard)) userRoute.Post("/stars/dashboard/:id", routing.Wrap(hs.StarDashboard))
userRoute.Delete("/stars/dashboard/:id", routing.Wrap(UnstarDashboard)) userRoute.Delete("/stars/dashboard/:id", routing.Wrap(hs.UnstarDashboard))
userRoute.Put("/password", routing.Wrap(ChangeUserPassword)) userRoute.Put("/password", routing.Wrap(ChangeUserPassword))
userRoute.Get("/quotas", routing.Wrap(GetUserQuotas)) userRoute.Get("/quotas", routing.Wrap(GetUserQuotas))

View File

@ -5,12 +5,11 @@ import (
"strconv" "strconv"
"github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
) )
func StarDashboard(c *models.ReqContext) response.Response { func (hs *HTTPServer) StarDashboard(c *models.ReqContext) response.Response {
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64) id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil { if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err) return response.Error(http.StatusBadRequest, "id is invalid", err)
@ -21,14 +20,14 @@ func StarDashboard(c *models.ReqContext) response.Response {
return response.Error(400, "Missing dashboard id", nil) return response.Error(400, "Missing dashboard id", nil)
} }
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil { if err := hs.SQLStore.StarDashboard(c.Req.Context(), &cmd); err != nil {
return response.Error(500, "Failed to star dashboard", err) return response.Error(500, "Failed to star dashboard", err)
} }
return response.Success("Dashboard starred!") return response.Success("Dashboard starred!")
} }
func UnstarDashboard(c *models.ReqContext) response.Response { func (hs *HTTPServer) UnstarDashboard(c *models.ReqContext) response.Response {
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64) id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil { if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err) return response.Error(http.StatusBadRequest, "id is invalid", err)
@ -39,7 +38,7 @@ func UnstarDashboard(c *models.ReqContext) response.Response {
return response.Error(400, "Missing dashboard id", nil) return response.Error(400, "Missing dashboard id", nil)
} }
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil { if err := hs.SQLStore.UnstarDashboard(c.Req.Context(), &cmd); err != nil {
return response.Error(500, "Failed to unstar dashboard", err) return response.Error(500, "Failed to unstar dashboard", err)
} }

View File

@ -7,7 +7,6 @@ import (
"github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
@ -70,7 +69,7 @@ func (hs *HTTPServer) UpdateTeam(c *models.ReqContext) response.Response {
return response.Error(403, "Not allowed to update team", err) return response.Error(403, "Not allowed to update team", err)
} }
if err := hs.Bus.Dispatch(c.Req.Context(), &cmd); err != nil { if err := hs.SQLStore.UpdateTeam(c.Req.Context(), &cmd); err != nil {
if errors.Is(err, models.ErrTeamNameTaken) { if errors.Is(err, models.ErrTeamNameTaken) {
return response.Error(400, "Team name taken", err) return response.Error(400, "Team name taken", err)
} }
@ -93,7 +92,7 @@ func (hs *HTTPServer) DeleteTeamByID(c *models.ReqContext) response.Response {
return response.Error(403, "Not allowed to delete team", err) return response.Error(403, "Not allowed to delete team", err)
} }
if err := hs.Bus.Dispatch(c.Req.Context(), &models.DeleteTeamCommand{OrgId: orgId, Id: teamId}); err != nil { if err := hs.SQLStore.DeleteTeam(c.Req.Context(), &models.DeleteTeamCommand{OrgId: orgId, Id: teamId}); err != nil {
if errors.Is(err, models.ErrTeamNotFound) { if errors.Is(err, models.ErrTeamNotFound) {
return response.Error(404, "Failed to delete Team. ID not found", nil) return response.Error(404, "Failed to delete Team. ID not found", nil)
} }
@ -129,7 +128,7 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response {
HiddenUsers: hs.Cfg.HiddenUsers, HiddenUsers: hs.Cfg.HiddenUsers,
} }
if err := bus.Dispatch(c.Req.Context(), &query); err != nil { if err := hs.SQLStore.SearchTeams(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to search Teams", err) return response.Error(500, "Failed to search Teams", err)
} }
@ -156,7 +155,7 @@ func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response {
HiddenUsers: hs.Cfg.HiddenUsers, HiddenUsers: hs.Cfg.HiddenUsers,
} }
if err := bus.Dispatch(c.Req.Context(), &query); err != nil { if err := hs.SQLStore.GetTeamById(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrTeamNotFound) { if errors.Is(err, models.ErrTeamNotFound) {
return response.Error(404, "Team not found", err) return response.Error(404, "Team not found", err)
} }

View File

@ -7,7 +7,6 @@ import (
"github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
@ -23,7 +22,7 @@ func (hs *HTTPServer) GetTeamMembers(c *models.ReqContext) response.Response {
query := models.GetTeamMembersQuery{OrgId: c.OrgId, TeamId: teamId} query := models.GetTeamMembersQuery{OrgId: c.OrgId, TeamId: teamId}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil { if err := hs.SQLStore.GetTeamMembers(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to get Team Members", err) return response.Error(500, "Failed to get Team Members", err)
} }
@ -109,7 +108,7 @@ func (hs *HTTPServer) UpdateTeamMember(c *models.ReqContext) response.Response {
} }
cmd.OrgId = orgId cmd.OrgId = orgId
if err := hs.Bus.Dispatch(c.Req.Context(), &cmd); err != nil { if err := hs.SQLStore.UpdateTeamMember(c.Req.Context(), &cmd); err != nil {
if errors.Is(err, models.ErrTeamMemberNotFound) { if errors.Is(err, models.ErrTeamMemberNotFound) {
return response.Error(404, "Team member not found.", nil) return response.Error(404, "Team member not found.", nil)
} }
@ -139,7 +138,7 @@ func (hs *HTTPServer) RemoveTeamMember(c *models.ReqContext) response.Response {
protectLastAdmin = true protectLastAdmin = true
} }
if err := hs.Bus.Dispatch(c.Req.Context(), &models.RemoveTeamMemberCommand{OrgId: orgId, TeamId: teamId, UserId: userId, ProtectLastAdmin: protectLastAdmin}); err != nil { if err := hs.SQLStore.RemoveTeamMember(c.Req.Context(), &models.RemoveTeamMemberCommand{OrgId: orgId, TeamId: teamId, UserId: userId, ProtectLastAdmin: protectLastAdmin}); err != nil {
if errors.Is(err, models.ErrTeamNotFound) { if errors.Is(err, models.ErrTeamNotFound) {
return response.Error(404, "Team not found", nil) return response.Error(404, "Team not found", nil)
} }

View File

@ -3,38 +3,49 @@ package api
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"testing" "testing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func setUpGetTeamMembersHandler() { func setUpGetTeamMembersHandler(t *testing.T, sqlStore *sqlstore.SQLStore) {
bus.AddHandler("test", func(ctx context.Context, query *models.GetTeamMembersQuery) error { const testOrgID int64 = 1
query.Result = []*models.TeamMemberDTO{ var userCmd models.CreateUserCommand
{Email: "testUser@grafana.com", Login: testUserLogin}, team, err := sqlStore.CreateTeam("group1 name", "test1@test.com", testOrgID)
{Email: "user1@grafana.com", Login: "user1"}, require.NoError(t, err)
{Email: "user2@grafana.com", Login: "user2"}, for i := 0; i < 3; i++ {
userCmd = models.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
} }
return nil // user
}) user, err := sqlStore.CreateUser(context.Background(), userCmd)
require.NoError(t, err)
err = sqlStore.AddTeamMember(user.Id, testOrgID, team.Id, false, 1)
require.NoError(t, err)
}
} }
func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) { func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) {
settings := setting.NewCfg() settings := setting.NewCfg()
sqlStore := sqlstore.InitTestDB(t)
hs := &HTTPServer{ hs := &HTTPServer{
Cfg: settings, Cfg: settings,
License: &licensing.OSSLicensingService{}, License: &licensing.OSSLicensingService{},
SQLStore: sqlStore,
} }
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "api/teams/1/members", loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "api/teams/1/members",
"api/teams/:teamId/members", models.ROLE_ADMIN, func(sc *scenarioContext) { "api/teams/:teamId/members", models.ROLE_ADMIN, func(sc *scenarioContext) {
setUpGetTeamMembersHandler() setUpGetTeamMembersHandler(t, sqlStore)
sc.handlerFunc = hs.GetTeamMembers sc.handlerFunc = hs.GetTeamMembers
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
@ -56,7 +67,7 @@ func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) {
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "api/teams/1/members", loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "api/teams/1/members",
"api/teams/:teamId/members", models.ROLE_ADMIN, func(sc *scenarioContext) { "api/teams/:teamId/members", models.ROLE_ADMIN, func(sc *scenarioContext) {
setUpGetTeamMembersHandler() setUpGetTeamMembersHandler(t, sqlStore)
sc.handlerFunc = hs.GetTeamMembers sc.handlerFunc = hs.GetTeamMembers
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
@ -66,9 +77,10 @@ func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) {
var resp []models.TeamMemberDTO var resp []models.TeamMemberDTO
err := json.Unmarshal(sc.resp.Body.Bytes(), &resp) err := json.Unmarshal(sc.resp.Body.Bytes(), &resp)
require.NoError(t, err) require.NoError(t, err)
assert.Len(t, resp, 2) assert.Len(t, resp, 3)
assert.Equal(t, testUserLogin, resp[0].Login) assert.Equal(t, "loginuser0", resp[0].Login)
assert.Equal(t, "user2", resp[1].Login) assert.Equal(t, "loginuser1", resp[1].Login)
assert.Equal(t, "loginuser2", resp[2].Login)
}) })
}) })
} }

View File

@ -1,14 +1,12 @@
package api package api
import ( import (
"context" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
"testing" "testing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol"
@ -32,64 +30,45 @@ func (stub *testLogger) Warn(testMessage string, ctx ...interface{}) {
func TestTeamAPIEndpoint(t *testing.T) { func TestTeamAPIEndpoint(t *testing.T) {
t.Run("Given two teams", func(t *testing.T) { t.Run("Given two teams", func(t *testing.T) {
mockResult := models.SearchTeamQueryResult{
Teams: []*models.TeamDTO{
{Name: "team1"},
{Name: "team2"},
},
TotalCount: 2,
}
hs := setupSimpleHTTPServer(nil) hs := setupSimpleHTTPServer(nil)
hs.SQLStore = sqlstore.InitTestDB(t)
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) { loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) {
var sentLimit int _, err := hs.SQLStore.CreateTeam("team1", "", 1)
var sendPage int require.NoError(t, err)
bus.AddHandler("test", func(ctx context.Context, query *models.SearchTeamsQuery) error { _, err = hs.SQLStore.CreateTeam("team2", "", 1)
query.Result = mockResult require.NoError(t, err)
sentLimit = query.Limit
sendPage = query.Page
return nil
})
sc.handlerFunc = hs.SearchTeams sc.handlerFunc = hs.SearchTeams
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
require.Equal(t, http.StatusOK, sc.resp.Code)
assert.Equal(t, 1000, sentLimit) var resp models.SearchTeamQueryResult
assert.Equal(t, 1, sendPage) err = json.Unmarshal(sc.resp.Body.Bytes(), &resp)
respJSON, err := simplejson.NewJson(sc.resp.Body.Bytes())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, 2, respJSON.Get("totalCount").MustInt()) assert.EqualValues(t, 2, resp.TotalCount)
assert.Equal(t, 2, len(respJSON.Get("teams").MustArray())) assert.Equal(t, 2, len(resp.Teams))
}) })
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) { loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) {
var sentLimit int _, err := hs.SQLStore.CreateTeam("team1", "", 1)
var sendPage int require.NoError(t, err)
bus.AddHandler("test", func(ctx context.Context, query *models.SearchTeamsQuery) error { _, err = hs.SQLStore.CreateTeam("team2", "", 1)
query.Result = mockResult require.NoError(t, err)
sentLimit = query.Limit
sendPage = query.Page
return nil
})
sc.handlerFunc = hs.SearchTeams sc.handlerFunc = hs.SearchTeams
sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec()
require.Equal(t, http.StatusOK, sc.resp.Code)
var resp models.SearchTeamQueryResult
err = json.Unmarshal(sc.resp.Body.Bytes(), &resp)
require.NoError(t, err)
assert.Equal(t, 10, sentLimit) assert.EqualValues(t, 2, resp.TotalCount)
assert.Equal(t, 2, sendPage) assert.Equal(t, 0, len(resp.Teams))
}) })
}) })
t.Run("When creating team with API key", func(t *testing.T) { t.Run("When creating team with API key", func(t *testing.T) {
defer bus.ClearBusHandlers()
hs := setupSimpleHTTPServer(nil) hs := setupSimpleHTTPServer(nil)
hs.Cfg.EditorsCanAdmin = true hs.Cfg.EditorsCanAdmin = true

View File

@ -12,7 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol"
) )
func New(options Options, router routing.RouteRegister, ac accesscontrol.AccessControl, store accesscontrol.ResourcePermissionsStore) (*Service, error) { func New(options Options, router routing.RouteRegister, ac accesscontrol.AccessControl, store accesscontrol.ResourcePermissionsStore, sqlStore *sqlstore.SQLStore) (*Service, error) {
var permissions []string var permissions []string
validActions := make(map[string]struct{}) validActions := make(map[string]struct{})
for permission, actions := range options.PermissionsToActions { for permission, actions := range options.PermissionsToActions {
@ -39,6 +39,7 @@ func New(options Options, router routing.RouteRegister, ac accesscontrol.AccessC
permissions: permissions, permissions: permissions,
actions: actions, actions: actions,
validActions: validActions, validActions: validActions,
sqlStore: sqlStore,
} }
s.api = newApi(ac, router, s) s.api = newApi(ac, router, s)
@ -62,6 +63,7 @@ type Service struct {
permissions []string permissions []string
actions []string actions []string
validActions map[string]struct{} validActions map[string]struct{}
sqlStore *sqlstore.SQLStore
} }
func (s *Service) GetPermissions(ctx context.Context, orgID int64, resourceID string) ([]accesscontrol.ResourcePermission, error) { func (s *Service) GetPermissions(ctx context.Context, orgID int64, resourceID string) ([]accesscontrol.ResourcePermission, error) {
@ -216,7 +218,7 @@ func (s *Service) validateUser(ctx context.Context, orgID, userID int64) error {
} }
func (s *Service) validateTeam(ctx context.Context, orgID, teamID int64) error { func (s *Service) validateTeam(ctx context.Context, orgID, teamID int64) error {
if err := sqlstore.GetTeamById(ctx, &models.GetTeamByIdQuery{OrgId: orgID, Id: teamID}); err != nil { if err := s.sqlStore.GetTeamById(ctx, &models.GetTeamByIdQuery{OrgId: orgID, Id: teamID}); err != nil {
return err return err
} }
return nil return nil

View File

@ -148,7 +148,7 @@ func setupTestEnvironment(t *testing.T, permissions []*accesscontrol.Permission,
sql := sqlstore.InitTestDB(t) sql := sqlstore.InitTestDB(t)
store := database.ProvideService(sql) store := database.ProvideService(sql)
service, err := New(ops, routing.NewRouteRegister(), accesscontrolmock.New().WithPermissions(permissions), store) service, err := New(ops, routing.NewRouteRegister(), accesscontrolmock.New().WithPermissions(permissions), store, sql)
require.NoError(t, err) require.NoError(t, err)
return service, sql return service, sql

View File

@ -128,6 +128,7 @@ func newSQLStore(cfg *setting.Cfg, cacheService *localcache.CacheService, bus bu
ss.addDashboardVersionQueryAndCommandHandlers() ss.addDashboardVersionQueryAndCommandHandlers()
ss.addAPIKeysQueryAndCommandHandlers() ss.addAPIKeysQueryAndCommandHandlers()
ss.addPlaylistQueryAndCommandHandlers() ss.addPlaylistQueryAndCommandHandlers()
ss.addTeamQueryAndCommandHandlers()
// if err := ss.Reset(); err != nil { // if err := ss.Reset(); err != nil {
// return nil, err // return nil, err

View File

@ -11,19 +11,29 @@ import (
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
) )
func init() { func (ss *SQLStore) addTeamQueryAndCommandHandlers() {
bus.AddHandler("sql", UpdateTeam) bus.AddHandler("sql", ss.UpdateTeam)
bus.AddHandler("sql", DeleteTeam) bus.AddHandler("sql", ss.DeleteTeam)
bus.AddHandler("sql", SearchTeams) bus.AddHandler("sql", ss.SearchTeams)
bus.AddHandler("sql", GetTeamById) bus.AddHandler("sql", ss.GetTeamById)
bus.AddHandler("sql", GetTeamsByUser) bus.AddHandler("sql", GetTeamsByUser)
bus.AddHandler("sql", UpdateTeamMember) bus.AddHandler("sql", ss.UpdateTeamMember)
bus.AddHandler("sql", RemoveTeamMember) bus.AddHandler("sql", ss.RemoveTeamMember)
bus.AddHandler("sql", GetTeamMembers) bus.AddHandler("sql", ss.GetTeamMembers)
bus.AddHandler("sql", IsAdminOfTeams) bus.AddHandler("sql", IsAdminOfTeams)
} }
type TeamStore interface {
UpdateTeam(ctx context.Context, cmd *models.UpdateTeamCommand) error
DeleteTeam(ctx context.Context, cmd *models.DeleteTeamCommand) error
SearchTeams(ctx context.Context, query *models.SearchTeamsQuery) error
GetTeamById(ctx context.Context, query *models.GetTeamByIdQuery) error
UpdateTeamMember(ctx context.Context, cmd *models.UpdateTeamMemberCommand) error
RemoveTeamMember(ctx context.Context, cmd *models.RemoveTeamMemberCommand) error
GetTeamMembers(ctx context.Context, cmd *models.GetTeamMembersQuery) error
}
func getFilteredUsers(signedInUser *models.SignedInUser, hiddenUsers map[string]struct{}) []string { func getFilteredUsers(signedInUser *models.SignedInUser, hiddenUsers map[string]struct{}) []string {
filteredUsers := make([]string, 0, len(hiddenUsers)) filteredUsers := make([]string, 0, len(hiddenUsers))
if signedInUser == nil || signedInUser.IsGrafanaAdmin { if signedInUser == nil || signedInUser.IsGrafanaAdmin {
@ -95,7 +105,7 @@ func (ss *SQLStore) CreateTeam(name, email string, orgID int64) (models.Team, er
return team, err return team, err
} }
func UpdateTeam(ctx context.Context, cmd *models.UpdateTeamCommand) error { func (ss *SQLStore) UpdateTeam(ctx context.Context, cmd *models.UpdateTeamCommand) error {
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
if isNameTaken, err := isTeamNameTaken(cmd.OrgId, cmd.Name, cmd.Id, sess); err != nil { if isNameTaken, err := isTeamNameTaken(cmd.OrgId, cmd.Name, cmd.Id, sess); err != nil {
return err return err
@ -126,7 +136,7 @@ func UpdateTeam(ctx context.Context, cmd *models.UpdateTeamCommand) error {
} }
// DeleteTeam will delete a team, its member and any permissions connected to the team // DeleteTeam will delete a team, its member and any permissions connected to the team
func DeleteTeam(ctx context.Context, cmd *models.DeleteTeamCommand) error { func (ss *SQLStore) DeleteTeam(ctx context.Context, cmd *models.DeleteTeamCommand) error {
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
if _, err := teamExists(cmd.OrgId, cmd.Id, sess); err != nil { if _, err := teamExists(cmd.OrgId, cmd.Id, sess); err != nil {
return err return err
@ -172,7 +182,7 @@ func isTeamNameTaken(orgId int64, name string, existingId int64, sess *DBSession
return false, nil return false, nil
} }
func SearchTeams(ctx context.Context, query *models.SearchTeamsQuery) error { func (ss *SQLStore) SearchTeams(ctx context.Context, query *models.SearchTeamsQuery) error {
query.Result = models.SearchTeamQueryResult{ query.Result = models.SearchTeamQueryResult{
Teams: make([]*models.TeamDTO, 0), Teams: make([]*models.TeamDTO, 0),
} }
@ -235,7 +245,7 @@ func SearchTeams(ctx context.Context, query *models.SearchTeamsQuery) error {
return err return err
} }
func GetTeamById(ctx context.Context, query *models.GetTeamByIdQuery) error { func (ss *SQLStore) GetTeamById(ctx context.Context, query *models.GetTeamByIdQuery) error {
var sql bytes.Buffer var sql bytes.Buffer
params := make([]interface{}, 0) params := make([]interface{}, 0)
@ -322,7 +332,7 @@ func getTeamMember(sess *DBSession, orgId int64, teamId int64, userId int64) (mo
} }
// UpdateTeamMember updates a team member // UpdateTeamMember updates a team member
func UpdateTeamMember(ctx context.Context, cmd *models.UpdateTeamMemberCommand) error { func (ss *SQLStore) UpdateTeamMember(ctx context.Context, cmd *models.UpdateTeamMemberCommand) error {
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
member, err := getTeamMember(sess, cmd.OrgId, cmd.TeamId, cmd.UserId) member, err := getTeamMember(sess, cmd.OrgId, cmd.TeamId, cmd.UserId)
if err != nil { if err != nil {
@ -348,7 +358,7 @@ func UpdateTeamMember(ctx context.Context, cmd *models.UpdateTeamMemberCommand)
} }
// RemoveTeamMember removes a member from a team // RemoveTeamMember removes a member from a team
func RemoveTeamMember(ctx context.Context, cmd *models.RemoveTeamMemberCommand) error { func (ss *SQLStore) RemoveTeamMember(ctx context.Context, cmd *models.RemoveTeamMemberCommand) error {
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
if _, err := teamExists(cmd.OrgId, cmd.TeamId, sess); err != nil { if _, err := teamExists(cmd.OrgId, cmd.TeamId, sess); err != nil {
return err return err
@ -399,7 +409,7 @@ func isLastAdmin(sess *DBSession, orgId int64, teamId int64, userId int64) (bool
} }
// GetTeamMembers return a list of members for the specified team // GetTeamMembers return a list of members for the specified team
func GetTeamMembers(ctx context.Context, query *models.GetTeamMembersQuery) error { func (ss *SQLStore) GetTeamMembers(ctx context.Context, query *models.GetTeamMembersQuery) error {
query.Result = make([]*models.TeamMemberDTO, 0) query.Result = make([]*models.TeamMemberDTO, 0)
sess := x.Table("team_member") sess := x.Table("team_member")
sess.Join("INNER", x.Dialect().Quote("user"), fmt.Sprintf("team_member.user_id=%s.id", x.Dialect().Quote("user"))) sess.Join("INNER", x.Dialect().Quote("user"), fmt.Sprintf("team_member.user_id=%s.id", x.Dialect().Quote("user")))

View File

@ -44,7 +44,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
t.Run("Should be able to create teams and add users", func(t *testing.T) { t.Run("Should be able to create teams and add users", func(t *testing.T) {
query := &models.SearchTeamsQuery{OrgId: testOrgID, Name: "group1 name", Page: 1, Limit: 10} query := &models.SearchTeamsQuery{OrgId: testOrgID, Name: "group1 name", Page: 1, Limit: 10}
err = SearchTeams(context.Background(), query) err = sqlStore.SearchTeams(context.Background(), query)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, query.Page, 1) require.Equal(t, query.Page, 1)
@ -60,7 +60,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
q1 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id} q1 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id}
err = GetTeamMembers(context.Background(), q1) err = sqlStore.GetTeamMembers(context.Background(), q1)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(q1.Result), 2) require.Equal(t, len(q1.Result), 2)
require.Equal(t, q1.Result[0].TeamId, team1.Id) require.Equal(t, q1.Result[0].TeamId, team1.Id)
@ -72,7 +72,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.Equal(t, q1.Result[1].External, true) require.Equal(t, q1.Result[1].External, true)
q2 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, External: true} q2 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, External: true}
err = GetTeamMembers(context.Background(), q2) err = sqlStore.GetTeamMembers(context.Background(), q2)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(q2.Result), 1) require.Equal(t, len(q2.Result), 1)
require.Equal(t, q2.Result[0].TeamId, team1.Id) require.Equal(t, q2.Result[0].TeamId, team1.Id)
@ -80,13 +80,13 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.Equal(t, q2.Result[0].OrgId, testOrgID) require.Equal(t, q2.Result[0].OrgId, testOrgID)
require.Equal(t, q2.Result[0].External, true) require.Equal(t, q2.Result[0].External, true)
err = SearchTeams(context.Background(), query) err = sqlStore.SearchTeams(context.Background(), query)
require.NoError(t, err) require.NoError(t, err)
team1 = query.Result.Teams[0] team1 = query.Result.Teams[0]
require.EqualValues(t, team1.MemberCount, 2) require.EqualValues(t, team1.MemberCount, 2)
getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: team1.Id} getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: team1.Id}
err = GetTeamById(context.Background(), getTeamQuery) err = sqlStore.GetTeamById(context.Background(), getTeamQuery)
require.NoError(t, err) require.NoError(t, err)
team1 = getTeamQuery.Result team1 = getTeamQuery.Result
require.Equal(t, team1.Name, "group1 name") require.Equal(t, team1.Name, "group1 name")
@ -101,7 +101,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
userId := userIds[1] userId := userIds[1]
teamQuery := &models.SearchTeamsQuery{OrgId: testOrgID, Name: "group1 name", Page: 1, Limit: 10} teamQuery := &models.SearchTeamsQuery{OrgId: testOrgID, Name: "group1 name", Page: 1, Limit: 10}
err = SearchTeams(context.Background(), teamQuery) err = sqlStore.SearchTeams(context.Background(), teamQuery)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, teamQuery.Page, 1) require.Equal(t, teamQuery.Page, 1)
@ -111,7 +111,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
memberQuery := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, External: true} memberQuery := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, External: true}
err = GetTeamMembers(context.Background(), memberQuery) err = sqlStore.GetTeamMembers(context.Background(), memberQuery)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(memberQuery.Result), 1) require.Equal(t, len(memberQuery.Result), 1)
require.Equal(t, memberQuery.Result[0].TeamId, team1.Id) require.Equal(t, memberQuery.Result[0].TeamId, team1.Id)
@ -127,11 +127,11 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id} qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
err = GetTeamMembers(context.Background(), qBeforeUpdate) err = sqlStore.GetTeamMembers(context.Background(), qBeforeUpdate)
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, qBeforeUpdate.Result[0].Permission, 0) require.EqualValues(t, qBeforeUpdate.Result[0].Permission, 0)
err = UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{ err = sqlStore.UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{
UserId: userId, UserId: userId,
OrgId: testOrgID, OrgId: testOrgID,
TeamId: team.Id, TeamId: team.Id,
@ -141,7 +141,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id} qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
err = GetTeamMembers(context.Background(), qAfterUpdate) err = sqlStore.GetTeamMembers(context.Background(), qAfterUpdate)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, qAfterUpdate.Result[0].Permission, models.PERMISSION_ADMIN) require.Equal(t, qAfterUpdate.Result[0].Permission, models.PERMISSION_ADMIN)
}) })
@ -155,12 +155,12 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id} qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
err = GetTeamMembers(context.Background(), qBeforeUpdate) err = sqlStore.GetTeamMembers(context.Background(), qBeforeUpdate)
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, qBeforeUpdate.Result[0].Permission, 0) require.EqualValues(t, qBeforeUpdate.Result[0].Permission, 0)
invalidPermissionLevel := models.PERMISSION_EDIT invalidPermissionLevel := models.PERMISSION_EDIT
err = UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{ err = sqlStore.UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{
UserId: userID, UserId: userID,
OrgId: testOrgID, OrgId: testOrgID,
TeamId: team.Id, TeamId: team.Id,
@ -170,7 +170,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id} qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
err = GetTeamMembers(context.Background(), qAfterUpdate) err = sqlStore.GetTeamMembers(context.Background(), qAfterUpdate)
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, qAfterUpdate.Result[0].Permission, 0) require.EqualValues(t, qAfterUpdate.Result[0].Permission, 0)
}) })
@ -178,7 +178,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
t.Run("Shouldn't be able to update a user not in the team.", func(t *testing.T) { t.Run("Shouldn't be able to update a user not in the team.", func(t *testing.T) {
sqlStore = InitTestDB(t) sqlStore = InitTestDB(t)
setup() setup()
err = UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{ err = sqlStore.UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{
UserId: 1, UserId: 1,
OrgId: testOrgID, OrgId: testOrgID,
TeamId: team1.Id, TeamId: team1.Id,
@ -190,13 +190,13 @@ func TestTeamCommandsAndQueries(t *testing.T) {
t.Run("Should be able to search for teams", func(t *testing.T) { t.Run("Should be able to search for teams", func(t *testing.T) {
query := &models.SearchTeamsQuery{OrgId: testOrgID, Query: "group", Page: 1} query := &models.SearchTeamsQuery{OrgId: testOrgID, Query: "group", Page: 1}
err = SearchTeams(context.Background(), query) err = sqlStore.SearchTeams(context.Background(), query)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(query.Result.Teams), 2) require.Equal(t, len(query.Result.Teams), 2)
require.EqualValues(t, query.Result.TotalCount, 2) require.EqualValues(t, query.Result.TotalCount, 2)
query2 := &models.SearchTeamsQuery{OrgId: testOrgID, Query: ""} query2 := &models.SearchTeamsQuery{OrgId: testOrgID, Query: ""}
err = SearchTeams(context.Background(), query2) err = sqlStore.SearchTeams(context.Background(), query2)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(query2.Result.Teams), 2) require.Equal(t, len(query2.Result.Teams), 2)
}) })
@ -220,11 +220,11 @@ func TestTeamCommandsAndQueries(t *testing.T) {
err = sqlStore.AddTeamMember(userIds[0], testOrgID, team1.Id, false, 0) err = sqlStore.AddTeamMember(userIds[0], testOrgID, team1.Id, false, 0)
require.NoError(t, err) require.NoError(t, err)
err = RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0]}) err = sqlStore.RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0]})
require.NoError(t, err) require.NoError(t, err)
q2 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id} q2 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id}
err = GetTeamMembers(context.Background(), q2) err = sqlStore.GetTeamMembers(context.Background(), q2)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(q2.Result), 0) require.Equal(t, len(q2.Result), 0)
}) })
@ -234,19 +234,19 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
t.Run("A user should not be able to remove the last admin", func(t *testing.T) { t.Run("A user should not be able to remove the last admin", func(t *testing.T) {
err = RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], ProtectLastAdmin: true}) err = sqlStore.RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], ProtectLastAdmin: true})
require.Equal(t, err, models.ErrLastTeamAdmin) require.Equal(t, err, models.ErrLastTeamAdmin)
}) })
t.Run("A user should be able to remove an admin if there are other admins", func(t *testing.T) { t.Run("A user should be able to remove an admin if there are other admins", func(t *testing.T) {
err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN) err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN)
require.NoError(t, err) require.NoError(t, err)
err = RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], ProtectLastAdmin: true}) err = sqlStore.RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], ProtectLastAdmin: true})
require.NoError(t, err) require.NoError(t, err)
}) })
t.Run("A user should not be able to remove the admin permission for the last admin", func(t *testing.T) { t.Run("A user should not be able to remove the admin permission for the last admin", func(t *testing.T) {
err = UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true}) err = sqlStore.UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true})
require.Error(t, err, models.ErrLastTeamAdmin) require.Error(t, err, models.ErrLastTeamAdmin)
}) })
@ -259,7 +259,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN) err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN)
require.NoError(t, err) require.NoError(t, err)
err = UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true}) err = sqlStore.UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true})
require.NoError(t, err) require.NoError(t, err)
}) })
}) })
@ -274,11 +274,11 @@ func TestTeamCommandsAndQueries(t *testing.T) {
DashboardID: 1, OrgID: testOrgID, Permission: models.PERMISSION_EDIT, TeamID: groupId, DashboardID: 1, OrgID: testOrgID, Permission: models.PERMISSION_EDIT, TeamID: groupId,
}) })
require.NoError(t, err) require.NoError(t, err)
err = DeleteTeam(context.Background(), &models.DeleteTeamCommand{OrgId: testOrgID, Id: groupId}) err = sqlStore.DeleteTeam(context.Background(), &models.DeleteTeamCommand{OrgId: testOrgID, Id: groupId})
require.NoError(t, err) require.NoError(t, err)
query := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: groupId} query := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: groupId}
err = GetTeamById(context.Background(), query) err = sqlStore.GetTeamById(context.Background(), query)
require.Equal(t, err, models.ErrTeamNotFound) require.Equal(t, err, models.ErrTeamNotFound)
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: testOrgID} permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: testOrgID}
@ -323,21 +323,21 @@ func TestTeamCommandsAndQueries(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
searchQuery := &models.SearchTeamsQuery{OrgId: testOrgID, Page: 1, Limit: 10, SignedInUser: signedInUser, HiddenUsers: hiddenUsers} searchQuery := &models.SearchTeamsQuery{OrgId: testOrgID, Page: 1, Limit: 10, SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
err = SearchTeams(context.Background(), searchQuery) err = sqlStore.SearchTeams(context.Background(), searchQuery)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(searchQuery.Result.Teams), 2) require.Equal(t, len(searchQuery.Result.Teams), 2)
team1 := searchQuery.Result.Teams[0] team1 := searchQuery.Result.Teams[0]
require.EqualValues(t, team1.MemberCount, 2) require.EqualValues(t, team1.MemberCount, 2)
searchQueryFilteredByUser := &models.SearchTeamsQuery{OrgId: testOrgID, Page: 1, Limit: 10, UserIdFilter: userIds[0], SignedInUser: signedInUser, HiddenUsers: hiddenUsers} searchQueryFilteredByUser := &models.SearchTeamsQuery{OrgId: testOrgID, Page: 1, Limit: 10, UserIdFilter: userIds[0], SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
err = SearchTeams(context.Background(), searchQueryFilteredByUser) err = sqlStore.SearchTeams(context.Background(), searchQueryFilteredByUser)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, len(searchQueryFilteredByUser.Result.Teams), 1) require.Equal(t, len(searchQueryFilteredByUser.Result.Teams), 1)
team1 = searchQuery.Result.Teams[0] team1 = searchQuery.Result.Teams[0]
require.EqualValues(t, team1.MemberCount, 2) require.EqualValues(t, team1.MemberCount, 2)
getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: teamId, SignedInUser: signedInUser, HiddenUsers: hiddenUsers} getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: teamId, SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
err = GetTeamById(context.Background(), getTeamQuery) err = sqlStore.GetTeamById(context.Background(), getTeamQuery)
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, getTeamQuery.Result.MemberCount, 2) require.EqualValues(t, getTeamQuery.Result.MemberCount, 2)
}) })

View File

@ -7,14 +7,16 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
) )
type TeamGuardianStoreImpl struct{} type TeamGuardianStoreImpl struct {
sqlStore *sqlstore.SQLStore
}
func ProvideTeamGuardianStore() *TeamGuardianStoreImpl { func ProvideTeamGuardianStore(sqlStore *sqlstore.SQLStore) *TeamGuardianStoreImpl {
return &TeamGuardianStoreImpl{} return &TeamGuardianStoreImpl{sqlStore: sqlStore}
} }
func (t *TeamGuardianStoreImpl) GetTeamMembers(ctx context.Context, query models.GetTeamMembersQuery) ([]*models.TeamMemberDTO, error) { func (t *TeamGuardianStoreImpl) GetTeamMembers(ctx context.Context, query models.GetTeamMembersQuery) ([]*models.TeamMemberDTO, error) {
if err := sqlstore.GetTeamMembers(ctx, &query); err != nil { if err := t.sqlStore.GetTeamMembers(ctx, &query); err != nil {
return nil, err return nil, err
} }