Authn: Add function to resolve identity from org and namespace id (#84555)
* Add function to get the namespaced id * Add function to resolve an identity through authn.Service from org and namespace id * Switch to resolve identity for re-authenticate in another org
This commit is contained in:
@@ -77,6 +77,10 @@ type Service interface {
|
||||
RedirectURL(ctx context.Context, client string, r *Request) (*Redirect, error)
|
||||
// Logout revokes session token and does additional clean up if client used to authenticate supports it
|
||||
Logout(ctx context.Context, user identity.Requester, sessionToken *usertoken.UserToken) (*Redirect, error)
|
||||
|
||||
// ResolveIdentity resolves an identity from org and namespace id.
|
||||
ResolveIdentity(ctx context.Context, orgID int64, namespaceID string) (*Identity, error)
|
||||
|
||||
// RegisterClient will register a new authn.Client that can be used for authentication
|
||||
RegisterClient(c Client)
|
||||
}
|
||||
|
||||
@@ -391,6 +391,20 @@ Default:
|
||||
return redirect, nil
|
||||
}
|
||||
|
||||
func (s *Service) ResolveIdentity(ctx context.Context, orgID int64, namespaceID string) (*authn.Identity, error) {
|
||||
r := &authn.Request{}
|
||||
r.OrgID = orgID
|
||||
// hack to not update last seen
|
||||
r.SetMeta(authn.MetaKeyIsLogin, "true")
|
||||
|
||||
identity, err := s.authenticate(ctx, clients.ProvideIdentity(namespaceID), r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return identity, nil
|
||||
}
|
||||
|
||||
func (s *Service) RegisterClient(c authn.Client) {
|
||||
s.clients[c.Name()] = c
|
||||
if cac, ok := c.(authn.ContextAwareClient); ok {
|
||||
|
||||
@@ -68,7 +68,11 @@ func (f *FakeService) RedirectURL(ctx context.Context, client string, r *authn.R
|
||||
return f.ExpectedRedirect, f.ExpectedErr
|
||||
}
|
||||
|
||||
func (*FakeService) Logout(_ context.Context, _ identity.Requester, _ *usertoken.UserToken) (*authn.Redirect, error) {
|
||||
func (f *FakeService) Logout(_ context.Context, _ identity.Requester, _ *usertoken.UserToken) (*authn.Redirect, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (f *FakeService) ResolveIdentity(ctx context.Context, orgID int64, namespaceID string) (*authn.Identity, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,10 @@ func (*MockService) Logout(_ context.Context, _ identity.Requester, _ *usertoken
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (m *MockService) ResolveIdentity(ctx context.Context, orgID int64, namespaceID string) (*authn.Identity, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (m *MockService) SyncIdentity(ctx context.Context, identity *authn.Identity) error {
|
||||
if m.SyncIdentityFunc != nil {
|
||||
return m.SyncIdentityFunc(ctx, identity)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package clients
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/authn"
|
||||
)
|
||||
|
||||
var _ authn.Client = (*IdentityClient)(nil)
|
||||
|
||||
func ProvideIdentity(namespaceID string) *IdentityClient {
|
||||
return &IdentityClient{namespaceID}
|
||||
}
|
||||
|
||||
type IdentityClient struct {
|
||||
namespaceID string
|
||||
}
|
||||
|
||||
func (i *IdentityClient) Name() string {
|
||||
return "identity"
|
||||
}
|
||||
|
||||
// Authenticate implements authn.Client.
|
||||
func (i *IdentityClient) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||
return &authn.Identity{
|
||||
OrgID: r.OrgID,
|
||||
ID: i.namespaceID,
|
||||
ClientParams: authn.ClientParams{
|
||||
FetchSyncedUser: true,
|
||||
SyncPermissions: true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -87,6 +87,18 @@ type Identity struct {
|
||||
IDToken string
|
||||
}
|
||||
|
||||
func (i *Identity) GetID() string {
|
||||
return i.ID
|
||||
}
|
||||
|
||||
func (i *Identity) GetNamespacedID() (namespace string, identifier string) {
|
||||
split := strings.Split(i.GetID(), ":")
|
||||
if len(split) != 2 {
|
||||
return "", ""
|
||||
}
|
||||
return split[0], split[1]
|
||||
}
|
||||
|
||||
func (i *Identity) GetAuthenticatedBy() string {
|
||||
return i.AuthenticatedBy
|
||||
}
|
||||
@@ -122,16 +134,6 @@ func (i *Identity) GetLogin() string {
|
||||
return i.Login
|
||||
}
|
||||
|
||||
func (i *Identity) GetNamespacedID() (namespace string, identifier string) {
|
||||
split := strings.Split(i.ID, ":")
|
||||
|
||||
if len(split) != 2 {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
return split[0], split[1]
|
||||
}
|
||||
|
||||
// GetOrgID implements identity.Requester.
|
||||
func (i *Identity) GetOrgID() int64 {
|
||||
return i.OrgID
|
||||
|
||||
Reference in New Issue
Block a user