Skip to content

Commit

Permalink
Allow SA names and namespaces to contain wildcards (#58)
Browse files Browse the repository at this point in the history
Two main changes:
1) Use `StrListContainsGlob` instead of `StrListContains` to allow for
   globbed names/namespaces - seemed like the path of least resistance
2) Update the `setupBackend` to accept the test role's allowed SA
   name/namespace as parameters, allowing to test globbed namespaces
  • Loading branch information
nathkn authored and jefferai committed Jun 21, 2019
1 parent 877fa44 commit e469573
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
4 changes: 2 additions & 2 deletions path_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,14 @@ func (b *kubeAuthBackend) parseAndValidateJWT(jwtStr string, role *roleStorageEn

// verify the namespace is allowed
if len(role.ServiceAccountNamespaces) > 1 || role.ServiceAccountNamespaces[0] != "*" {
if !strutil.StrListContains(role.ServiceAccountNamespaces, sa.namespace()) {
if !strutil.StrListContainsGlob(role.ServiceAccountNamespaces, sa.namespace()) {
return errors.New("namespace not authorized")
}
}

// verify the service account name is allowed
if len(role.ServiceAccountNames) > 1 || role.ServiceAccountNames[0] != "*" {
if !strutil.StrListContains(role.ServiceAccountNames, sa.name()) {
if !strutil.StrListContainsGlob(role.ServiceAccountNames, sa.name()) {
return errors.New("service account name not authorized")
}
}
Expand Down
59 changes: 51 additions & 8 deletions path_login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ var (
testUID = "d77f89bc-9055-11e7-a068-0800276d99bf"
testMockFactory = mockTokenReviewFactory(testName, testNamespace, testUID)

testGlobbedNamespace = "def*"
testGlobbedName = "vault-*"

// Projected ServiceAccount tokens have name "default", and require a
// different mock token reviewer
testProjectedName = "default"
Expand All @@ -28,7 +31,7 @@ var (
testNoPEMs = []string{testECCert, testRSACert}
)

func setupBackend(t *testing.T, pems []string) (logical.Backend, logical.Storage) {
func setupBackend(t *testing.T, pems []string, saName string, saNamespace string) (logical.Backend, logical.Storage) {
b, storage := getBackend(t)

// pems := []string{testECCert, testRSACert, testMinikubePubKey}
Expand Down Expand Up @@ -57,8 +60,8 @@ func setupBackend(t *testing.T, pems []string) (logical.Backend, logical.Storage
}

data = map[string]interface{}{
"bound_service_account_names": testName,
"bound_service_account_namespaces": testNamespace,
"bound_service_account_names": saName,
"bound_service_account_namespaces": saNamespace,
"policies": "test",
"period": "3s",
"ttl": "1s",
Expand All @@ -83,7 +86,7 @@ func setupBackend(t *testing.T, pems []string) (logical.Backend, logical.Storage
}

func TestLogin(t *testing.T) {
b, storage := setupBackend(t, testDefaultPEMs)
b, storage := setupBackend(t, testDefaultPEMs, testName, testNamespace)

// Test bad inputs
data := map[string]interface{}{
Expand Down Expand Up @@ -203,10 +206,50 @@ func TestLogin(t *testing.T) {
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}

// test successful login for globbed name
b, storage = setupBackend(t, testDefaultPEMs, testGlobbedName, testNamespace)

data = map[string]interface{}{
"role": "plugin-test",
"jwt": jwtData,
}

req = &logical.Request{
Operation: logical.UpdateOperation,
Path: "login",
Storage: storage,
Data: data,
}

resp, err = b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}

// test successful login for globbed namespace
b, storage = setupBackend(t, testDefaultPEMs, testName, testGlobbedNamespace)

data = map[string]interface{}{
"role": "plugin-test",
"jwt": jwtData,
}

req = &logical.Request{
Operation: logical.UpdateOperation,
Path: "login",
Storage: storage,
Data: data,
}

resp, err = b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}
}

func TestLogin_ECDSA_PEM(t *testing.T) {
b, storage := setupBackend(t, testNoPEMs)
b, storage := setupBackend(t, testNoPEMs, testName, testNamespace)

// test no certificate
data := map[string]interface{}{
Expand Down Expand Up @@ -247,7 +290,7 @@ func TestLogin_ECDSA_PEM(t *testing.T) {
}

func TestLogin_NoPEMs(t *testing.T) {
b, storage := setupBackend(t, testNoPEMs)
b, storage := setupBackend(t, testNoPEMs, testName, testNamespace)

// test bad jwt service account
data := map[string]interface{}{
Expand Down Expand Up @@ -289,7 +332,7 @@ func TestLogin_NoPEMs(t *testing.T) {
}

func TestAliasLookAhead(t *testing.T) {
b, storage := setupBackend(t, testDefaultPEMs)
b, storage := setupBackend(t, testDefaultPEMs, testName, testNamespace)

// Test bad inputs
data := map[string]interface{}{
Expand Down Expand Up @@ -328,7 +371,7 @@ Pk9Yf9rIf374m5XP1U8q79dBhLSIuaojsvOT39UUcPJROSD1FqYLued0rXiooIii
-----END PUBLIC KEY-----`

func TestLoginProjectedToken(t *testing.T) {
b, storage := setupBackend(t, append(testDefaultPEMs, testMinikubePubKey))
b, storage := setupBackend(t, append(testDefaultPEMs, testMinikubePubKey), testName, testNamespace)

// update backend to accept "default" bound account name
data := map[string]interface{}{
Expand Down

0 comments on commit e469573

Please sign in to comment.