mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Authn: external identity sync (#73461)
* Authn: Add interface for external identity sync This interface is implemented by authnimpl.Service and just triggers PostAuthHooks and skipping last seen update by default * Authn: Add SyncIdentity to fake and add a new mock
This commit is contained in:
parent
878e94ae25
commit
124e0efe1f
@ -40,6 +40,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey/apikeyimpl"
|
"github.com/grafana/grafana/pkg/services/apikey/apikeyimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/jwt"
|
"github.com/grafana/grafana/pkg/services/auth/jwt"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/authn/authnimpl"
|
"github.com/grafana/grafana/pkg/services/authn/authnimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/certgenerator"
|
"github.com/grafana/grafana/pkg/services/certgenerator"
|
||||||
"github.com/grafana/grafana/pkg/services/cleanup"
|
"github.com/grafana/grafana/pkg/services/cleanup"
|
||||||
@ -350,6 +351,8 @@ var wireBasicSet = wire.NewSet(
|
|||||||
tagimpl.ProvideService,
|
tagimpl.ProvideService,
|
||||||
wire.Bind(new(tag.Service), new(*tagimpl.Service)),
|
wire.Bind(new(tag.Service), new(*tagimpl.Service)),
|
||||||
authnimpl.ProvideService,
|
authnimpl.ProvideService,
|
||||||
|
wire.Bind(new(authn.Service), new(*authnimpl.Service)),
|
||||||
|
wire.Bind(new(authn.IdentitySynchronizer), new(*authnimpl.Service)),
|
||||||
supportbundlesimpl.ProvideService,
|
supportbundlesimpl.ProvideService,
|
||||||
grafanaapiserver.WireSet,
|
grafanaapiserver.WireSet,
|
||||||
oasimpl.ProvideService,
|
oasimpl.ProvideService,
|
||||||
|
@ -84,6 +84,10 @@ type Service interface {
|
|||||||
RegisterClient(c Client)
|
RegisterClient(c Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IdentitySynchronizer interface {
|
||||||
|
SyncIdentity(ctx context.Context, identity *Identity) error
|
||||||
|
}
|
||||||
|
|
||||||
type Client interface {
|
type Client interface {
|
||||||
// Name returns the name of a client
|
// Name returns the name of a client
|
||||||
Name() string
|
Name() string
|
||||||
|
@ -50,6 +50,9 @@ var (
|
|||||||
// make sure service implements authn.Service interface
|
// make sure service implements authn.Service interface
|
||||||
var _ authn.Service = new(Service)
|
var _ authn.Service = new(Service)
|
||||||
|
|
||||||
|
// make sure service implements authn.IdentitySynchronizer interface
|
||||||
|
var _ authn.IdentitySynchronizer = new(Service)
|
||||||
|
|
||||||
func ProvideService(
|
func ProvideService(
|
||||||
cfg *setting.Cfg, tracer tracing.Tracer,
|
cfg *setting.Cfg, tracer tracing.Tracer,
|
||||||
orgService org.Service, sessionService auth.UserTokenService,
|
orgService org.Service, sessionService auth.UserTokenService,
|
||||||
@ -65,7 +68,7 @@ func ProvideService(
|
|||||||
socialService social.Service, cache *remotecache.RemoteCache,
|
socialService social.Service, cache *remotecache.RemoteCache,
|
||||||
ldapService service.LDAP, registerer prometheus.Registerer,
|
ldapService service.LDAP, registerer prometheus.Registerer,
|
||||||
signingKeysService signingkeys.Service, oauthServer oauthserver.OAuth2Server,
|
signingKeysService signingkeys.Service, oauthServer oauthserver.OAuth2Server,
|
||||||
) authn.Service {
|
) *Service {
|
||||||
s := &Service{
|
s := &Service{
|
||||||
log: log.New("authn.service"),
|
log: log.New("authn.service"),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
@ -228,11 +231,9 @@ func (s *Service) authenticate(ctx context.Context, c authn.Client, r *authn.Req
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hook := range s.postAuthHooks.items {
|
if err := s.runPostAuthHooks(ctx, identity, r); err != nil {
|
||||||
if err := hook.v(ctx, identity, r); err != nil {
|
s.log.FromContext(ctx).Warn("Failed to run post auth hook", "client", c.Name(), "id", identity.ID, "error", err)
|
||||||
s.log.FromContext(ctx).Warn("Failed to run post auth hook", "client", c.Name(), "id", identity.ID, "error", err)
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if identity.IsDisabled {
|
if identity.IsDisabled {
|
||||||
@ -249,6 +250,15 @@ func (s *Service) authenticate(ctx context.Context, c authn.Client, r *authn.Req
|
|||||||
return identity, nil
|
return identity, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) runPostAuthHooks(ctx context.Context, identity *authn.Identity, r *authn.Request) error {
|
||||||
|
for _, hook := range s.postAuthHooks.items {
|
||||||
|
if err := hook.v(ctx, identity, r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) RegisterPostAuthHook(hook authn.PostAuthHookFn, priority uint) {
|
func (s *Service) RegisterPostAuthHook(hook authn.PostAuthHookFn, priority uint) {
|
||||||
s.postAuthHooks.insert(hook, priority)
|
s.postAuthHooks.insert(hook, priority)
|
||||||
}
|
}
|
||||||
@ -332,6 +342,13 @@ func (s *Service) RegisterClient(c authn.Client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) SyncIdentity(ctx context.Context, identity *authn.Identity) error {
|
||||||
|
r := &authn.Request{OrgID: identity.OrgID}
|
||||||
|
// hack to not update last seen on external syncs
|
||||||
|
r.SetMeta(authn.MetaKeyIsLogin, "true")
|
||||||
|
return s.runPostAuthHooks(ctx, identity, r)
|
||||||
|
}
|
||||||
|
|
||||||
func orgIDFromRequest(r *authn.Request) int64 {
|
func orgIDFromRequest(r *authn.Request) int64 {
|
||||||
if r.HTTPRequest == nil {
|
if r.HTTPRequest == nil {
|
||||||
return 0
|
return 0
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ authn.Service = new(FakeService)
|
var _ authn.Service = new(FakeService)
|
||||||
|
var _ authn.IdentitySynchronizer = new(FakeService)
|
||||||
|
|
||||||
type FakeService struct {
|
type FakeService struct {
|
||||||
ExpectedErr error
|
ExpectedErr error
|
||||||
@ -67,6 +68,10 @@ func (f *FakeService) RedirectURL(ctx context.Context, client string, r *authn.R
|
|||||||
|
|
||||||
func (f *FakeService) RegisterClient(c authn.Client) {}
|
func (f *FakeService) RegisterClient(c authn.Client) {}
|
||||||
|
|
||||||
|
func (f *FakeService) SyncIdentity(ctx context.Context, identity *authn.Identity) error {
|
||||||
|
return f.ExpectedErr
|
||||||
|
}
|
||||||
|
|
||||||
var _ authn.ContextAwareClient = new(FakeClient)
|
var _ authn.ContextAwareClient = new(FakeClient)
|
||||||
|
|
||||||
type FakeClient struct {
|
type FakeClient struct {
|
||||||
|
@ -6,6 +6,44 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ authn.Service = new(MockService)
|
||||||
|
var _ authn.IdentitySynchronizer = new(MockService)
|
||||||
|
|
||||||
|
type MockService struct {
|
||||||
|
SyncIdentityFunc func(ctx context.Context, identity *authn.Identity) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) Login(ctx context.Context, client string, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) RedirectURL(ctx context.Context, client string, r *authn.Request) (*authn.Redirect, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) RegisterClient(c authn.Client) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) RegisterPostAuthHook(hook authn.PostAuthHookFn, priority uint) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) RegisterPostLoginHook(hook authn.PostLoginHookFn, priority uint) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockService) SyncIdentity(ctx context.Context, identity *authn.Identity) error {
|
||||||
|
if m.SyncIdentityFunc != nil {
|
||||||
|
return m.SyncIdentityFunc(ctx, identity)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var _ authn.HookClient = new(MockClient)
|
var _ authn.HookClient = new(MockClient)
|
||||||
var _ authn.ContextAwareClient = new(MockClient)
|
var _ authn.ContextAwareClient = new(MockClient)
|
||||||
|
|
||||||
|
@ -16,9 +16,10 @@ type FakeUserService struct {
|
|||||||
ExpectedUserProfileDTOs []*user.UserProfileDTO
|
ExpectedUserProfileDTOs []*user.UserProfileDTO
|
||||||
ExpectedUsageStats map[string]interface{}
|
ExpectedUsageStats map[string]interface{}
|
||||||
|
|
||||||
GetSignedInUserFn func(ctx context.Context, query *user.GetSignedInUserQuery) (*user.SignedInUser, error)
|
GetSignedInUserFn func(ctx context.Context, query *user.GetSignedInUserQuery) (*user.SignedInUser, error)
|
||||||
CreateFn func(ctx context.Context, cmd *user.CreateUserCommand) (*user.User, error)
|
CreateFn func(ctx context.Context, cmd *user.CreateUserCommand) (*user.User, error)
|
||||||
DisableFn func(ctx context.Context, cmd *user.DisableUserCommand) error
|
DisableFn func(ctx context.Context, cmd *user.DisableUserCommand) error
|
||||||
|
BatchDisableUsersFn func(ctx context.Context, cmd *user.BatchDisableUsersCommand) error
|
||||||
|
|
||||||
counter int
|
counter int
|
||||||
}
|
}
|
||||||
@ -105,6 +106,9 @@ func (f *FakeUserService) Disable(ctx context.Context, cmd *user.DisableUserComm
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeUserService) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisableUsersCommand) error {
|
func (f *FakeUserService) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisableUsersCommand) error {
|
||||||
|
if f.BatchDisableUsersFn != nil {
|
||||||
|
return f.BatchDisableUsersFn(ctx, cmd)
|
||||||
|
}
|
||||||
return f.ExpectedError
|
return f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user