// newServiceAccountAuthenticator returns an authenticator.Request or an error func newServiceAccountAuthenticator(keyfile string, lookup bool, serviceAccountGetter serviceaccount.ServiceAccountTokenGetter) (authenticator.Request, error) { publicKey, err := serviceaccount.ReadPublicKey(keyfile) if err != nil { return nil, err } tokenAuthenticator := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{publicKey}, lookup, serviceAccountGetter) return bearertoken.New(tokenAuthenticator), nil }
func TestTokenGenerateAndValidate(t *testing.T) { expectedUserName := "******" expectedUserUID := "12345" // Related API objects serviceAccount := &api.ServiceAccount{ ObjectMeta: api.ObjectMeta{ Name: "my-service-account", UID: "12345", Namespace: "test", }, } secret := &api.Secret{ ObjectMeta: api.ObjectMeta{ Name: "my-secret", Namespace: "test", }, } // Generate the token generator := serviceaccount.JWTTokenGenerator(getPrivateKey(privateKey)) token, err := generator.GenerateToken(*serviceAccount, *secret) if err != nil { t.Fatalf("error generating token: %v", err) } if len(token) == 0 { t.Fatalf("no token generated") } // "Save" the token secret.Data = map[string][]byte{ "token": []byte(token), } testCases := map[string]struct { Client clientset.Interface Keys []*rsa.PublicKey ExpectedErr bool ExpectedOK bool ExpectedUserName string ExpectedUserUID string ExpectedGroups []string }{ "no keys": { Client: nil, Keys: []*rsa.PublicKey{}, ExpectedErr: false, ExpectedOK: false, }, "invalid keys": { Client: nil, Keys: []*rsa.PublicKey{getPublicKey(otherPublicKey)}, ExpectedErr: true, ExpectedOK: false, }, "valid key": { Client: nil, Keys: []*rsa.PublicKey{getPublicKey(publicKey)}, ExpectedErr: false, ExpectedOK: true, ExpectedUserName: expectedUserName, ExpectedUserUID: expectedUserUID, ExpectedGroups: []string{"system:serviceaccounts", "system:serviceaccounts:test"}, }, "rotated keys": { Client: nil, Keys: []*rsa.PublicKey{getPublicKey(otherPublicKey), getPublicKey(publicKey)}, ExpectedErr: false, ExpectedOK: true, ExpectedUserName: expectedUserName, ExpectedUserUID: expectedUserUID, ExpectedGroups: []string{"system:serviceaccounts", "system:serviceaccounts:test"}, }, "valid lookup": { Client: fake.NewSimpleClientset(serviceAccount, secret), Keys: []*rsa.PublicKey{getPublicKey(publicKey)}, ExpectedErr: false, ExpectedOK: true, ExpectedUserName: expectedUserName, ExpectedUserUID: expectedUserUID, ExpectedGroups: []string{"system:serviceaccounts", "system:serviceaccounts:test"}, }, "invalid secret lookup": { Client: fake.NewSimpleClientset(serviceAccount), Keys: []*rsa.PublicKey{getPublicKey(publicKey)}, ExpectedErr: true, ExpectedOK: false, }, "invalid serviceaccount lookup": { Client: fake.NewSimpleClientset(secret), Keys: []*rsa.PublicKey{getPublicKey(publicKey)}, ExpectedErr: true, ExpectedOK: false, }, } for k, tc := range testCases { getter := serviceaccountcontroller.NewGetterFromClient(tc.Client) authenticator := serviceaccount.JWTTokenAuthenticator(tc.Keys, tc.Client != nil, getter) user, ok, err := authenticator.AuthenticateToken(token) if (err != nil) != tc.ExpectedErr { t.Errorf("%s: Expected error=%v, got %v", k, tc.ExpectedErr, err) continue } if ok != tc.ExpectedOK { t.Errorf("%s: Expected ok=%v, got %v", k, tc.ExpectedOK, ok) continue } if err != nil || !ok { continue } if user.GetName() != tc.ExpectedUserName { t.Errorf("%s: Expected username=%v, got %v", k, tc.ExpectedUserName, user.GetName()) continue } if user.GetUID() != tc.ExpectedUserUID { t.Errorf("%s: Expected userUID=%v, got %v", k, tc.ExpectedUserUID, user.GetUID()) continue } if !reflect.DeepEqual(user.GetGroups(), tc.ExpectedGroups) { t.Errorf("%s: Expected groups=%v, got %v", k, tc.ExpectedGroups, user.GetGroups()) continue } } }