Apiserver: Refactor authenticator and authorizers (#101449)

* Clean up authenticator

* Cleanup authorizers and replace org_id and stack_id with namespace authorizer

* Remove dependency on org service

* Extract orgID from /apis/ urls and validate stack id
This commit is contained in:
Karl Persson
2025-03-06 16:01:12 +01:00
committed by GitHub
parent 0a24a7cd4c
commit 43f56c5ca1
16 changed files with 372 additions and 375 deletions

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
goerrors "errors"
"fmt"
"io"
"net/http"
@ -49,7 +50,10 @@ import (
"github.com/grafana/grafana/pkg/tests/testinfra"
)
const Org1 = "Org1"
const (
Org1 = "Org1"
Org2 = "OrgB"
)
type K8sTestHelper struct {
t *testing.T
@ -61,6 +65,10 @@ type K8sTestHelper struct {
// // Registered groups
groups []metav1.APIGroup
orgSvc org.Service
teamSvc team.Service
userSvc user.Service
}
func NewK8sTestHelper(t *testing.T, opts testinfra.GrafanaOpts) *K8sTestHelper {
@ -85,8 +93,27 @@ func NewK8sTestHelper(t *testing.T, opts testinfra.GrafanaOpts) *K8sTestHelper {
Namespacer: request.GetNamespaceMapper(nil),
}
quotaService := quotaimpl.ProvideService(c.env.SQLStore, c.env.Cfg)
orgSvc, err := orgimpl.ProvideService(c.env.SQLStore, c.env.Cfg, quotaService)
require.NoError(c.t, err)
c.orgSvc = orgSvc
teamSvc, err := teamimpl.ProvideService(c.env.SQLStore, c.env.Cfg, tracing.NewNoopTracerService())
require.NoError(c.t, err)
c.teamSvc = teamSvc
userSvc, err := userimpl.ProvideService(
c.env.SQLStore, orgSvc, c.env.Cfg, teamSvc,
localcache.ProvideService(), tracing.NewNoopTracerService(), quotaService,
supportbundlestest.NewFakeBundleService())
require.NoError(c.t, err)
c.userSvc = userSvc
_ = c.CreateOrg(Org1)
_ = c.CreateOrg(Org2)
c.Org1 = c.createTestUsers(Org1)
c.OrgB = c.createTestUsers("OrgB")
c.OrgB = c.createTestUsers(Org2)
c.loadAPIGroups()
@ -455,6 +482,7 @@ func (c *K8sTestHelper) createTestUsers(orgName string) OrgUsers {
Editor: c.CreateUser("editor", orgName, org.RoleEditor, nil),
Viewer: c.CreateUser("viewer", orgName, org.RoleViewer, nil),
}
users.Staff = c.CreateTeam("staff", "staff@"+orgName, users.Admin.Identity.GetOrgID())
// Add Admin and Editor to Staff team as Admin and Member, respectively.
@ -464,61 +492,67 @@ func (c *K8sTestHelper) createTestUsers(orgName string) OrgUsers {
return users
}
func (c *K8sTestHelper) CreateOrg(name string) int64 {
if name == Org1 {
return 1
}
oldAssing := c.env.Cfg.AutoAssignOrg
defer func() {
c.env.Cfg.AutoAssignOrg = oldAssing
}()
c.env.Cfg.AutoAssignOrg = false
o, err := c.orgSvc.GetByName(context.Background(), &org.GetOrgByNameQuery{
Name: name,
})
if goerrors.Is(err, org.ErrOrgNotFound) {
id, err := c.orgSvc.GetOrCreate(context.Background(), name)
require.NoError(c.t, err)
return id
}
require.NoError(c.t, err)
return o.ID
}
func (c *K8sTestHelper) CreateUser(name string, orgName string, basicRole org.RoleType, permissions []resourcepermissions.SetResourcePermissionCommand) User {
c.t.Helper()
store := c.env.SQLStore
defer func() {
c.env.Cfg.AutoAssignOrg = false
c.env.Cfg.AutoAssignOrgId = 1 // the default
}()
quotaService := quotaimpl.ProvideService(store, c.env.Cfg)
orgService, err := orgimpl.ProvideService(store, c.env.Cfg, quotaService)
require.NoError(c.t, err)
orgId := int64(1)
if orgName != Org1 {
o, err := orgService.GetByName(context.Background(), &org.GetOrgByNameQuery{Name: orgName})
if err != nil {
if !org.ErrOrgNotFound.Is(err) {
require.NoError(c.t, err)
}
orgId, err = orgService.GetOrCreate(context.Background(), orgName)
require.NoError(c.t, err)
} else {
orgId = o.ID
}
}
c.env.Cfg.AutoAssignOrg = true
c.env.Cfg.AutoAssignOrgId = int(orgId)
teamSvc, err := teamimpl.ProvideService(store, c.env.Cfg, tracing.InitializeTracerForTest())
require.NoError(c.t, err)
cache := localcache.ProvideService()
userSvc, err := userimpl.ProvideService(
store, orgService, c.env.Cfg, teamSvc,
cache, tracing.InitializeTracerForTest(), quotaService,
supportbundlestest.NewFakeBundleService())
require.NoError(c.t, err)
orgId := c.CreateOrg(orgName)
baseUrl := fmt.Sprintf("http://%s", c.env.Server.HTTPServer.Listener.Addr())
u, err := userSvc.Create(context.Background(), &user.CreateUserCommand{
// make org1 admins grafana admins
isGrafanaAdmin := basicRole == identity.RoleAdmin && orgId == 1
u, err := c.userSvc.Create(context.Background(), &user.CreateUserCommand{
DefaultOrgRole: string(basicRole),
Password: user.Password(name),
Login: fmt.Sprintf("%s-%d", name, orgId),
OrgID: orgId,
IsAdmin: basicRole == identity.RoleAdmin && orgId == 1, // make org1 admins grafana admins
IsAdmin: isGrafanaAdmin,
})
// for tests to work we need to add grafana admins to every org
if isGrafanaAdmin {
orgs, err := c.orgSvc.Search(context.Background(), &org.SearchOrgsQuery{})
require.NoError(c.t, err)
for _, o := range orgs {
_ = c.orgSvc.AddOrgUser(context.Background(), &org.AddOrgUserCommand{
Role: identity.RoleAdmin,
OrgID: o.ID,
UserID: u.ID,
})
}
}
require.NoError(c.t, err)
require.Equal(c.t, orgId, u.OrgID)
require.True(c.t, u.ID > 0)
// should this always return a user with ID token?
s, err := userSvc.GetSignedInUser(context.Background(), &user.GetSignedInUserQuery{
s, err := c.userSvc.GetSignedInUser(context.Background(), &user.GetSignedInUserQuery{
UserID: u.ID,
Login: u.Login,
Email: u.Email,
@ -563,19 +597,6 @@ func (c *K8sTestHelper) SetPermissions(user User, permissions []resourcepermissi
}
func (c *K8sTestHelper) AddOrUpdateTeamMember(user User, teamID int64, permission team.PermissionType) {
teamSvc, err := teamimpl.ProvideService(c.env.SQLStore, c.env.Cfg, tracing.InitializeTracerForTest())
require.NoError(c.t, err)
orgService, err := orgimpl.ProvideService(c.env.SQLStore, c.env.Cfg, c.env.Server.HTTPServer.QuotaService)
require.NoError(c.t, err)
cache := localcache.ProvideService()
userSvc, err := userimpl.ProvideService(
c.env.SQLStore, orgService, c.env.Cfg, teamSvc,
cache, tracing.InitializeTracerForTest(), c.env.Server.HTTPServer.QuotaService,
supportbundlestest.NewFakeBundleService())
require.NoError(c.t, err)
teampermissionSvc, err := ossaccesscontrol.ProvideTeamPermissions(
c.env.Cfg,
c.env.FeatureToggles,
@ -584,8 +605,8 @@ func (c *K8sTestHelper) AddOrUpdateTeamMember(user User, teamID int64, permissio
c.env.Server.HTTPServer.AccessControl,
c.env.Server.HTTPServer.License,
c.env.Server.HTTPServer.AlertNG.AccesscontrolService,
teamSvc,
userSvc,
c.teamSvc,
c.userSvc,
resourcepermissions.NewActionSetService(c.env.FeatureToggles),
)
require.NoError(c.t, err)
@ -662,7 +683,7 @@ func (c *K8sTestHelper) CreateDS(cmd *datasources.AddDataSourceCommand) *datasou
func (c *K8sTestHelper) CreateTeam(name, email string, orgID int64) team.Team {
c.t.Helper()
team, err := c.env.Server.HTTPServer.TeamService.CreateTeam(context.Background(), name, email, orgID)
team, err := c.teamSvc.CreateTeam(context.Background(), name, email, orgID)
require.NoError(c.t, err)
return team
}