AuthN: Add interface and function to operate on clients that supports redirects (#61905)

This commit is contained in:
Karl Persson
2023-01-23 11:54:38 +01:00
committed by GitHub
parent db51e963de
commit 50608db59a
5 changed files with 94 additions and 0 deletions

View File

@@ -29,6 +29,10 @@ import (
"github.com/grafana/grafana/pkg/web"
)
const (
attributeKeyClient = "authn.client"
)
var (
errDisabledIdentity = errutil.NewBase(errutil.StatusUnauthorized, "identity.disabled")
)
@@ -220,6 +224,24 @@ func (s *Service) RegisterPostLoginHook(hook authn.PostLoginHookFn) {
s.postLoginHooks = append(s.postLoginHooks, hook)
}
func (s *Service) RedirectURL(ctx context.Context, client string, r *authn.Request) (string, error) {
ctx, span := s.tracer.Start(ctx, "authn.RedirectURL")
defer span.End()
span.SetAttributes(attributeKeyClient, client, attribute.Key(attributeKeyClient).String(client))
c, ok := s.clients[client]
if !ok {
return "", authn.ErrClientNotConfigured.Errorf("client not configured: %s", client)
}
redirectClient, ok := c.(authn.RedirectClient)
if !ok {
return "", authn.ErrUnsupportedClient.Errorf("client does not support generating redirect url: %s", client)
}
return redirectClient.RedirectURL(ctx, r)
}
func orgIDFromRequest(r *authn.Request) int64 {
if r.HTTPRequest == nil {
return 0

View File

@@ -210,6 +210,49 @@ func TestService_Login(t *testing.T) {
}
}
func TestService_RedirectURL(t *testing.T) {
type testCase struct {
desc string
client string
expectedURL string
expectedErr error
}
tests := []testCase{
{
desc: "should generate url for valid redirect client",
client: "redirect",
expectedURL: "https://localhost/redirect",
expectedErr: nil,
},
{
desc: "should return error on non existing client",
client: "non-existing",
expectedErr: authn.ErrClientNotConfigured,
},
{
desc: "should return error when client don't support the redirect interface",
client: "non-redirect",
expectedErr: authn.ErrUnsupportedClient,
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service := setupTests(t, func(svc *Service) {
svc.clients["redirect"] = authntest.FakeRedirectClient{
ExpectedURL: tt.expectedURL,
}
svc.clients["non-redirect"] = &authntest.FakeClient{}
})
u, err := service.RedirectURL(context.Background(), tt.client, nil)
assert.ErrorIs(t, err, tt.expectedErr)
assert.Equal(t, tt.expectedURL, u)
})
}
}
func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {