1// Copyright 2019 Istio Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package trustdomain 16 17import ( 18 "reflect" 19 "testing" 20) 21 22func TestReplaceTrustDomainAliases(t *testing.T) { 23 testCases := []struct { 24 name string 25 trustDomainBundle Bundle 26 principals []string 27 expect []string 28 }{ 29 { 30 name: "No trust domain aliases (no change in trust domain)", 31 trustDomainBundle: NewBundle("cluster.local", nil), 32 principals: []string{"cluster.local/ns/foo/sa/bar"}, 33 expect: []string{"cluster.local/ns/foo/sa/bar"}, 34 }, 35 { 36 name: "Principal with *", 37 trustDomainBundle: NewBundle("cluster.local", nil), 38 principals: []string{"*"}, 39 expect: []string{"*"}, 40 }, 41 { 42 name: "Principal with * prefix", 43 trustDomainBundle: NewBundle("cluster.local", nil), 44 principals: []string{"*/ns/foo/sa/bar"}, 45 expect: []string{"*/ns/foo/sa/bar"}, 46 }, 47 { 48 name: "One trust domain alias, one principal", 49 trustDomainBundle: NewBundle("td2", []string{"td1"}), 50 principals: []string{"td1/ns/foo/sa/bar"}, 51 expect: []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar"}, 52 }, 53 { 54 name: "One trust domain alias, two principals", 55 trustDomainBundle: NewBundle("td1", []string{"cluster.local"}), 56 principals: []string{"cluster.local/ns/foo/sa/bar", "cluster.local/ns/yyy/sa/zzz"}, 57 expect: []string{"td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"}, 58 }, 59 { 60 name: "One trust domain alias, principals with * as-is", 61 trustDomainBundle: NewBundle("td1", []string{"cluster.local"}), 62 principals: []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"}, 63 expect: []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"}, 64 }, 65 { 66 name: "Two trust domain aliases, two principals", 67 trustDomainBundle: NewBundle("td2", []string{"td1", "cluster.local"}), 68 principals: []string{"cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz"}, 69 expect: []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", 70 "td2/ns/yyy/sa/zzz", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"}, 71 }, 72 { 73 name: "Two trust domain aliases with * prefix in trust domain", 74 trustDomainBundle: NewBundle("td2", []string{"foo-td1", "cluster.local"}), 75 principals: []string{"*-td1/ns/foo/sa/bar"}, 76 expect: []string{"td2/ns/foo/sa/bar", "*-td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar"}, 77 }, 78 { 79 name: "Principals not match any trust domains", 80 trustDomainBundle: NewBundle("td1", []string{"td2"}), 81 principals: []string{"some-td/ns/foo/sa/bar"}, 82 expect: []string{"some-td/ns/foo/sa/bar"}, 83 }, 84 { 85 name: "Principals match one alias", 86 trustDomainBundle: NewBundle("td1", []string{"td2", "some-td"}), 87 principals: []string{"some-td/ns/foo/sa/bar"}, 88 expect: []string{"td1/ns/foo/sa/bar", "td2/ns/foo/sa/bar", "some-td/ns/foo/sa/bar"}, 89 }, 90 { 91 name: "One principal match one alias", 92 trustDomainBundle: NewBundle("new-td", []string{"td2", "td3"}), 93 principals: []string{"td1/ns/some-ns/sa/some-sa", "td2/ns/foo/sa/bar"}, 94 expect: []string{"td1/ns/some-ns/sa/some-sa", "new-td/ns/foo/sa/bar", 95 "td2/ns/foo/sa/bar", "td3/ns/foo/sa/bar"}, 96 }, 97 { 98 name: "Trust domain is empty string", 99 trustDomainBundle: NewBundle("new-td", []string{"td2", "td3"}), 100 principals: []string{"/ns/some-ns/sa/some-sa"}, 101 expect: []string{"/ns/some-ns/sa/some-sa"}, 102 }, 103 { 104 name: "No duplicated principals for prefix", 105 trustDomainBundle: NewBundle("new-td", []string{"old-td"}), 106 principals: []string{"*-td/ns/some-ns/sa/some-sa"}, 107 // Rather than output *-td/ns/some-ns/sa/some-sa once for each trust domain. 108 expect: []string{"*-td/ns/some-ns/sa/some-sa"}, 109 }, 110 } 111 112 for _, tc := range testCases { 113 got := tc.trustDomainBundle.ReplaceTrustDomainAliases(tc.principals) 114 if !reflect.DeepEqual(got, tc.expect) { 115 t.Errorf("%s failed. Expect: %s. Got: %s", tc.name, tc.expect, got) 116 } 117 } 118} 119 120func TestReplaceTrustDomainInPrincipal(t *testing.T) { 121 cases := []struct { 122 trustDomainIn string 123 principal string 124 out string 125 }{ 126 {principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""}, 127 {principal: "sa/test-sa/ns/default", out: ""}, 128 {trustDomainIn: "td", principal: "cluster.local/ns/foo/sa/bar", out: "td/ns/foo/sa/bar"}, 129 {trustDomainIn: "abc", principal: "xyz/ns/foo/sa/bar", out: "abc/ns/foo/sa/bar"}, 130 } 131 132 for _, c := range cases { 133 got := replaceTrustDomainInPrincipal(c.trustDomainIn, c.principal) 134 if got != c.out { 135 t.Errorf("expect %s, but got %s", c.out, got) 136 } 137 } 138} 139 140func TestGetTrustDomainFromSpiffeIdentity(t *testing.T) { 141 cases := []struct { 142 principal string 143 out string 144 }{ 145 {principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""}, 146 {principal: "sa/test-sa/ns/default", out: ""}, 147 {principal: "cluster.local/ns/foo/sa/bar", out: "cluster.local"}, 148 {principal: "xyz/ns/foo/sa/bar", out: "xyz"}, 149 } 150 151 for _, c := range cases { 152 got, _ := getTrustDomainFromSpiffeIdentity(c.principal) 153 if got != c.out { 154 t.Errorf("expect %s, but got %s", c.out, got) 155 } 156 } 157} 158 159func TestIsTrustDomainBeingEnforced(t *testing.T) { 160 cases := []struct { 161 principal string 162 want bool 163 }{ 164 {principal: "cluster.local/ns/foo/sa/bar", want: true}, 165 {principal: "*/ns/foo/sa/bar", want: false}, 166 {principal: "*-td/ns/foo/sa/bar", want: true}, 167 {principal: "*/sa/bar", want: false}, 168 {principal: "*", want: false}, 169 {principal: "/ns/foo/sa/bar", want: true}, 170 } 171 172 for _, c := range cases { 173 got := isTrustDomainBeingEnforced(c.principal) 174 if got != c.want { 175 t.Errorf("expect %v, but got %v", c.want, got) 176 } 177 } 178} 179