Authn: Identity resolvers (#85930)

* AuthN: Add NamespaceID struct. We should replace the usage of encoded namespaceID with this one

* AuthN: Add optional interface that clients can implement to be able to resolve identity for a namespace

* Authn: Implement IdentityResolverClient for api keys

* AuthN: use idenity resolvers

Co-authored-by: Misi <mgyongyosi@users.noreply.github.com>
This commit is contained in:
Karl Persson
2024-04-12 11:38:20 +02:00
committed by GitHub
co-authored by Misi
parent c837d95677
commit 73fecc8d80
11 changed files with 409 additions and 87 deletions
+52 -8
View File
@@ -383,6 +383,49 @@ func TestService_Logout(t *testing.T) {
}
}
func TestService_ResolveIdentity(t *testing.T) {
t.Run("should return error for for unknown namespace", func(t *testing.T) {
svc := setupTests(t)
_, err := svc.ResolveIdentity(context.Background(), 1, "some:1")
assert.ErrorIs(t, err, authn.ErrInvalidNamepsaceID)
})
t.Run("should return error for for namespace that don't have a resolver", func(t *testing.T) {
svc := setupTests(t)
_, err := svc.ResolveIdentity(context.Background(), 1, "api-key:1")
assert.ErrorIs(t, err, authn.ErrUnsupportedIdentity)
})
t.Run("should resolve for user", func(t *testing.T) {
svc := setupTests(t)
identity, err := svc.ResolveIdentity(context.Background(), 1, "user:1")
assert.NoError(t, err)
assert.NotNil(t, identity)
})
t.Run("should resolve for service account", func(t *testing.T) {
svc := setupTests(t)
identity, err := svc.ResolveIdentity(context.Background(), 1, "service-account:1")
assert.NoError(t, err)
assert.NotNil(t, identity)
})
t.Run("should resolve for valid namespace if client is registered", func(t *testing.T) {
svc := setupTests(t, func(svc *Service) {
svc.RegisterClient(&authntest.MockClient{
NamespaceFunc: func() string { return authn.NamespaceAPIKey },
ResolveIdentityFunc: func(ctx context.Context, orgID int64, namespaceID authn.NamespaceID) (*authn.Identity, error) {
return &authn.Identity{}, nil
},
})
})
identity, err := svc.ResolveIdentity(context.Background(), 1, "api-key:1")
assert.NoError(t, err)
assert.NotNil(t, identity)
})
}
func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
@@ -395,14 +438,15 @@ func setupTests(t *testing.T, opts ...func(svc *Service)) *Service {
t.Helper()
s := &Service{
log: log.NewNopLogger(),
cfg: setting.NewCfg(),
clients: map[string]authn.Client{},
clientQueue: newQueue[authn.ContextAwareClient](),
tracer: tracing.InitializeTracerForTest(),
metrics: newMetrics(nil),
postAuthHooks: newQueue[authn.PostAuthHookFn](),
postLoginHooks: newQueue[authn.PostLoginHookFn](),
log: log.NewNopLogger(),
cfg: setting.NewCfg(),
clients: make(map[string]authn.Client),
clientQueue: newQueue[authn.ContextAwareClient](),
idenityResolverClients: make(map[string]authn.IdentityResolverClient),
tracer: tracing.InitializeTracerForTest(),
metrics: newMetrics(nil),
postAuthHooks: newQueue[authn.PostAuthHookFn](),
postLoginHooks: newQueue[authn.PostLoginHookFn](),
}
for _, o := range opts {