Skip to content

Commit

Permalink
Auth: Decouple client and hook registration (#85084)
Browse files Browse the repository at this point in the history
  • Loading branch information
kalleep committed Apr 4, 2024
1 parent bdc492b commit 504870f
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 145 deletions.
30 changes: 0 additions & 30 deletions pkg/infra/usagestats/service/accesscontrol.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/infra/usagestats/service/api.go
Expand Up @@ -15,7 +15,7 @@ func (uss *UsageStats) registerAPIEndpoints() {
authorize := accesscontrol.Middleware(uss.accesscontrol)

uss.RouteRegister.Group(rootUrl, func(subrouter routing.RouteRegister) {
subrouter.Get("/usage-report-preview", authorize(accesscontrol.EvalPermission(ActionRead)), routing.Wrap(uss.getUsageReportPreview))
subrouter.Get("/usage-report-preview", authorize(accesscontrol.EvalPermission(accesscontrol.ActionUsageStatsRead)), routing.Wrap(uss.getUsageReportPreview))
})
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/infra/usagestats/service/api_test.go
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/grafana/grafana/pkg/infra/db/dbtest"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/stats"
Expand All @@ -28,13 +29,13 @@ func TestApi_getUsageStats(t *testing.T) {
{
desc: "expect usage stats",
enabled: true,
permissions: map[string][]string{ActionRead: {}},
permissions: map[string][]string{accesscontrol.ActionUsageStatsRead: {}},
expectedStatus: 200,
},
{
desc: "expect usage stat preview still there after disabling",
enabled: false,
permissions: map[string][]string{ActionRead: {}},
permissions: map[string][]string{accesscontrol.ActionUsageStatsRead: {}},
expectedStatus: 200,
},
{
Expand Down
5 changes: 0 additions & 5 deletions pkg/infra/usagestats/service/service.go
Expand Up @@ -35,7 +35,6 @@ func ProvideService(cfg *setting.Cfg,
routeRegister routing.RouteRegister,
tracer tracing.Tracer,
accesscontrol ac.AccessControl,
accesscontrolService ac.Service,
bundleRegistry supportbundles.Service,
) (*UsageStats, error) {
s := &UsageStats{
Expand All @@ -47,10 +46,6 @@ func ProvideService(cfg *setting.Cfg,
accesscontrol: accesscontrol,
}

if err := declareFixedRoles(accesscontrolService); err != nil {
return nil, err
}

s.registerAPIEndpoints()
bundleRegistry.RegisterSupportItemCollector(s.supportBundleCollector())

Expand Down
2 changes: 0 additions & 2 deletions pkg/infra/usagestats/service/usage_stats_test.go
Expand Up @@ -23,7 +23,6 @@ import (
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tests/testsuite"
Expand Down Expand Up @@ -248,7 +247,6 @@ func createService(t *testing.T, sqlStore db.DB, withDB bool) *UsageStats {
routing.NewRouteRegister(),
tracing.InitializeTracerForTest(),
acimpl.ProvideAccessControl(cfg),
actest.FakeService{},
supportbundlestest.NewFakeBundleService(),
)

Expand Down
3 changes: 2 additions & 1 deletion pkg/registry/backgroundsvcs/background_services.go
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/anonymous/anonimpl"
grafanaapiserver "github.com/grafana/grafana/pkg/services/apiserver"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/authn/authnimpl"
"github.com/grafana/grafana/pkg/services/cleanup"
"github.com/grafana/grafana/pkg/services/cloudmigration"
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
Expand Down Expand Up @@ -68,7 +69,7 @@ func ProvideBackgroundServiceRegistry(
_ *plugindashboardsservice.DashboardUpdater, _ *sanitizer.Provider,
_ *grpcserver.HealthService, _ entity.EntityStoreServer, _ *grpcserver.ReflectionService, _ *ldapapi.Service,
_ *apiregistry.Service, _ auth.IDService, _ *teamapi.TeamAPI, _ ssosettings.Service,
_ cloudmigration.Service,
_ cloudmigration.Service, _ authnimpl.Registration,
) *BackgroundServiceRegistry {
return NewBackgroundServiceRegistry(
httpServer,
Expand Down
1 change: 1 addition & 0 deletions pkg/server/wire.go
Expand Up @@ -356,6 +356,7 @@ var wireBasicSet = wire.NewSet(
authnimpl.ProvideService,
authnimpl.ProvideIdentitySynchronizer,
authnimpl.ProvideAuthnService,
authnimpl.ProvideRegistration,
supportbundlesimpl.ProvideService,
extsvcaccounts.ProvideExtSvcAccountsService,
wire.Bind(new(serviceaccounts.ExtSvcAccountsService), new(*extsvcaccounts.ExtSvcAccountsService)),
Expand Down
3 changes: 3 additions & 0 deletions pkg/services/accesscontrol/models.go
Expand Up @@ -481,6 +481,9 @@ const (
ActionLibraryPanelsRead = "library.panels:read"
ActionLibraryPanelsWrite = "library.panels:write"
ActionLibraryPanelsDelete = "library.panels:delete"

// Usage stats actions
ActionUsageStatsRead = "server.usagestats.report:read"
)

var (
Expand Down
23 changes: 20 additions & 3 deletions pkg/services/accesscontrol/roles.go
Expand Up @@ -280,6 +280,16 @@ var (
},
},
}

usagestatsReaderRole = RoleDTO{
Name: "fixed:usagestats:reader",
DisplayName: "Usage stats report reader",
Description: "View usage statistics report",
Group: "Statistics",
Permissions: []Permission{
{Action: ActionUsageStatsRead},
},
}
)

// Declare OSS roles to the accesscontrol service
Expand Down Expand Up @@ -320,15 +330,22 @@ func DeclareFixedRoles(service Service, cfg *setting.Cfg) error {
Role: generalAuthConfigWriterRole,
Grants: []string{RoleGrafanaAdmin},
}

// TODO: Move to own service when implemented
authenticationConfigWriter := RoleRegistration{
Role: authenticationConfigWriterRole,
Grants: []string{RoleGrafanaAdmin},
}

return service.DeclareFixedRoles(ldapReader, ldapWriter, orgUsersReader, orgUsersWriter,
settingsReader, statsReader, usersReader, usersWriter, authenticationConfigWriter, generalAuthConfigWriter)
usageStatsReader := RoleRegistration{
Role: usagestatsReaderRole,
Grants: []string{RoleGrafanaAdmin},
}

return service.DeclareFixedRoles(
ldapReader, ldapWriter, orgUsersReader, orgUsersWriter,
settingsReader, statsReader, usersReader, usersWriter,
authenticationConfigWriter, generalAuthConfigWriter, usageStatsReader,
)
}

func ConcatPermissions(permissions ...[]Permission) []Permission {
Expand Down
116 changes: 116 additions & 0 deletions pkg/services/authn/authnimpl/registration.go
@@ -0,0 +1,116 @@
package authnimpl

import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/apikey"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/authn/authnimpl/sync"
"github.com/grafana/grafana/pkg/services/authn/clients"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/ldap/service"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/loginattempt"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/signingkeys"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)

type Registration struct{}

func ProvideRegistration(
cfg *setting.Cfg, authnSvc authn.Service,
orgService org.Service, sessionService auth.UserTokenService,
accessControlService accesscontrol.Service,
apikeyService apikey.Service, userService user.Service,
jwtService auth.JWTVerifierService, userProtectionService login.UserProtectionService,
loginAttempts loginattempt.Service, quotaService quota.Service,
authInfoService login.AuthInfoService, renderService rendering.Service,
features *featuremgmt.FeatureManager, oauthTokenService oauthtoken.OAuthTokenService,
socialService social.Service, cache *remotecache.RemoteCache, signingKeysService signingkeys.Service,
ldapService service.LDAP, settingsProviderService setting.Provider,
) Registration {
logger := log.New("authn.registration")

authnSvc.RegisterClient(clients.ProvideRender(renderService))
authnSvc.RegisterClient(clients.ProvideAPIKey(apikeyService))

if cfg.LoginCookieName != "" {
authnSvc.RegisterClient(clients.ProvideSession(cfg, sessionService))
}

var proxyClients []authn.ProxyClient
var passwordClients []authn.PasswordClient
if cfg.LDAPAuthEnabled {
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService)
proxyClients = append(proxyClients, ldap)
passwordClients = append(passwordClients, ldap)
}

if !cfg.DisableLogin {
grafana := clients.ProvideGrafana(cfg, userService)
proxyClients = append(proxyClients, grafana)
passwordClients = append(passwordClients, grafana)
}

// if we have password clients configure check if basic auth or form auth is enabled
if len(passwordClients) > 0 {
passwordClient := clients.ProvidePassword(loginAttempts, passwordClients...)
if cfg.BasicAuthEnabled {
authnSvc.RegisterClient(clients.ProvideBasic(passwordClient))
}

if !cfg.DisableLoginForm {
authnSvc.RegisterClient(clients.ProvideForm(passwordClient))
}
}

if cfg.AuthProxy.Enabled && len(proxyClients) > 0 {
proxy, err := clients.ProvideProxy(cfg, cache, proxyClients...)
if err != nil {
logger.Error("Failed to configure auth proxy", "err", err)
} else {
authnSvc.RegisterClient(proxy)
}
}

if cfg.JWTAuth.Enabled {
authnSvc.RegisterClient(clients.ProvideJWT(jwtService, cfg))
}

if cfg.ExtJWTAuth.Enabled && features.IsEnabledGlobally(featuremgmt.FlagAuthAPIAccessTokenAuth) {
authnSvc.RegisterClient(clients.ProvideExtendedJWT(userService, cfg, signingKeysService))
}

for name := range socialService.GetOAuthProviders() {
clientName := authn.ClientWithPrefix(name)
authnSvc.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService, settingsProviderService, features))
}

// FIXME (jguer): move to User package
userSync := sync.ProvideUserSync(userService, userProtectionService, authInfoService, quotaService)
orgSync := sync.ProvideOrgSync(userService, orgService, accessControlService, cfg)
authnSvc.RegisterPostAuthHook(userSync.SyncUserHook, 10)
authnSvc.RegisterPostAuthHook(userSync.EnableUserHook, 20)
authnSvc.RegisterPostAuthHook(orgSync.SyncOrgRolesHook, 30)
authnSvc.RegisterPostAuthHook(userSync.SyncLastSeenHook, 130)
authnSvc.RegisterPostAuthHook(sync.ProvideOAuthTokenSync(oauthTokenService, sessionService, socialService).SyncOauthTokenHook, 60)
authnSvc.RegisterPostAuthHook(userSync.FetchSyncedUserHook, 100)

rbacSync := sync.ProvideRBACSync(accessControlService)
if features.IsEnabledGlobally(featuremgmt.FlagCloudRBACRoles) {
authnSvc.RegisterPostAuthHook(rbacSync.SyncCloudRoles, 110)
}

authnSvc.RegisterPostAuthHook(rbacSync.SyncPermissionsHook, 120)
authnSvc.RegisterPostAuthHook(orgSync.SetDefaultOrgHook, 130)

return Registration{}
}

0 comments on commit 504870f

Please sign in to comment.