Chore: Move team models to models pkg (#61262)

* Chore: Move team models to models pkg

* Fix ACL tests

* More ACL tests

* Change Id to ID in conflict user command test

* Remove team from models

* Fix ac test lint
This commit is contained in:
idafurjes
2023-01-11 14:20:09 +01:00
committed by GitHub
parent 672b1711b0
commit f2ffce4351
31 changed files with 385 additions and 359 deletions

View File

@@ -564,7 +564,7 @@ func setUp(confs ...setUpConf) *HTTPServer {
aclMockResp = c.aclMockResp
}
}
store.ExpectedTeamsByUser = []*models.TeamDTO{}
store.ExpectedTeamsByUser = []*team.TeamDTO{}
teamSvc := &teamtest.FakeService{}
dashSvc := &dashboards.FakeDashboardService{}
dashSvc.On("GetDashboardACLInfoList", mock.Anything, mock.AnythingOfType("*models.GetDashboardACLInfoListQuery")).Run(func(args mock.Arguments) {

View File

@@ -20,6 +20,7 @@ import (
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/team/teamtest"
)
@@ -33,7 +34,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
}
sqlmock := mockstore.NewSQLStoreMock()
sqlmock.ExpectedTeamsByUser = []*models.TeamDTO{}
sqlmock.ExpectedTeamsByUser = []*team.TeamDTO{}
jsonModel, err := simplejson.NewJson([]byte(`{"id":100}`))
require.NoError(t, err)
@@ -257,7 +258,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
func TestGetDashboardSnapshotNotFound(t *testing.T) {
sqlmock := mockstore.NewSQLStoreMock()
sqlmock.ExpectedTeamsByUser = []*models.TeamDTO{}
sqlmock.ExpectedTeamsByUser = []*team.TeamDTO{}
setUpSnapshotTest := func(t *testing.T) dashboardsnapshots.Service {
t.Helper()
@@ -307,7 +308,7 @@ func TestGetDashboardSnapshotNotFound(t *testing.T) {
func TestGetDashboardSnapshotFailure(t *testing.T) {
sqlmock := mockstore.NewSQLStoreMock()
sqlmock.ExpectedTeamsByUser = []*models.TeamDTO{}
sqlmock.ExpectedTeamsByUser = []*team.TeamDTO{}
setUpSnapshotTest := func(t *testing.T) dashboardsnapshots.Service {
t.Helper()

View File

@@ -244,7 +244,7 @@ func TestOrgUsersAPIEndpoint_LegacyAccessControl_TeamAdmin(t *testing.T) {
// Setup store teams
team1, err := sc.teamService.CreateTeam("testteam1", "testteam1@example.org", testOrgID)
require.NoError(t, err)
err = sc.teamService.AddTeamMember(testUserID, testOrgID, team1.Id, false, models.PERMISSION_ADMIN)
err = sc.teamService.AddTeamMember(testUserID, testOrgID, team1.ID, false, models.PERMISSION_ADMIN)
require.NoError(t, err)
response := callAPI(sc.server, http.MethodGet, "/api/org/users/lookup", nil, t)

View File

@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -24,7 +25,7 @@ import (
// 409: conflictError
// 500: internalServerError
func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
cmd := models.CreateTeamCommand{}
cmd := team.CreateTeamCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
@@ -33,9 +34,9 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
return response.Error(403, "Not allowed to create team.", nil)
}
team, err := hs.teamService.CreateTeam(cmd.Name, cmd.Email, c.OrgID)
t, err := hs.teamService.CreateTeam(cmd.Name, cmd.Email, c.OrgID)
if err != nil {
if errors.Is(err, models.ErrTeamNameTaken) {
if errors.Is(err, team.ErrTeamNameTaken) {
return response.Error(409, "Team name taken", err)
}
return response.Error(500, "Failed to create Team", err)
@@ -52,7 +53,7 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
// the SignedInUser is an empty struct therefore
// an additional check whether it is an actual user is required
if c.SignedInUser.IsRealUser() {
if err := addOrUpdateTeamMember(c.Req.Context(), hs.teamPermissionsService, c.SignedInUser.UserID, c.OrgID, team.Id, models.PERMISSION_ADMIN.String()); err != nil {
if err := addOrUpdateTeamMember(c.Req.Context(), hs.teamPermissionsService, c.SignedInUser.UserID, c.OrgID, t.ID, models.PERMISSION_ADMIN.String()); err != nil {
c.Logger.Error("Could not add creator to team", "error", err)
}
} else {
@@ -60,7 +61,7 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
}
}
return response.JSON(http.StatusOK, &util.DynMap{
"teamId": team.Id,
"teamId": t.ID,
"message": "Team created",
})
}
@@ -77,25 +78,25 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
// 409: conflictError
// 500: internalServerError
func (hs *HTTPServer) UpdateTeam(c *models.ReqContext) response.Response {
cmd := models.UpdateTeamCommand{}
cmd := team.UpdateTeamCommand{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.OrgID
cmd.Id, err = strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
cmd.OrgID = c.OrgID
cmd.ID, err = strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
if hs.AccessControl.IsDisabled() {
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgId, cmd.Id, c.SignedInUser); err != nil {
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgID, cmd.ID, c.SignedInUser); err != nil {
return response.Error(403, "Not allowed to update team", err)
}
}
if err := hs.teamService.UpdateTeam(c.Req.Context(), &cmd); err != nil {
if errors.Is(err, models.ErrTeamNameTaken) {
if errors.Is(err, team.ErrTeamNameTaken) {
return response.Error(400, "Team name taken", err)
}
return response.Error(500, "Failed to update Team", err)
@@ -115,21 +116,21 @@ func (hs *HTTPServer) UpdateTeam(c *models.ReqContext) response.Response {
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) DeleteTeamByID(c *models.ReqContext) response.Response {
orgId := c.OrgID
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
orgID := c.OrgID
teamID, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
}
user := c.SignedInUser
if hs.AccessControl.IsDisabled() {
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, user); err != nil {
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgID, teamID, user); err != nil {
return response.Error(403, "Not allowed to delete team", err)
}
}
if err := hs.teamService.DeleteTeam(c.Req.Context(), &models.DeleteTeamCommand{OrgId: orgId, Id: teamId}); err != nil {
if errors.Is(err, models.ErrTeamNotFound) {
if err := hs.teamService.DeleteTeam(c.Req.Context(), &team.DeleteTeamCommand{OrgID: orgID, ID: teamID}); err != nil {
if errors.Is(err, team.ErrTeamNotFound) {
return response.Error(404, "Failed to delete Team. ID not found", nil)
}
return response.Error(500, "Failed to delete Team", err)
@@ -157,43 +158,44 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response {
}
// Using accesscontrol the filtering is done based on user permissions
userIdFilter := models.FilterIgnoreUser
userIDFilter := team.FilterIgnoreUser
if hs.AccessControl.IsDisabled() {
userIdFilter = userFilter(c)
userIDFilter = userFilter(c)
}
query := models.SearchTeamsQuery{
OrgId: c.OrgID,
query := team.SearchTeamsQuery{
OrgID: c.OrgID,
Query: c.Query("query"),
Name: c.Query("name"),
UserIdFilter: userIdFilter,
UserIDFilter: userIDFilter,
Page: page,
Limit: perPage,
SignedInUser: c.SignedInUser,
HiddenUsers: hs.Cfg.HiddenUsers,
}
if err := hs.teamService.SearchTeams(c.Req.Context(), &query); err != nil {
queryResult, err := hs.teamService.SearchTeams(c.Req.Context(), &query)
if err != nil {
return response.Error(500, "Failed to search Teams", err)
}
teamIDs := map[string]bool{}
for _, team := range query.Result.Teams {
team.AvatarUrl = dtos.GetGravatarUrlWithDefault(team.Email, team.Name)
teamIDs[strconv.FormatInt(team.Id, 10)] = true
for _, team := range queryResult.Teams {
team.AvatarURL = dtos.GetGravatarUrlWithDefault(team.Email, team.Name)
teamIDs[strconv.FormatInt(team.ID, 10)] = true
}
metadata := hs.getMultiAccessControlMetadata(c, c.OrgID, "teams:id:", teamIDs)
if len(metadata) > 0 {
for _, team := range query.Result.Teams {
team.AccessControl = metadata[strconv.FormatInt(team.Id, 10)]
for _, team := range queryResult.Teams {
team.AccessControl = metadata[strconv.FormatInt(team.ID, 10)]
}
}
query.Result.Page = page
query.Result.PerPage = perPage
queryResult.Page = page
queryResult.PerPage = perPage
return response.JSON(http.StatusOK, query.Result)
return response.JSON(http.StatusOK, queryResult)
}
// UserFilter returns the user ID used in a filter when querying a team
@@ -202,7 +204,7 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response {
func userFilter(c *models.ReqContext) int64 {
userIdFilter := c.SignedInUser.UserID
if c.OrgRole == org.RoleAdmin {
userIdFilter = models.FilterIgnoreUser
userIdFilter = team.FilterIgnoreUser
}
return userIdFilter
}
@@ -224,21 +226,22 @@ func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response {
}
// Using accesscontrol the filtering has already been performed at middleware layer
userIdFilter := models.FilterIgnoreUser
userIdFilter := team.FilterIgnoreUser
if hs.AccessControl.IsDisabled() {
userIdFilter = userFilter(c)
}
query := models.GetTeamByIdQuery{
OrgId: c.OrgID,
Id: teamId,
query := team.GetTeamByIDQuery{
OrgID: c.OrgID,
ID: teamId,
SignedInUser: c.SignedInUser,
HiddenUsers: hs.Cfg.HiddenUsers,
UserIdFilter: userIdFilter,
}
if err := hs.teamService.GetTeamById(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrTeamNotFound) {
queryResult, err := hs.teamService.GetTeamByID(c.Req.Context(), &query)
if err != nil {
if errors.Is(err, team.ErrTeamNotFound) {
return response.Error(404, "Team not found", err)
}
@@ -246,10 +249,10 @@ func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response {
}
// Add accesscontrol metadata
query.Result.AccessControl = hs.getAccessControlMetadata(c, c.OrgID, "teams:id:", strconv.FormatInt(query.Result.Id, 10))
queryResult.AccessControl = hs.getAccessControlMetadata(c, c.OrgID, "teams:id:", strconv.FormatInt(queryResult.ID, 10))
query.Result.AvatarUrl = dtos.GetGravatarUrlWithDefault(query.Result.Email, query.Result.Name)
return response.JSON(http.StatusOK, &query.Result)
queryResult.AvatarURL = dtos.GetGravatarUrlWithDefault(queryResult.Email, queryResult.Name)
return response.JSON(http.StatusOK, &queryResult)
}
// swagger:route GET /teams/{team_id}/preferences teams getTeamPreferences
@@ -361,14 +364,14 @@ type SearchTeamsParams struct {
type CreateTeamParams struct {
// in:body
// required:true
Body models.CreateTeamCommand `json:"body"`
Body team.CreateTeamCommand `json:"body"`
}
// swagger:parameters updateTeam
type UpdateTeamParams struct {
// in:body
// required:true
Body models.UpdateTeamCommand `json:"body"`
Body team.UpdateTeamCommand `json:"body"`
// in:path
// required:true
TeamID string `json:"team_id"`
@@ -378,14 +381,14 @@ type UpdateTeamParams struct {
type SearchTeamsResponse struct {
// The response message
// in: body
Body models.SearchTeamQueryResult `json:"body"`
Body team.SearchTeamQueryResult `json:"body"`
}
// swagger:response getTeamByIDResponse
type GetTeamByIDResponse struct {
// The response message
// in: body
Body *models.TeamDTO `json:"body"`
Body *team.TeamDTO `json:"body"`
}
// swagger:response createTeamResponse

View File

@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -197,11 +198,11 @@ func (hs *HTTPServer) RemoveTeamMember(c *models.ReqContext) response.Response {
teamIDString := strconv.FormatInt(teamId, 10)
if _, err := hs.teamPermissionsService.SetUserPermission(c.Req.Context(), orgId, accesscontrol.User{ID: userId}, teamIDString, ""); err != nil {
if errors.Is(err, models.ErrTeamNotFound) {
if errors.Is(err, team.ErrTeamNotFound) {
return response.Error(404, "Team not found", nil)
}
if errors.Is(err, models.ErrTeamMemberNotFound) {
if errors.Is(err, team.ErrTeamMemberNotFound) {
return response.Error(404, "Team member not found", nil)
}

View File

@@ -65,7 +65,7 @@ func setUpGetTeamMembersHandler(t *testing.T, sqlStore *sqlstore.SQLStore) {
// user
user, err := usrSvc.CreateUserForTests(context.Background(), &userCmd)
require.NoError(t, err)
err = teamSvc.AddTeamMember(user.ID, testOrgID, team.Id, false, 1)
err = teamSvc.AddTeamMember(user.ID, testOrgID, team.ID, false, 1)
require.NoError(t, err)
}
}

View File

@@ -21,6 +21,7 @@ import (
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/preference/preftest"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
"github.com/grafana/grafana/pkg/services/user"
@@ -49,7 +50,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
sc.handlerFunc = hs.SearchTeams
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
require.Equal(t, http.StatusOK, sc.resp.Code)
var resp models.SearchTeamQueryResult
var resp team.SearchTeamQueryResult
err = json.Unmarshal(sc.resp.Body.Bytes(), &resp)
require.NoError(t, err)
@@ -65,13 +66,13 @@ func TestTeamAPIEndpoint(t *testing.T) {
require.NoError(t, err)
// Adding the test user to the teams in order for him to list them
err = hs.teamService.AddTeamMember(testUserID, testOrgID, team1.Id, false, 0)
err = hs.teamService.AddTeamMember(testUserID, testOrgID, team1.ID, false, 0)
require.NoError(t, err)
sc.handlerFunc = hs.SearchTeams
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
require.Equal(t, http.StatusOK, sc.resp.Code)
var resp models.SearchTeamQueryResult
var resp team.SearchTeamQueryResult
err = json.Unmarshal(sc.resp.Body.Bytes(), &resp)
require.NoError(t, err)
@@ -87,15 +88,15 @@ func TestTeamAPIEndpoint(t *testing.T) {
require.NoError(t, err)
// Adding the test user to the teams in order for him to list them
err = hs.teamService.AddTeamMember(testUserID, testOrgID, team1.Id, false, 0)
err = hs.teamService.AddTeamMember(testUserID, testOrgID, team1.ID, false, 0)
require.NoError(t, err)
err = hs.teamService.AddTeamMember(testUserID, testOrgID, team2.Id, false, 0)
err = hs.teamService.AddTeamMember(testUserID, testOrgID, team2.ID, false, 0)
require.NoError(t, err)
sc.handlerFunc = hs.SearchTeams
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
var resp team.SearchTeamQueryResult
err = json.Unmarshal(sc.resp.Body.Bytes(), &resp)
require.NoError(t, err)
@@ -129,7 +130,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
Logger: logger,
}
c.OrgRole = org.RoleEditor
c.Req.Body = mockRequestBody(models.CreateTeamCommand{Name: teamName})
c.Req.Body = mockRequestBody(team.CreateTeamCommand{Name: teamName})
c.Req.Header.Add("Content-Type", "application/json")
r := hs.CreateTeam(c)
@@ -146,7 +147,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
Logger: logger,
}
c.OrgRole = org.RoleEditor
c.Req.Body = mockRequestBody(models.CreateTeamCommand{Name: teamName})
c.Req.Body = mockRequestBody(team.CreateTeamCommand{Name: teamName})
c.Req.Header.Add("Content-Type", "application/json")
r := hs.CreateTeam(c)
assert.Equal(t, 200, r.Status())
@@ -270,7 +271,7 @@ func TestTeamAPIEndpoint_SearchTeams_RBAC(t *testing.T) {
func TestTeamAPIEndpoint_GetTeamByID_RBAC(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &models.TeamDTO{}}
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &team.TeamDTO{}}
})
url := fmt.Sprintf(detailTeamURL, 1)
@@ -313,7 +314,7 @@ func TestTeamAPIEndpoint_GetTeamByID_RBAC(t *testing.T) {
func TestTeamAPIEndpoint_UpdateTeam_RBAC(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &models.TeamDTO{}}
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &team.TeamDTO{}}
})
request := func(teamID int64, user *user.SignedInUser) (*http.Response, error) {
@@ -356,7 +357,7 @@ func TestTeamAPIEndpoint_UpdateTeam_RBAC(t *testing.T) {
func TestTeamAPIEndpoint_DeleteTeam_RBAC(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &models.TeamDTO{}}
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &team.TeamDTO{}}
})
request := func(teamID int64, user *user.SignedInUser) (*http.Response, error) {

View File

@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
@@ -289,16 +290,17 @@ func (hs *HTTPServer) GetUserTeams(c *models.ReqContext) response.Response {
}
func (hs *HTTPServer) getUserTeamList(c *models.ReqContext, orgID int64, userID int64) response.Response {
query := models.GetTeamsByUserQuery{OrgId: orgID, UserId: userID, SignedInUser: c.SignedInUser}
query := team.GetTeamsByUserQuery{OrgID: orgID, UserID: userID, SignedInUser: c.SignedInUser}
if err := hs.teamService.GetTeamsByUser(c.Req.Context(), &query); err != nil {
queryResult, err := hs.teamService.GetTeamsByUser(c.Req.Context(), &query)
if err != nil {
return response.Error(500, "Failed to get user teams", err)
}
for _, team := range query.Result {
team.AvatarUrl = dtos.GetGravatarUrlWithDefault(team.Email, team.Name)
for _, team := range queryResult {
team.AvatarURL = dtos.GetGravatarUrlWithDefault(team.Email, team.Name)
}
return response.JSON(http.StatusOK, query.Result)
return response.JSON(http.StatusOK, queryResult)
}
// swagger:route GET /users/{user_id}/orgs users getUserOrgList
@@ -657,14 +659,14 @@ type GetSignedInUserOrgListResponse struct {
type GetUserTeamsResponse struct {
// The response message
// in: body
Body []*models.TeamDTO `json:"body"`
Body []*team.TeamDTO `json:"body"`
}
// swagger:response getSignedInUserTeamListResponse
type GetSignedInUserTeamListResponse struct {
// The response message
// in: body
Body []*models.TeamDTO `json:"body"`
Body []*team.TeamDTO `json:"body"`
}
// swagger:response helpFlagResponse