mirror of https://github.com/grafana/grafana.git
Teams: Move team API to own service (#76347)
* move team API to its own service * remove uneeded import * reshare pref api logic
This commit is contained in:
parent
665dc1fa44
commit
466f8a1f5a
|
|
@ -270,25 +270,6 @@ func (hs *HTTPServer) registerRoutes() {
|
|||
usersRoute.Post("/:id/using/:orgId", authorize(ac.EvalPermission(ac.ActionUsersWrite, userIDScope)), routing.Wrap(hs.UpdateUserActiveOrg))
|
||||
}, requestmeta.SetOwner(requestmeta.TeamAuth))
|
||||
|
||||
// team (admin permission required)
|
||||
apiRoute.Group("/teams", func(teamsRoute routing.RouteRegister) {
|
||||
teamsRoute.Post("/", authorize(ac.EvalPermission(ac.ActionTeamsCreate)), routing.Wrap(hs.CreateTeam))
|
||||
teamsRoute.Put("/:teamId", authorize(ac.EvalPermission(ac.ActionTeamsWrite, ac.ScopeTeamsID)), routing.Wrap(hs.UpdateTeam))
|
||||
teamsRoute.Delete("/:teamId", authorize(ac.EvalPermission(ac.ActionTeamsDelete, ac.ScopeTeamsID)), routing.Wrap(hs.DeleteTeamByID))
|
||||
teamsRoute.Get("/:teamId/members", authorize(ac.EvalPermission(ac.ActionTeamsPermissionsRead, ac.ScopeTeamsID)), routing.Wrap(hs.GetTeamMembers))
|
||||
teamsRoute.Post("/:teamId/members", authorize(ac.EvalPermission(ac.ActionTeamsPermissionsWrite, ac.ScopeTeamsID)), routing.Wrap(hs.AddTeamMember))
|
||||
teamsRoute.Put("/:teamId/members/:userId", authorize(ac.EvalPermission(ac.ActionTeamsPermissionsWrite, ac.ScopeTeamsID)), routing.Wrap(hs.UpdateTeamMember))
|
||||
teamsRoute.Delete("/:teamId/members/:userId", authorize(ac.EvalPermission(ac.ActionTeamsPermissionsWrite, ac.ScopeTeamsID)), routing.Wrap(hs.RemoveTeamMember))
|
||||
teamsRoute.Get("/:teamId/preferences", authorize(ac.EvalPermission(ac.ActionTeamsRead, ac.ScopeTeamsID)), routing.Wrap(hs.GetTeamPreferences))
|
||||
teamsRoute.Put("/:teamId/preferences", authorize(ac.EvalPermission(ac.ActionTeamsWrite, ac.ScopeTeamsID)), routing.Wrap(hs.UpdateTeamPreferences))
|
||||
}, requestmeta.SetOwner(requestmeta.TeamAuth))
|
||||
|
||||
// team without requirement of user to be org admin
|
||||
apiRoute.Group("/teams", func(teamsRoute routing.RouteRegister) {
|
||||
teamsRoute.Get("/:teamId", authorize(ac.EvalPermission(ac.ActionTeamsRead, ac.ScopeTeamsID)), routing.Wrap(hs.GetTeamByID))
|
||||
teamsRoute.Get("/search", authorize(ac.EvalPermission(ac.ActionTeamsRead)), routing.Wrap(hs.SearchTeams))
|
||||
}, requestmeta.SetOwner(requestmeta.TeamAuth))
|
||||
|
||||
// org information available to all users.
|
||||
apiRoute.Group("/org", func(orgRoute routing.RouteRegister) {
|
||||
orgRoute.Get("/", authorize(ac.EvalPermission(ac.ActionOrgsRead)), routing.Wrap(hs.GetCurrentOrg))
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ func setupScenarioContext(t *testing.T, url string) *scenarioContext {
|
|||
return sc
|
||||
}
|
||||
|
||||
// FIXME: This user should not be anonymous
|
||||
func authedUserWithPermissions(userID, orgID int64, permissions []accesscontrol.Permission) *user.SignedInUser {
|
||||
return &user.SignedInUser{UserID: userID, OrgID: orgID, OrgRole: org.RoleViewer, Permissions: map[int64]map[string][]string{orgID: accesscontrol.GroupScopesByAction(permissions)}}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ type HTTPServer struct {
|
|||
queryDataService query.Service
|
||||
serviceAccountsService serviceaccounts.Service
|
||||
authInfoService login.AuthInfoService
|
||||
teamPermissionsService accesscontrol.TeamPermissionsService
|
||||
NotificationService *notifications.NotificationService
|
||||
DashboardService dashboards.DashboardService
|
||||
dashboardProvisioningService dashboards.DashboardProvisioningService
|
||||
|
|
@ -236,7 +235,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||
dsGuardian guardian.DatasourceGuardianProvider, alertNotificationService *alerting.AlertNotificationService,
|
||||
dashboardsnapshotsService dashboardsnapshots.Service, pluginSettings pluginSettings.Service,
|
||||
avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service,
|
||||
teamsPermissionsService accesscontrol.TeamPermissionsService, folderPermissionsService accesscontrol.FolderPermissionsService,
|
||||
folderPermissionsService accesscontrol.FolderPermissionsService,
|
||||
dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service,
|
||||
starService star.Service, csrfService csrf.Service, basekinds *corekind.Base,
|
||||
playlistService playlist.Service, apiKeyService apikey.Service, kvStore kvstore.KVStore,
|
||||
|
|
@ -319,7 +318,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||
dashboardProvisioningService: dashboardProvisioningService,
|
||||
folderService: folderService,
|
||||
dsGuardian: dsGuardian,
|
||||
teamPermissionsService: teamsPermissionsService,
|
||||
AlertNotificationService: alertNotificationService,
|
||||
dashboardsnapshotsService: dashboardsnapshotsService,
|
||||
PluginSettings: pluginSettings,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
"github.com/grafana/grafana/pkg/services/preference/prefapi"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
|
|
@ -68,56 +69,7 @@ func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Re
|
|||
return response.Error(http.StatusInternalServerError, "Failed to get user preferences", errID)
|
||||
}
|
||||
|
||||
return hs.getPreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), userID, 0)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) getPreferencesFor(ctx context.Context, orgID, userID, teamID int64) response.Response {
|
||||
prefsQuery := pref.GetPreferenceQuery{UserID: userID, OrgID: orgID, TeamID: teamID}
|
||||
|
||||
preference, err := hs.preferenceService.Get(ctx, &prefsQuery)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get preferences", err)
|
||||
}
|
||||
|
||||
var dashboardUID string
|
||||
|
||||
// when homedashboardID is 0, that means it is the default home dashboard, no UID would be returned in the response
|
||||
if preference.HomeDashboardID != 0 {
|
||||
query := dashboards.GetDashboardQuery{ID: preference.HomeDashboardID, OrgID: orgID}
|
||||
queryResult, err := hs.DashboardService.GetDashboard(ctx, &query)
|
||||
if err == nil {
|
||||
dashboardUID = queryResult.UID
|
||||
}
|
||||
}
|
||||
|
||||
dto := preferences.Spec{}
|
||||
|
||||
if preference.WeekStart != nil && *preference.WeekStart != "" {
|
||||
dto.WeekStart = preference.WeekStart
|
||||
}
|
||||
if preference.Theme != "" {
|
||||
dto.Theme = &preference.Theme
|
||||
}
|
||||
if dashboardUID != "" {
|
||||
dto.HomeDashboardUID = &dashboardUID
|
||||
}
|
||||
if preference.Timezone != "" {
|
||||
dto.Timezone = &preference.Timezone
|
||||
}
|
||||
|
||||
if preference.JSONData != nil {
|
||||
if preference.JSONData.Language != "" {
|
||||
dto.Language = &preference.JSONData.Language
|
||||
}
|
||||
|
||||
if preference.JSONData.QueryHistory.HomeTab != "" {
|
||||
dto.QueryHistory = &preferences.QueryHistoryPreference{
|
||||
HomeTab: &preference.JSONData.QueryHistory.HomeTab,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response.JSON(http.StatusOK, &dto)
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), userID, 0)
|
||||
}
|
||||
|
||||
// swagger:route PUT /user/preferences user_preferences updateUserPreferences
|
||||
|
|
@ -142,48 +94,8 @@ func (hs *HTTPServer) UpdateUserPreferences(c *contextmodel.ReqContext) response
|
|||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", errID)
|
||||
}
|
||||
|
||||
return hs.updatePreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), userID, 0, &dtoCmd)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) updatePreferencesFor(ctx context.Context, orgID, userID, teamId int64, dtoCmd *dtos.UpdatePrefsCmd) response.Response {
|
||||
if dtoCmd.Theme != "" && !pref.IsValidThemeID(dtoCmd.Theme) {
|
||||
return response.Error(http.StatusBadRequest, "Invalid theme", nil)
|
||||
}
|
||||
|
||||
dashboardID := dtoCmd.HomeDashboardID
|
||||
if dtoCmd.HomeDashboardUID != nil {
|
||||
query := dashboards.GetDashboardQuery{UID: *dtoCmd.HomeDashboardUID, OrgID: orgID}
|
||||
if query.UID == "" {
|
||||
// clear the value
|
||||
dashboardID = 0
|
||||
} else {
|
||||
queryResult, err := hs.DashboardService.GetDashboard(ctx, &query)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusNotFound, "Dashboard not found", err)
|
||||
}
|
||||
dashboardID = queryResult.ID
|
||||
}
|
||||
}
|
||||
dtoCmd.HomeDashboardID = dashboardID
|
||||
|
||||
saveCmd := pref.SavePreferenceCommand{
|
||||
UserID: userID,
|
||||
OrgID: orgID,
|
||||
TeamID: teamId,
|
||||
Theme: dtoCmd.Theme,
|
||||
Language: dtoCmd.Language,
|
||||
Timezone: dtoCmd.Timezone,
|
||||
WeekStart: dtoCmd.WeekStart,
|
||||
HomeDashboardID: dtoCmd.HomeDashboardID,
|
||||
QueryHistory: dtoCmd.QueryHistory,
|
||||
CookiePreferences: dtoCmd.Cookies,
|
||||
}
|
||||
|
||||
if err := hs.preferenceService.Save(ctx, &saveCmd); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to save preferences", err)
|
||||
}
|
||||
|
||||
return response.Success("Preferences updated")
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService,
|
||||
hs.preferenceService, c.SignedInUser.GetOrgID(), userID, 0, &dtoCmd)
|
||||
}
|
||||
|
||||
// swagger:route PATCH /user/preferences user_preferences patchUserPreferences
|
||||
|
|
@ -262,7 +174,7 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
|
|||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetOrgPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
return hs.getPreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, 0)
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), 0, 0)
|
||||
}
|
||||
|
||||
// swagger:route PUT /org/preferences org_preferences updateOrgPreferences
|
||||
|
|
@ -281,7 +193,7 @@ func (hs *HTTPServer) UpdateOrgPreferences(c *contextmodel.ReqContext) response.
|
|||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
|
||||
return hs.updatePreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, 0, &dtoCmd)
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), 0, 0, &dtoCmd)
|
||||
}
|
||||
|
||||
// swagger:route PATCH /org/preferences org_preferences patchOrgPreferences
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import (
|
|||
"github.com/grafana/grafana/pkg/services/store/entity"
|
||||
"github.com/grafana/grafana/pkg/services/store/sanitizer"
|
||||
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlesimpl"
|
||||
"github.com/grafana/grafana/pkg/services/team/teamapi"
|
||||
"github.com/grafana/grafana/pkg/services/updatechecker"
|
||||
)
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ func ProvideBackgroundServiceRegistry(
|
|||
_ serviceaccounts.Service, _ *guardian.Provider,
|
||||
_ *plugindashboardsservice.DashboardUpdater, _ *sanitizer.Provider,
|
||||
_ *grpcserver.HealthService, _ entity.EntityStoreServer, _ *grpcserver.ReflectionService, _ *ldapapi.Service,
|
||||
_ *apiregistry.Service, _ auth.IDService,
|
||||
_ *apiregistry.Service, _ auth.IDService, _ *teamapi.TeamAPI,
|
||||
) *BackgroundServiceRegistry {
|
||||
return NewBackgroundServiceRegistry(
|
||||
httpServer,
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ import (
|
|||
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlesimpl"
|
||||
"github.com/grafana/grafana/pkg/services/tag"
|
||||
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
|
||||
"github.com/grafana/grafana/pkg/services/team/teamapi"
|
||||
"github.com/grafana/grafana/pkg/services/team/teamimpl"
|
||||
tempuser "github.com/grafana/grafana/pkg/services/temp_user"
|
||||
"github.com/grafana/grafana/pkg/services/temp_user/tempuserimpl"
|
||||
|
|
@ -342,6 +343,7 @@ var wireBasicSet = wire.NewSet(
|
|||
resolver.ProvideEntityReferenceResolver,
|
||||
httpentitystore.ProvideHTTPEntityStore,
|
||||
teamimpl.ProvideService,
|
||||
teamapi.ProvideTeamAPI,
|
||||
tempuserimpl.ProvideService,
|
||||
loginattemptimpl.ProvideService,
|
||||
wire.Bind(new(loginattempt.Service), new(*loginattemptimpl.Service)),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
// shared logic between httpserver and teamapi
|
||||
package prefapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/kinds/preferences"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
)
|
||||
|
||||
func UpdatePreferencesFor(ctx context.Context,
|
||||
dashboardService dashboards.DashboardService, preferenceService pref.Service,
|
||||
orgID, userID, teamId int64, dtoCmd *dtos.UpdatePrefsCmd) response.Response {
|
||||
if dtoCmd.Theme != "" && !pref.IsValidThemeID(dtoCmd.Theme) {
|
||||
return response.Error(http.StatusBadRequest, "Invalid theme", nil)
|
||||
}
|
||||
|
||||
dashboardID := dtoCmd.HomeDashboardID
|
||||
if dtoCmd.HomeDashboardUID != nil {
|
||||
query := dashboards.GetDashboardQuery{UID: *dtoCmd.HomeDashboardUID, OrgID: orgID}
|
||||
if query.UID == "" {
|
||||
// clear the value
|
||||
dashboardID = 0
|
||||
} else {
|
||||
queryResult, err := dashboardService.GetDashboard(ctx, &query)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusNotFound, "Dashboard not found", err)
|
||||
}
|
||||
dashboardID = queryResult.ID
|
||||
}
|
||||
}
|
||||
dtoCmd.HomeDashboardID = dashboardID
|
||||
|
||||
saveCmd := pref.SavePreferenceCommand{
|
||||
UserID: userID,
|
||||
OrgID: orgID,
|
||||
TeamID: teamId,
|
||||
Theme: dtoCmd.Theme,
|
||||
Language: dtoCmd.Language,
|
||||
Timezone: dtoCmd.Timezone,
|
||||
WeekStart: dtoCmd.WeekStart,
|
||||
HomeDashboardID: dtoCmd.HomeDashboardID,
|
||||
QueryHistory: dtoCmd.QueryHistory,
|
||||
CookiePreferences: dtoCmd.Cookies,
|
||||
}
|
||||
|
||||
if err := preferenceService.Save(ctx, &saveCmd); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to save preferences", err)
|
||||
}
|
||||
|
||||
return response.Success("Preferences updated")
|
||||
}
|
||||
|
||||
func GetPreferencesFor(ctx context.Context,
|
||||
dashboardService dashboards.DashboardService, preferenceService pref.Service,
|
||||
orgID, userID, teamID int64) response.Response {
|
||||
prefsQuery := pref.GetPreferenceQuery{UserID: userID, OrgID: orgID, TeamID: teamID}
|
||||
|
||||
preference, err := preferenceService.Get(ctx, &prefsQuery)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get preferences", err)
|
||||
}
|
||||
|
||||
var dashboardUID string
|
||||
|
||||
// when homedashboardID is 0, that means it is the default home dashboard, no UID would be returned in the response
|
||||
if preference.HomeDashboardID != 0 {
|
||||
query := dashboards.GetDashboardQuery{ID: preference.HomeDashboardID, OrgID: orgID}
|
||||
queryResult, err := dashboardService.GetDashboard(ctx, &query)
|
||||
if err == nil {
|
||||
dashboardUID = queryResult.UID
|
||||
}
|
||||
}
|
||||
|
||||
dto := preferences.Spec{}
|
||||
|
||||
if preference.WeekStart != nil && *preference.WeekStart != "" {
|
||||
dto.WeekStart = preference.WeekStart
|
||||
}
|
||||
if preference.Theme != "" {
|
||||
dto.Theme = &preference.Theme
|
||||
}
|
||||
if dashboardUID != "" {
|
||||
dto.HomeDashboardUID = &dashboardUID
|
||||
}
|
||||
if preference.Timezone != "" {
|
||||
dto.Timezone = &preference.Timezone
|
||||
}
|
||||
|
||||
if preference.JSONData != nil {
|
||||
if preference.JSONData.Language != "" {
|
||||
dto.Language = &preference.JSONData.Language
|
||||
}
|
||||
|
||||
if preference.JSONData.QueryHistory.HomeTab != "" {
|
||||
dto.QueryHistory = &preferences.QueryHistoryPreference{
|
||||
HomeTab: &preference.JSONData.QueryHistory.HomeTab,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response.JSON(http.StatusOK, &dto)
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package teamapi
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/middleware/requestmeta"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type TeamAPI struct {
|
||||
teamService team.Service
|
||||
ac accesscontrol.Service
|
||||
teamPermissionsService accesscontrol.TeamPermissionsService
|
||||
license licensing.Licensing
|
||||
cfg *setting.Cfg
|
||||
preferenceService pref.Service
|
||||
ds dashboards.DashboardService
|
||||
}
|
||||
|
||||
func ProvideTeamAPI(
|
||||
routeRegister routing.RouteRegister,
|
||||
teamService team.Service,
|
||||
ac accesscontrol.Service,
|
||||
acEvaluator accesscontrol.AccessControl,
|
||||
teamPermissionsService accesscontrol.TeamPermissionsService,
|
||||
license licensing.Licensing,
|
||||
cfg *setting.Cfg,
|
||||
preferenceService pref.Service,
|
||||
ds dashboards.DashboardService,
|
||||
) *TeamAPI {
|
||||
tapi := &TeamAPI{
|
||||
teamService: teamService,
|
||||
ac: ac,
|
||||
teamPermissionsService: teamPermissionsService,
|
||||
license: license,
|
||||
cfg: cfg,
|
||||
preferenceService: preferenceService,
|
||||
ds: ds,
|
||||
}
|
||||
|
||||
tapi.registerRoutes(routeRegister, acEvaluator)
|
||||
return tapi
|
||||
}
|
||||
|
||||
func (tapi *TeamAPI) registerRoutes(router routing.RouteRegister, ac accesscontrol.AccessControl) {
|
||||
authorize := accesscontrol.Middleware(ac)
|
||||
router.Group("/api", func(apiRoute routing.RouteRegister) {
|
||||
// team (admin permission required)
|
||||
apiRoute.Group("/teams", func(teamsRoute routing.RouteRegister) {
|
||||
teamsRoute.Post("/", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsCreate)),
|
||||
routing.Wrap(tapi.createTeam))
|
||||
teamsRoute.Put("/:teamId", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsWrite,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.updateTeam))
|
||||
teamsRoute.Delete("/:teamId", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsDelete,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.deleteTeamByID))
|
||||
teamsRoute.Get("/:teamId/members", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsRead,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.getTeamMembers))
|
||||
teamsRoute.Post("/:teamId/members", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.addTeamMember))
|
||||
teamsRoute.Put("/:teamId/members/:userId", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.updateTeamMember))
|
||||
teamsRoute.Delete("/:teamId/members/:userId", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.removeTeamMember))
|
||||
teamsRoute.Get("/:teamId/preferences", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.getTeamPreferences))
|
||||
teamsRoute.Put("/:teamId/preferences", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsWrite,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.updateTeamPreferences))
|
||||
}, requestmeta.SetOwner(requestmeta.TeamAuth))
|
||||
|
||||
// team without requirement of user to be org admin
|
||||
apiRoute.Group("/teams", func(teamsRoute routing.RouteRegister) {
|
||||
teamsRoute.Get("/:teamId", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead,
|
||||
accesscontrol.ScopeTeamsID)), routing.Wrap(tapi.getTeamByID))
|
||||
teamsRoute.Get("/search", authorize(accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead)),
|
||||
routing.Wrap(tapi.searchTeams))
|
||||
}, requestmeta.SetOwner(requestmeta.TeamAuth))
|
||||
})
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package api
|
||||
package teamapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
|
@ -7,9 +7,11 @@ import (
|
|||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/preference/prefapi"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
"github.com/grafana/grafana/pkg/services/team/sortopts"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
|
@ -26,13 +28,13 @@ import (
|
|||
// 403: forbiddenError
|
||||
// 409: conflictError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) CreateTeam(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) createTeam(c *contextmodel.ReqContext) response.Response {
|
||||
cmd := team.CreateTeamCommand{}
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
|
||||
t, err := hs.teamService.CreateTeam(cmd.Name, cmd.Email, c.SignedInUser.GetOrgID())
|
||||
t, err := tapi.teamService.CreateTeam(cmd.Name, cmd.Email, c.SignedInUser.GetOrgID())
|
||||
if err != nil {
|
||||
if errors.Is(err, team.ErrTeamNameTaken) {
|
||||
return response.Error(http.StatusConflict, "Team name taken", err)
|
||||
|
|
@ -42,7 +44,7 @@ func (hs *HTTPServer) CreateTeam(c *contextmodel.ReqContext) response.Response {
|
|||
|
||||
// Clear permission cache for the user who's created the team, so that new permissions are fetched for their next call
|
||||
// Required for cases when caller wants to immediately interact with the newly created object
|
||||
hs.accesscontrolService.ClearUserPermissionCache(c.SignedInUser)
|
||||
tapi.ac.ClearUserPermissionCache(c.SignedInUser)
|
||||
|
||||
// if the request is authenticated using API tokens
|
||||
// the SignedInUser is an empty struct therefore
|
||||
|
|
@ -55,7 +57,7 @@ func (hs *HTTPServer) CreateTeam(c *contextmodel.ReqContext) response.Response {
|
|||
c.Logger.Error("Could not add creator to team because user id is not a number", "error", err)
|
||||
break
|
||||
}
|
||||
if err := addOrUpdateTeamMember(c.Req.Context(), hs.teamPermissionsService, userID, c.SignedInUser.GetOrgID(),
|
||||
if err := addOrUpdateTeamMember(c.Req.Context(), tapi.teamPermissionsService, userID, c.SignedInUser.GetOrgID(),
|
||||
t.ID, dashboards.PERMISSION_ADMIN.String()); err != nil {
|
||||
c.Logger.Error("Could not add creator to team", "error", err)
|
||||
}
|
||||
|
|
@ -80,7 +82,7 @@ func (hs *HTTPServer) CreateTeam(c *contextmodel.ReqContext) response.Response {
|
|||
// 404: notFoundError
|
||||
// 409: conflictError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) UpdateTeam(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) updateTeam(c *contextmodel.ReqContext) response.Response {
|
||||
cmd := team.UpdateTeamCommand{}
|
||||
var err error
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
|
|
@ -92,7 +94,7 @@ func (hs *HTTPServer) UpdateTeam(c *contextmodel.ReqContext) response.Response {
|
|||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
if err := hs.teamService.UpdateTeam(c.Req.Context(), &cmd); err != nil {
|
||||
if err := tapi.teamService.UpdateTeam(c.Req.Context(), &cmd); err != nil {
|
||||
if errors.Is(err, team.ErrTeamNameTaken) {
|
||||
return response.Error(http.StatusBadRequest, "Team name taken", err)
|
||||
}
|
||||
|
|
@ -112,14 +114,14 @@ func (hs *HTTPServer) UpdateTeam(c *contextmodel.ReqContext) response.Response {
|
|||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) DeleteTeamByID(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) deleteTeamByID(c *contextmodel.ReqContext) response.Response {
|
||||
orgID := c.SignedInUser.GetOrgID()
|
||||
teamID, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
if err := hs.teamService.DeleteTeam(c.Req.Context(), &team.DeleteTeamCommand{OrgID: orgID, ID: teamID}); err != nil {
|
||||
if err := tapi.teamService.DeleteTeam(c.Req.Context(), &team.DeleteTeamCommand{OrgID: orgID, ID: teamID}); err != nil {
|
||||
if errors.Is(err, team.ErrTeamNotFound) {
|
||||
return response.Error(http.StatusNotFound, "Failed to delete Team. ID not found", nil)
|
||||
}
|
||||
|
|
@ -137,7 +139,7 @@ func (hs *HTTPServer) DeleteTeamByID(c *contextmodel.ReqContext) response.Respon
|
|||
// 401: unauthorisedError
|
||||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) SearchTeams(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) searchTeams(c *contextmodel.ReqContext) response.Response {
|
||||
perPage := c.QueryInt("perpage")
|
||||
if perPage <= 0 {
|
||||
perPage = 1000
|
||||
|
|
@ -159,11 +161,11 @@ func (hs *HTTPServer) SearchTeams(c *contextmodel.ReqContext) response.Response
|
|||
Page: page,
|
||||
Limit: perPage,
|
||||
SignedInUser: c.SignedInUser,
|
||||
HiddenUsers: hs.Cfg.HiddenUsers,
|
||||
HiddenUsers: tapi.cfg.HiddenUsers,
|
||||
SortOpts: sortOpts,
|
||||
}
|
||||
|
||||
queryResult, err := hs.teamService.SearchTeams(c.Req.Context(), &query)
|
||||
queryResult, err := tapi.teamService.SearchTeams(c.Req.Context(), &query)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to search Teams", err)
|
||||
}
|
||||
|
|
@ -174,7 +176,7 @@ func (hs *HTTPServer) SearchTeams(c *contextmodel.ReqContext) response.Response
|
|||
teamIDs[strconv.FormatInt(team.ID, 10)] = true
|
||||
}
|
||||
|
||||
metadata := hs.getMultiAccessControlMetadata(c, "teams:id:", teamIDs)
|
||||
metadata := tapi.getMultiAccessControlMetadata(c, "teams:id:", teamIDs)
|
||||
if len(metadata) > 0 {
|
||||
for _, team := range queryResult.Teams {
|
||||
team.AccessControl = metadata[strconv.FormatInt(team.ID, 10)]
|
||||
|
|
@ -197,7 +199,7 @@ func (hs *HTTPServer) SearchTeams(c *contextmodel.ReqContext) response.Response
|
|||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetTeamByID(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) getTeamByID(c *contextmodel.ReqContext) response.Response {
|
||||
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
|
|
@ -207,10 +209,10 @@ func (hs *HTTPServer) GetTeamByID(c *contextmodel.ReqContext) response.Response
|
|||
OrgID: c.SignedInUser.GetOrgID(),
|
||||
ID: teamId,
|
||||
SignedInUser: c.SignedInUser,
|
||||
HiddenUsers: hs.Cfg.HiddenUsers,
|
||||
HiddenUsers: tapi.cfg.HiddenUsers,
|
||||
}
|
||||
|
||||
queryResult, err := hs.teamService.GetTeamByID(c.Req.Context(), &query)
|
||||
queryResult, err := tapi.teamService.GetTeamByID(c.Req.Context(), &query)
|
||||
if err != nil {
|
||||
if errors.Is(err, team.ErrTeamNotFound) {
|
||||
return response.Error(http.StatusNotFound, "Team not found", err)
|
||||
|
|
@ -220,7 +222,7 @@ func (hs *HTTPServer) GetTeamByID(c *contextmodel.ReqContext) response.Response
|
|||
}
|
||||
|
||||
// Add accesscontrol metadata
|
||||
queryResult.AccessControl = hs.getAccessControlMetadata(c, c.SignedInUser.GetOrgID(), "teams:id:", strconv.FormatInt(queryResult.ID, 10))
|
||||
queryResult.AccessControl = tapi.getAccessControlMetadata(c, c.SignedInUser.GetOrgID(), "teams:id:", strconv.FormatInt(queryResult.ID, 10))
|
||||
|
||||
queryResult.AvatarURL = dtos.GetGravatarUrlWithDefault(queryResult.Email, queryResult.Name)
|
||||
return response.JSON(http.StatusOK, &queryResult)
|
||||
|
|
@ -234,13 +236,13 @@ func (hs *HTTPServer) GetTeamByID(c *contextmodel.ReqContext) response.Response
|
|||
// 200: getPreferencesResponse
|
||||
// 401: unauthorisedError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetTeamPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) getTeamPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
return hs.getPreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, teamId)
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), tapi.ds, tapi.preferenceService, c.SignedInUser.GetOrgID(), 0, teamId)
|
||||
}
|
||||
|
||||
// swagger:route PUT /teams/{team_id}/preferences teams updateTeamPreferences
|
||||
|
|
@ -252,7 +254,7 @@ func (hs *HTTPServer) GetTeamPreferences(c *contextmodel.ReqContext) response.Re
|
|||
// 400: badRequestError
|
||||
// 401: unauthorisedError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) UpdateTeamPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) updateTeamPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
dtoCmd := dtos.UpdatePrefsCmd{}
|
||||
if err := web.Bind(c.Req, &dtoCmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
|
|
@ -263,7 +265,7 @@ func (hs *HTTPServer) UpdateTeamPreferences(c *contextmodel.ReqContext) response
|
|||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
return hs.updatePreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, teamId, &dtoCmd)
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), tapi.ds, tapi.preferenceService, c.SignedInUser.GetOrgID(), 0, teamId, &dtoCmd)
|
||||
}
|
||||
|
||||
// swagger:parameters updateTeamPreferences
|
||||
|
|
@ -355,3 +357,26 @@ type CreateTeamResponse struct {
|
|||
Message string `json:"message"`
|
||||
} `json:"body"`
|
||||
}
|
||||
|
||||
// getMultiAccessControlMetadata returns the accesscontrol metadata associated with a given set of resources
|
||||
// Context must contain permissions in the given org (see LoadPermissionsMiddleware or AuthorizeInOrgMiddleware)
|
||||
func (tapi *TeamAPI) getMultiAccessControlMetadata(c *contextmodel.ReqContext,
|
||||
prefix string, resourceIDs map[string]bool) map[string]accesscontrol.Metadata {
|
||||
if !c.QueryBool("accesscontrol") {
|
||||
return map[string]accesscontrol.Metadata{}
|
||||
}
|
||||
|
||||
if len(c.SignedInUser.GetPermissions()) == 0 {
|
||||
return map[string]accesscontrol.Metadata{}
|
||||
}
|
||||
|
||||
return accesscontrol.GetResourcesMetadata(c.Req.Context(), c.SignedInUser.GetPermissions(), prefix, resourceIDs)
|
||||
}
|
||||
|
||||
// Metadata helpers
|
||||
// getAccessControlMetadata returns the accesscontrol metadata associated with a given resource
|
||||
func (tapi *TeamAPI) getAccessControlMetadata(c *contextmodel.ReqContext,
|
||||
orgID int64, prefix string, resourceID string) accesscontrol.Metadata {
|
||||
ids := map[string]bool{resourceID: true}
|
||||
return tapi.getMultiAccessControlMetadata(c, prefix, ids)[resourceID]
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package api
|
||||
package teamapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -28,7 +28,7 @@ import (
|
|||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetTeamMembers(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) getTeamMembers(c *contextmodel.ReqContext) response.Response {
|
||||
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
|
|
@ -36,21 +36,21 @@ func (hs *HTTPServer) GetTeamMembers(c *contextmodel.ReqContext) response.Respon
|
|||
|
||||
query := team.GetTeamMembersQuery{OrgID: c.SignedInUser.GetOrgID(), TeamID: teamId, SignedInUser: c.SignedInUser}
|
||||
|
||||
queryResult, err := hs.teamService.GetTeamMembers(c.Req.Context(), &query)
|
||||
queryResult, err := tapi.teamService.GetTeamMembers(c.Req.Context(), &query)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to get Team Members", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get Team Members", err)
|
||||
}
|
||||
|
||||
filteredMembers := make([]*team.TeamMemberDTO, 0, len(queryResult))
|
||||
for _, member := range queryResult {
|
||||
if dtos.IsHiddenUser(member.Login, c.SignedInUser, hs.Cfg) {
|
||||
if dtos.IsHiddenUser(member.Login, c.SignedInUser, tapi.cfg) {
|
||||
continue
|
||||
}
|
||||
|
||||
member.AvatarURL = dtos.GetGravatarUrl(member.Email)
|
||||
member.Labels = []string{}
|
||||
|
||||
if hs.License.FeatureEnabled("teamgroupsync") && member.External {
|
||||
if tapi.license.FeatureEnabled("teamgroupsync") && member.External {
|
||||
authProvider := login.GetAuthProviderLabel(member.AuthModule)
|
||||
member.Labels = append(member.Labels, authProvider)
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ func (hs *HTTPServer) GetTeamMembers(c *contextmodel.ReqContext) response.Respon
|
|||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) AddTeamMember(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) addTeamMember(c *contextmodel.ReqContext) response.Response {
|
||||
cmd := team.AddTeamMemberCommand{}
|
||||
var err error
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
|
|
@ -83,17 +83,17 @@ func (hs *HTTPServer) AddTeamMember(c *contextmodel.ReqContext) response.Respons
|
|||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
isTeamMember, err := hs.teamService.IsTeamMember(c.SignedInUser.GetOrgID(), cmd.TeamID, cmd.UserID)
|
||||
isTeamMember, err := tapi.teamService.IsTeamMember(c.SignedInUser.GetOrgID(), cmd.TeamID, cmd.UserID)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to add team member.", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to add team member.", err)
|
||||
}
|
||||
if isTeamMember {
|
||||
return response.Error(400, "User is already added to this team", nil)
|
||||
return response.Error(http.StatusBadRequest, "User is already added to this team", nil)
|
||||
}
|
||||
|
||||
err = addOrUpdateTeamMember(c.Req.Context(), hs.teamPermissionsService, cmd.UserID, cmd.OrgID, cmd.TeamID, getPermissionName(cmd.Permission))
|
||||
err = addOrUpdateTeamMember(c.Req.Context(), tapi.teamPermissionsService, cmd.UserID, cmd.OrgID, cmd.TeamID, getPermissionName(cmd.Permission))
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to add Member to Team", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to add Member to Team", err)
|
||||
}
|
||||
|
||||
return response.JSON(http.StatusOK, &util.DynMap{
|
||||
|
|
@ -111,7 +111,7 @@ func (hs *HTTPServer) AddTeamMember(c *contextmodel.ReqContext) response.Respons
|
|||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) UpdateTeamMember(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) updateTeamMember(c *contextmodel.ReqContext) response.Response {
|
||||
cmd := team.UpdateTeamMemberCommand{}
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
|
|
@ -126,17 +126,17 @@ func (hs *HTTPServer) UpdateTeamMember(c *contextmodel.ReqContext) response.Resp
|
|||
}
|
||||
orgId := c.SignedInUser.GetOrgID()
|
||||
|
||||
isTeamMember, err := hs.teamService.IsTeamMember(orgId, teamId, userId)
|
||||
isTeamMember, err := tapi.teamService.IsTeamMember(orgId, teamId, userId)
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to update team member.", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update team member.", err)
|
||||
}
|
||||
if !isTeamMember {
|
||||
return response.Error(404, "Team member not found.", nil)
|
||||
return response.Error(http.StatusNotFound, "Team member not found.", nil)
|
||||
}
|
||||
|
||||
err = addOrUpdateTeamMember(c.Req.Context(), hs.teamPermissionsService, userId, orgId, teamId, getPermissionName(cmd.Permission))
|
||||
err = addOrUpdateTeamMember(c.Req.Context(), tapi.teamPermissionsService, userId, orgId, teamId, getPermissionName(cmd.Permission))
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to update team member.", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update team member.", err)
|
||||
}
|
||||
return response.Success("Team member updated")
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ func getPermissionName(permission dashboards.PermissionType) string {
|
|||
// 403: forbiddenError
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) RemoveTeamMember(c *contextmodel.ReqContext) response.Response {
|
||||
func (tapi *TeamAPI) removeTeamMember(c *contextmodel.ReqContext) response.Response {
|
||||
orgId := c.SignedInUser.GetOrgID()
|
||||
teamId, err := strconv.ParseInt(web.Params(c.Req)[":teamId"], 10, 64)
|
||||
if err != nil {
|
||||
|
|
@ -173,16 +173,16 @@ func (hs *HTTPServer) RemoveTeamMember(c *contextmodel.ReqContext) response.Resp
|
|||
}
|
||||
|
||||
teamIDString := strconv.FormatInt(teamId, 10)
|
||||
if _, err := hs.teamPermissionsService.SetUserPermission(c.Req.Context(), orgId, accesscontrol.User{ID: userId}, teamIDString, ""); err != nil {
|
||||
if _, err := tapi.teamPermissionsService.SetUserPermission(c.Req.Context(), orgId, accesscontrol.User{ID: userId}, teamIDString, ""); err != nil {
|
||||
if errors.Is(err, team.ErrTeamNotFound) {
|
||||
return response.Error(404, "Team not found", nil)
|
||||
return response.Error(http.StatusNotFound, "Team not found", nil)
|
||||
}
|
||||
|
||||
if errors.Is(err, team.ErrTeamMemberNotFound) {
|
||||
return response.Error(404, "Team member not found", nil)
|
||||
return response.Error(http.StatusNotFound, "Team member not found", nil)
|
||||
}
|
||||
|
||||
return response.Error(500, "Failed to remove Member from Team", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to remove Member from Team", err)
|
||||
}
|
||||
return response.Success("Team Member removed")
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package api
|
||||
package teamapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
|
@ -8,24 +8,52 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/preference/preftest"
|
||||
"github.com/grafana/grafana/pkg/services/team/teamtest"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web/webtest"
|
||||
)
|
||||
|
||||
func SetupAPITestServer(t *testing.T, opts ...func(a *TeamAPI)) *webtest.Server {
|
||||
t.Helper()
|
||||
router := routing.NewRouteRegister()
|
||||
cfg := setting.NewCfg()
|
||||
cfg.LDAPAuthEnabled = true
|
||||
|
||||
a := ProvideTeamAPI(router,
|
||||
teamtest.NewFakeService(),
|
||||
actest.FakeService{},
|
||||
acimpl.ProvideAccessControl(cfg),
|
||||
&actest.FakePermissionsService{},
|
||||
&licensing.OSSLicensingService{},
|
||||
cfg,
|
||||
preftest.NewPreferenceServiceFake(),
|
||||
dashboards.NewFakeDashboardService(t),
|
||||
)
|
||||
for _, o := range opts {
|
||||
o(a)
|
||||
}
|
||||
|
||||
server := webtest.NewServer(t, router)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func TestAddTeamMembersAPIEndpoint(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
hs.teamService = teamtest.NewFakeService()
|
||||
hs.teamPermissionsService = &actest.FakePermissionsService{}
|
||||
})
|
||||
server := SetupAPITestServer(t)
|
||||
|
||||
t.Run("should be able to add team member with correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewRequest(http.MethodPost, "/api/teams/1/members", strings.NewReader("{\"userId\": 1}")),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsWrite, Scope: "teams:id:1"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsWrite, Scope: "teams:id:1"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -36,7 +64,7 @@ func TestAddTeamMembersAPIEndpoint(t *testing.T) {
|
|||
t.Run("should not be able to add team member without correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewRequest(http.MethodPost, "/api/teams/1/members", strings.NewReader("{\"userId\": 1}")),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsWrite, Scope: "teams:id:2"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsWrite, Scope: "teams:id:2"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -46,16 +74,12 @@ func TestAddTeamMembersAPIEndpoint(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetTeamMembersAPIEndpoint(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
hs.teamService = teamtest.NewFakeService()
|
||||
hs.teamPermissionsService = &actest.FakePermissionsService{}
|
||||
})
|
||||
server := SetupAPITestServer(t)
|
||||
|
||||
t.Run("should be able to get team members with correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewGetRequest("/api/teams/1/members"),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsRead, Scope: "teams:id:1"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsRead, Scope: "teams:id:1"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -65,7 +89,7 @@ func TestGetTeamMembersAPIEndpoint(t *testing.T) {
|
|||
t.Run("should not be able to get team members without correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewGetRequest("/api/teams/1/members"),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsRead, Scope: "teams:id:2"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsRead, Scope: "teams:id:2"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -75,16 +99,14 @@ func TestGetTeamMembersAPIEndpoint(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateTeamMembersAPIEndpoint(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = &teamtest.FakeService{ExpectedIsMember: true}
|
||||
hs.teamPermissionsService = &actest.FakePermissionsService{}
|
||||
})
|
||||
|
||||
t.Run("should be able to update team member with correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewRequest(http.MethodPut, "/api/teams/1/members/1", strings.NewReader("{\"permission\": 1}")),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsWrite, Scope: "teams:id:1"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsWrite, Scope: "teams:id:1"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -94,7 +116,7 @@ func TestUpdateTeamMembersAPIEndpoint(t *testing.T) {
|
|||
t.Run("should not be able to update team member without correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewRequest(http.MethodPut, "/api/teams/1/members/1", strings.NewReader("{\"permission\": 1}")),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsWrite, Scope: "teams:id:2"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsWrite, Scope: "teams:id:2"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -104,8 +126,7 @@ func TestUpdateTeamMembersAPIEndpoint(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteTeamMembersAPIEndpoint(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = &teamtest.FakeService{ExpectedIsMember: true}
|
||||
hs.teamPermissionsService = &actest.FakePermissionsService{}
|
||||
})
|
||||
|
|
@ -113,7 +134,7 @@ func TestDeleteTeamMembersAPIEndpoint(t *testing.T) {
|
|||
t.Run("should be able to delete team member with correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewRequest(http.MethodDelete, "/api/teams/1/members/1", nil),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsWrite, Scope: "teams:id:1"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsWrite, Scope: "teams:id:1"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -123,7 +144,7 @@ func TestDeleteTeamMembersAPIEndpoint(t *testing.T) {
|
|||
t.Run("should not be able to delete member without correct permission", func(t *testing.T) {
|
||||
req := webtest.RequestWithSignedInUser(
|
||||
server.NewRequest(http.MethodDelete, "/api/teams/1/members/1", nil),
|
||||
userWithPermissions(1, []ac.Permission{{Action: ac.ActionTeamsPermissionsWrite, Scope: "teams:id:2"}}),
|
||||
authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsPermissionsWrite, Scope: "teams:id:2"}}),
|
||||
)
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -131,3 +152,7 @@ func TestDeleteTeamMembersAPIEndpoint(t *testing.T) {
|
|||
require.NoError(t, res.Body.Close())
|
||||
})
|
||||
}
|
||||
|
||||
func authedUserWithPermissions(userID, orgID int64, permissions []accesscontrol.Permission) *user.SignedInUser {
|
||||
return &user.SignedInUser{UserID: userID, OrgID: orgID, OrgRole: org.RoleViewer, Permissions: map[int64]map[string][]string{orgID: accesscontrol.GroupScopesByAction(permissions)}}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package api
|
||||
package teamapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -10,14 +10,11 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
"github.com/grafana/grafana/pkg/services/preference/preftest"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
"github.com/grafana/grafana/pkg/services/team/teamtest"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web/webtest"
|
||||
)
|
||||
|
||||
|
|
@ -31,17 +28,14 @@ const (
|
|||
)
|
||||
|
||||
func TestTeamAPIEndpoint_CreateTeam(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = teamtest.NewFakeService()
|
||||
hs.AccessControl = acimpl.ProvideAccessControl(setting.NewCfg())
|
||||
hs.accesscontrolService = actest.FakeService{}
|
||||
})
|
||||
|
||||
input := strings.NewReader(fmt.Sprintf(teamCmd, 1))
|
||||
t.Run("Access control allows creating teams with the correct permissions", func(t *testing.T) {
|
||||
req := server.NewPostRequest(createTeamURL, input)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsCreate}}))
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{{Action: accesscontrol.ActionTeamsCreate}}))
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||
|
|
@ -51,7 +45,7 @@ func TestTeamAPIEndpoint_CreateTeam(t *testing.T) {
|
|||
input = strings.NewReader(fmt.Sprintf(teamCmd, 2))
|
||||
t.Run("Access control prevents creating teams with the incorrect permissions", func(t *testing.T) {
|
||||
req := server.NewPostRequest(createTeamURL, input)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{}))
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{}))
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusForbidden, res.StatusCode)
|
||||
|
|
@ -60,14 +54,13 @@ func TestTeamAPIEndpoint_CreateTeam(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTeamAPIEndpoint_SearchTeams(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = teamtest.NewFakeService()
|
||||
})
|
||||
|
||||
t.Run("Access control prevents searching for teams with the incorrect permissions", func(t *testing.T) {
|
||||
req := server.NewGetRequest(searchTeamsURL)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{}))
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{}))
|
||||
res, err := server.Send(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusForbidden, res.StatusCode)
|
||||
|
|
@ -76,7 +69,7 @@ func TestTeamAPIEndpoint_SearchTeams(t *testing.T) {
|
|||
|
||||
t.Run("Access control allows searching for teams with the correct permissions", func(t *testing.T) {
|
||||
req := server.NewGetRequest(searchTeamsURL)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
|
||||
}))
|
||||
res, err := server.Send(req)
|
||||
|
|
@ -87,8 +80,7 @@ func TestTeamAPIEndpoint_SearchTeams(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTeamAPIEndpoint_GetTeamByID(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &team.TeamDTO{}}
|
||||
})
|
||||
|
||||
|
|
@ -96,7 +88,7 @@ func TestTeamAPIEndpoint_GetTeamByID(t *testing.T) {
|
|||
|
||||
t.Run("Access control prevents getting a team when missing permissions", func(t *testing.T) {
|
||||
req := server.NewGetRequest(url)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{}))
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{}))
|
||||
res, err := server.Send(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusForbidden, res.StatusCode)
|
||||
|
|
@ -105,7 +97,7 @@ func TestTeamAPIEndpoint_GetTeamByID(t *testing.T) {
|
|||
|
||||
t.Run("Access control allows getting a team with the correct permissions", func(t *testing.T) {
|
||||
req := server.NewGetRequest(url)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:id:1"},
|
||||
}))
|
||||
res, err := server.Send(req)
|
||||
|
|
@ -116,7 +108,7 @@ func TestTeamAPIEndpoint_GetTeamByID(t *testing.T) {
|
|||
|
||||
t.Run("Access control allows getting a team with wildcard scope", func(t *testing.T) {
|
||||
req := server.NewGetRequest(url)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, []accesscontrol.Permission{
|
||||
req = webtest.RequestWithSignedInUser(req, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:id:*"},
|
||||
}))
|
||||
res, err := server.Send(req)
|
||||
|
|
@ -130,8 +122,7 @@ func TestTeamAPIEndpoint_GetTeamByID(t *testing.T) {
|
|||
// Then the endpoint should return 200 if the user has accesscontrol.ActionTeamsWrite with teams:id:1 scope
|
||||
// else return 403
|
||||
func TestTeamAPIEndpoint_UpdateTeam(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &team.TeamDTO{}}
|
||||
})
|
||||
|
||||
|
|
@ -142,7 +133,7 @@ func TestTeamAPIEndpoint_UpdateTeam(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("Access control allows updating team with the correct permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsWrite, Scope: "teams:id:1"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -151,7 +142,7 @@ func TestTeamAPIEndpoint_UpdateTeam(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Access control allows updating teams with the wildcard scope", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsWrite, Scope: "teams:*"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -160,7 +151,7 @@ func TestTeamAPIEndpoint_UpdateTeam(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Access control prevent updating a team with wrong scope", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsWrite, Scope: "teams:id:2"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -173,8 +164,7 @@ func TestTeamAPIEndpoint_UpdateTeam(t *testing.T) {
|
|||
// Then the endpoint should return 200 if the user has accesscontrol.ActionTeamsDelete with teams:id:1 scope
|
||||
// else return 403
|
||||
func TestTeamAPIEndpoint_DeleteTeam(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.teamService = &teamtest.FakeService{ExpectedTeamDTO: &team.TeamDTO{}}
|
||||
})
|
||||
|
||||
|
|
@ -185,7 +175,7 @@ func TestTeamAPIEndpoint_DeleteTeam(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("Access control prevents deleting teams with the incorrect permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsDelete, Scope: "teams:id:2"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -194,7 +184,7 @@ func TestTeamAPIEndpoint_DeleteTeam(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Access control allows deleting teams with the correct permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsDelete, Scope: "teams:id:1"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -207,8 +197,7 @@ func TestTeamAPIEndpoint_DeleteTeam(t *testing.T) {
|
|||
// Then the endpoint should return 200 if the user has accesscontrol.ActionTeamsRead with teams:id:1 scope
|
||||
// else return 403
|
||||
func TestTeamAPIEndpoint_GetTeamPreferences(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.preferenceService = &preftest.FakePreferenceService{ExpectedPreference: &pref.Preference{}}
|
||||
})
|
||||
|
||||
|
|
@ -219,7 +208,7 @@ func TestTeamAPIEndpoint_GetTeamPreferences(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("Access control allows getting team preferences with the correct permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:id:1"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -228,7 +217,7 @@ func TestTeamAPIEndpoint_GetTeamPreferences(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Access control prevents getting team preferences with the incorrect permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:id:2"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -241,8 +230,7 @@ func TestTeamAPIEndpoint_GetTeamPreferences(t *testing.T) {
|
|||
// Then the endpoint should return 200 if the user has accesscontrol.ActionTeamsWrite with teams:id:1 scope
|
||||
// else return 403
|
||||
func TestTeamAPIEndpoint_UpdateTeamPreferences(t *testing.T) {
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = setting.NewCfg()
|
||||
server := SetupAPITestServer(t, func(hs *TeamAPI) {
|
||||
hs.preferenceService = &preftest.FakePreferenceService{ExpectedPreference: &pref.Preference{}}
|
||||
})
|
||||
|
||||
|
|
@ -253,7 +241,7 @@ func TestTeamAPIEndpoint_UpdateTeamPreferences(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("Access control allows updating team preferences with the correct permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsWrite, Scope: "teams:id:1"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
|
@ -262,7 +250,7 @@ func TestTeamAPIEndpoint_UpdateTeamPreferences(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Access control prevents updating team preferences with the incorrect permissions", func(t *testing.T) {
|
||||
res, err := request(1, userWithPermissions(1, []accesscontrol.Permission{
|
||||
res, err := request(1, authedUserWithPermissions(1, 1, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsWrite, Scope: "teams:id:2"},
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
Loading…
Reference in New Issue