mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 03:12:13 +08:00
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:
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user