123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /*
- Copyright 2017 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package bootstrap
- import (
- "context"
- "reflect"
- "testing"
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/errors"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apiserver/pkg/authentication/user"
- bootstrapapi "k8s.io/cluster-bootstrap/token/api"
- )
- type lister struct {
- secrets []*corev1.Secret
- }
- func (l *lister) List(selector labels.Selector) (ret []*corev1.Secret, err error) {
- return l.secrets, nil
- }
- func (l *lister) Get(name string) (*corev1.Secret, error) {
- for _, s := range l.secrets {
- if s.Name == name {
- return s, nil
- }
- }
- return nil, errors.NewNotFound(schema.GroupResource{}, name)
- }
- const (
- // Fake values for testing.
- tokenID = "foobar" // 6 letters
- tokenSecret = "circumnavigation" // 16 letters
- )
- func TestTokenAuthenticator(t *testing.T) {
- now := metav1.Now()
- tests := []struct {
- name string
- secrets []*corev1.Secret
- token string
- wantNotFound bool
- wantUser *user.DefaultInfo
- }{
- {
- name: "valid token",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantUser: &user.DefaultInfo{
- Name: "system:bootstrap:" + tokenID,
- Groups: []string{"system:bootstrappers"},
- },
- },
- {
- name: "valid token with extra group",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- bootstrapapi.BootstrapTokenExtraGroupsKey: []byte("system:bootstrappers:foo"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantUser: &user.DefaultInfo{
- Name: "system:bootstrap:" + tokenID,
- Groups: []string{"system:bootstrappers", "system:bootstrappers:foo"},
- },
- },
- {
- name: "invalid group",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- bootstrapapi.BootstrapTokenExtraGroupsKey: []byte("foo"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantNotFound: true,
- },
- {
- name: "invalid secret name",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "bad-name",
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantNotFound: true,
- },
- {
- name: "no usage",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantNotFound: true,
- },
- {
- name: "wrong token",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: "barfoo" + "." + tokenSecret,
- wantNotFound: true,
- },
- {
- name: "deleted token",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- DeletionTimestamp: &now,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantNotFound: true,
- },
- {
- name: "expired token",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- bootstrapapi.BootstrapTokenExpirationKey: []byte("2009-11-10T23:00:00Z"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantNotFound: true,
- },
- {
- name: "not expired token",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte(tokenID),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- bootstrapapi.BootstrapTokenExpirationKey: []byte("2109-11-10T23:00:00Z"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- token: tokenID + "." + tokenSecret,
- wantUser: &user.DefaultInfo{
- Name: "system:bootstrap:" + tokenID,
- Groups: []string{"system:bootstrappers"},
- },
- },
- {
- name: "token id wrong length",
- secrets: []*corev1.Secret{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: bootstrapapi.BootstrapTokenSecretPrefix + "foo",
- },
- Data: map[string][]byte{
- bootstrapapi.BootstrapTokenIDKey: []byte("foo"),
- bootstrapapi.BootstrapTokenSecretKey: []byte(tokenSecret),
- bootstrapapi.BootstrapTokenUsageAuthentication: []byte("true"),
- },
- Type: "bootstrap.kubernetes.io/token",
- },
- },
- // Token ID must be 6 characters.
- token: "foo" + "." + tokenSecret,
- wantNotFound: true,
- },
- }
- for _, test := range tests {
- func() {
- a := NewTokenAuthenticator(&lister{test.secrets})
- resp, found, err := a.AuthenticateToken(context.Background(), test.token)
- if err != nil {
- t.Errorf("test %q returned an error: %v", test.name, err)
- return
- }
- if !found {
- if !test.wantNotFound {
- t.Errorf("test %q expected to get user", test.name)
- }
- return
- }
- if test.wantNotFound {
- t.Errorf("test %q expected to not get a user", test.name)
- return
- }
- gotUser := resp.User.(*user.DefaultInfo)
- if !reflect.DeepEqual(gotUser, test.wantUser) {
- t.Errorf("test %q want user=%#v, got=%#v", test.name, test.wantUser, gotUser)
- }
- }()
- }
- }
|