Start returning user info in LoginRequest response.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
Signed-off-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
Matt Moyer 2020-07-24 10:21:36 -05:00
parent 9af3637403
commit 84bb0a9a21
2 changed files with 30 additions and 6 deletions

View File

@ -103,7 +103,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
} }
}() }()
_, authenticated, err := r.webhook.AuthenticateToken(cancelCtx, token.Value) authResponse, authenticated, err := r.webhook.AuthenticateToken(cancelCtx, token.Value)
if err != nil { if err != nil {
klog.Warningf("webhook authentication failure: %v", err) klog.Warningf("webhook authentication failure: %v", err)
return failureResponse(), nil return failureResponse(), nil
@ -111,7 +111,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
var out *placeholderapi.LoginRequest var out *placeholderapi.LoginRequest
if authenticated { if authenticated {
out = successfulResponse() out = successfulResponse(authResponse)
} else { } else {
out = failureResponse() out = failureResponse()
} }
@ -119,7 +119,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
return out, nil return out, nil
} }
func successfulResponse() *placeholderapi.LoginRequest { func successfulResponse(authResponse *authenticator.Response) *placeholderapi.LoginRequest {
return &placeholderapi.LoginRequest{ return &placeholderapi.LoginRequest{
Status: placeholderapi.LoginRequestStatus{ Status: placeholderapi.LoginRequestStatus{
Credential: &placeholderapi.LoginRequestCredential{ Credential: &placeholderapi.LoginRequestCredential{
@ -128,6 +128,10 @@ func successfulResponse() *placeholderapi.LoginRequest {
ClientCertificateData: "", ClientCertificateData: "",
ClientKeyData: "", ClientKeyData: "",
}, },
User: &placeholderapi.User{
Name: authResponse.User.GetName(),
Groups: authResponse.User.GetGroups(),
},
}, },
} }
} }

View File

@ -16,6 +16,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request" genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/registry/rest"
@ -31,8 +32,9 @@ type FakeToken struct {
reachedTimeout bool reachedTimeout bool
cancelled bool cancelled bool
webhookStartedRunningNotificationChan chan bool webhookStartedRunningNotificationChan chan bool
returnErr error returnResponse *authenticator.Response
returnUnauthenticated bool returnUnauthenticated bool
returnErr error
} }
func (f *FakeToken) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) { func (f *FakeToken) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) {
@ -48,7 +50,7 @@ func (f *FakeToken) AuthenticateToken(ctx context.Context, token string) (*authe
case <-ctx.Done(): case <-ctx.Done():
f.cancelled = true f.cancelled = true
} }
return &authenticator.Response{}, !f.returnUnauthenticated, f.returnErr return f.returnResponse, !f.returnUnauthenticated, f.returnErr
} }
func callCreate(ctx context.Context, storage *REST, loginRequest *placeholderapi.LoginRequest) (runtime.Object, error) { func callCreate(ctx context.Context, storage *REST, loginRequest *placeholderapi.LoginRequest) (runtime.Object, error) {
@ -91,8 +93,18 @@ func requireAPIError(t *testing.T, response runtime.Object, err error, expectedE
require.Contains(t, status.Status().Message, expectedErrorMessage) require.Contains(t, status.Status().Message, expectedErrorMessage)
} }
func emptyWebhookSuccessResponse() *authenticator.Response {
return &authenticator.Response{User: &user.DefaultInfo{}}
}
func TestCreateSucceedsWhenGivenATokenAndTheWebhookAuthenticatesTheToken(t *testing.T) { func TestCreateSucceedsWhenGivenATokenAndTheWebhookAuthenticatesTheToken(t *testing.T) {
webhook := FakeToken{ webhook := FakeToken{
returnResponse: &authenticator.Response{
User: &user.DefaultInfo{
Name: "test-user",
Groups: []string{"test-group-1", "test-group-2"},
},
},
returnUnauthenticated: false, returnUnauthenticated: false,
} }
storage := NewREST(&webhook) storage := NewREST(&webhook)
@ -103,6 +115,10 @@ func TestCreateSucceedsWhenGivenATokenAndTheWebhookAuthenticatesTheToken(t *test
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, response, &placeholderapi.LoginRequest{ require.Equal(t, response, &placeholderapi.LoginRequest{
Status: placeholderapi.LoginRequestStatus{ Status: placeholderapi.LoginRequestStatus{
User: &placeholderapi.User{
Name: "test-user",
Groups: []string{"test-group-1", "test-group-2"},
},
Credential: &placeholderapi.LoginRequestCredential{ Credential: &placeholderapi.LoginRequestCredential{
ExpirationTimestamp: nil, ExpirationTimestamp: nil,
Token: "snorlax", Token: "snorlax",
@ -152,7 +168,9 @@ func TestCreateSucceedsWithAnUnauthenticatedStatusWhenWebhookFails(t *testing.T)
} }
func TestCreateDoesNotPassAdditionalContextInfoToTheWebhook(t *testing.T) { func TestCreateDoesNotPassAdditionalContextInfoToTheWebhook(t *testing.T) {
webhook := FakeToken{} webhook := FakeToken{
returnResponse: emptyWebhookSuccessResponse(),
}
storage := NewREST(&webhook) storage := NewREST(&webhook)
ctx := context.WithValue(context.Background(), contextKey{}, "context-value") ctx := context.WithValue(context.Background(), contextKey{}, "context-value")
@ -235,6 +253,7 @@ func TestCreateCancelsTheWebhookInvocationWhenTheCallToCreateIsCancelledItself(t
webhook := FakeToken{ webhook := FakeToken{
timeout: time.Second * 2, timeout: time.Second * 2,
webhookStartedRunningNotificationChan: webhookStartedRunningNotificationChan, webhookStartedRunningNotificationChan: webhookStartedRunningNotificationChan,
returnResponse: emptyWebhookSuccessResponse(),
} }
storage := NewREST(&webhook) storage := NewREST(&webhook)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -261,6 +280,7 @@ func TestCreateAllowsTheWebhookInvocationToFinishWhenTheCallToCreateIsNotCancell
webhook := FakeToken{ webhook := FakeToken{
timeout: 0, timeout: 0,
webhookStartedRunningNotificationChan: webhookStartedRunningNotificationChan, webhookStartedRunningNotificationChan: webhookStartedRunningNotificationChan,
returnResponse: emptyWebhookSuccessResponse(),
} }
storage := NewREST(&webhook) storage := NewREST(&webhook)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())