github.com/argoproj/argo-cd/v2@v2.10.9/server/rbacpolicy/rbacpolicy_test.go (about) 1 package rbacpolicy 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/golang-jwt/jwt/v4" 8 "github.com/stretchr/testify/assert" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 "k8s.io/client-go/kubernetes/fake" 11 12 "github.com/argoproj/argo-cd/v2/common" 13 argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 14 "github.com/argoproj/argo-cd/v2/test" 15 "github.com/argoproj/argo-cd/v2/util/rbac" 16 ) 17 18 func newFakeProj() *argoappv1.AppProject { 19 jwtTokenByRole := make(map[string]argoappv1.JWTTokens) 20 jwtTokenByRole["my-role"] = argoappv1.JWTTokens{Items: []argoappv1.JWTToken{{IssuedAt: 1234}}} 21 22 return &argoappv1.AppProject{ 23 ObjectMeta: metav1.ObjectMeta{ 24 Name: "my-proj", 25 Namespace: test.FakeArgoCDNamespace, 26 }, 27 Spec: argoappv1.AppProjectSpec{ 28 Roles: []argoappv1.ProjectRole{ 29 { 30 Name: "my-role", 31 Policies: []string{ 32 "p, proj:my-proj:my-role, applications, create, my-proj/*, allow", 33 "p, proj:my-proj:my-role, logs, get, my-proj/*, allow", 34 "p, proj:my-proj:my-role, exec, create, my-proj/*, allow", 35 }, 36 Groups: []string{ 37 "my-org:my-team", 38 }, 39 JWTTokens: []argoappv1.JWTToken{ 40 { 41 IssuedAt: 1234, 42 }, 43 }, 44 }, 45 }, 46 }, 47 Status: argoappv1.AppProjectStatus{JWTTokensByRole: jwtTokenByRole}, 48 } 49 } 50 51 func TestEnforceAllPolicies(t *testing.T) { 52 kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) 53 projLister := test.NewFakeProjLister(newFakeProj()) 54 enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) 55 enf.EnableLog(true) 56 _ = enf.SetBuiltinPolicy(`p, alice, applications, create, my-proj/*, allow` + "\n" + `p, alice, logs, get, my-proj/*, allow` + "\n" + `p, alice, exec, create, my-proj/*, allow`) 57 _ = enf.SetUserPolicy(`p, bob, applications, create, my-proj/*, allow` + "\n" + `p, bob, logs, get, my-proj/*, allow` + "\n" + `p, bob, exec, create, my-proj/*, allow`) 58 rbacEnf := NewRBACPolicyEnforcer(enf, projLister) 59 enf.SetClaimsEnforcerFunc(rbacEnf.EnforceClaims) 60 61 claims := jwt.MapClaims{"sub": "alice"} 62 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 63 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 64 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 65 66 claims = jwt.MapClaims{"sub": "bob"} 67 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 68 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 69 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 70 71 claims = jwt.MapClaims{"sub": "proj:my-proj:my-role", "iat": 1234} 72 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 73 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 74 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 75 76 claims = jwt.MapClaims{"groups": []string{"my-org:my-team"}} 77 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 78 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 79 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 80 81 claims = jwt.MapClaims{"sub": "cathy"} 82 assert.False(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 83 assert.False(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 84 assert.False(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 85 86 // AWS cognito returns its groups in cognito:groups 87 rbacEnf.SetScopes([]string{"cognito:groups"}) 88 claims = jwt.MapClaims{"cognito:groups": []string{"my-org:my-team"}} 89 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 90 } 91 92 func TestEnforceActionActions(t *testing.T) { 93 kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) 94 projLister := test.NewFakeProjLister(newFakeProj()) 95 enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) 96 enf.EnableLog(true) 97 _ = enf.SetBuiltinPolicy(fmt.Sprintf(`p, alice, applications, %s/*, my-proj/*, allow 98 p, bob, applications, %s/argoproj.io/Rollout/*, my-proj/*, allow 99 p, cam, applications, %s/argoproj.io/Rollout/resume, my-proj/*, allow 100 `, ActionAction, ActionAction, ActionAction)) 101 rbacEnf := NewRBACPolicyEnforcer(enf, projLister) 102 enf.SetClaimsEnforcerFunc(rbacEnf.EnforceClaims) 103 104 // Alice has wild-card approval for all actions 105 claims := jwt.MapClaims{"sub": "alice"} 106 assert.True(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/Rollout/resume", "my-proj/my-app")) 107 claims = jwt.MapClaims{"sub": "alice"} 108 assert.True(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/NewCrd/abort", "my-proj/my-app")) 109 // Bob has wild-card approval for all actions under argoproj.io/Rollout 110 claims = jwt.MapClaims{"sub": "bob"} 111 assert.True(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/Rollout/resume", "my-proj/my-app")) 112 claims = jwt.MapClaims{"sub": "bob"} 113 assert.False(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/NewCrd/abort", "my-proj/my-app")) 114 // Cam only has approval for actions/argoproj.io/Rollout:resume 115 claims = jwt.MapClaims{"sub": "cam"} 116 assert.True(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/Rollout/resume", "my-proj/my-app")) 117 claims = jwt.MapClaims{"sub": "cam"} 118 assert.False(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/Rollout/abort", "my-proj/my-app")) 119 120 // Eve does not have approval for any actions 121 claims = jwt.MapClaims{"sub": "eve"} 122 assert.False(t, enf.Enforce(claims, "applications", ActionAction+"/argoproj.io/Rollout/resume", "my-proj/my-app")) 123 } 124 125 func TestInvalidatedCache(t *testing.T) { 126 kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) 127 projLister := test.NewFakeProjLister(newFakeProj()) 128 enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) 129 enf.EnableLog(true) 130 _ = enf.SetBuiltinPolicy(`p, alice, applications, create, my-proj/*, allow` + "\n" + `p, alice, logs, get, my-proj/*, allow` + "\n" + `p, alice, exec, create, my-proj/*, allow`) 131 _ = enf.SetUserPolicy(`p, bob, applications, create, my-proj/*, allow` + "\n" + `p, bob, logs, get, my-proj/*, allow` + "\n" + `p, bob, exec, create, my-proj/*, allow`) 132 rbacEnf := NewRBACPolicyEnforcer(enf, projLister) 133 enf.SetClaimsEnforcerFunc(rbacEnf.EnforceClaims) 134 135 claims := jwt.MapClaims{"sub": "alice"} 136 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 137 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 138 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 139 140 claims = jwt.MapClaims{"sub": "bob"} 141 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 142 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 143 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 144 145 _ = enf.SetBuiltinPolicy(`p, alice, applications, create, my-proj2/*, allow` + "\n" + `p, alice, logs, get, my-proj2/*, allow` + "\n" + `p, alice, exec, create, my-proj2/*, allow`) 146 _ = enf.SetUserPolicy(`p, bob, applications, create, my-proj2/*, allow` + "\n" + `p, bob, logs, get, my-proj2/*, allow` + "\n" + `p, bob, exec, create, my-proj2/*, allow`) 147 claims = jwt.MapClaims{"sub": "alice"} 148 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj2/my-app")) 149 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj2/my-app")) 150 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj2/my-app")) 151 152 claims = jwt.MapClaims{"sub": "bob"} 153 assert.True(t, enf.Enforce(claims, "applications", "create", "my-proj2/my-app")) 154 assert.True(t, enf.Enforce(claims, "logs", "get", "my-proj2/my-app")) 155 assert.True(t, enf.Enforce(claims, "exec", "create", "my-proj2/my-app")) 156 157 claims = jwt.MapClaims{"sub": "alice"} 158 assert.False(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 159 assert.False(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 160 assert.False(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 161 162 claims = jwt.MapClaims{"sub": "bob"} 163 assert.False(t, enf.Enforce(claims, "applications", "create", "my-proj/my-app")) 164 assert.False(t, enf.Enforce(claims, "logs", "get", "my-proj/my-app")) 165 assert.False(t, enf.Enforce(claims, "exec", "create", "my-proj/my-app")) 166 } 167 168 func TestGetScopes_DefaultScopes(t *testing.T) { 169 rbacEnforcer := NewRBACPolicyEnforcer(nil, nil) 170 171 scopes := rbacEnforcer.GetScopes() 172 assert.Equal(t, scopes, defaultScopes) 173 } 174 175 func TestGetScopes_CustomScopes(t *testing.T) { 176 rbacEnforcer := NewRBACPolicyEnforcer(nil, nil) 177 customScopes := []string{"custom"} 178 rbacEnforcer.SetScopes(customScopes) 179 180 scopes := rbacEnforcer.GetScopes() 181 assert.Equal(t, scopes, customScopes) 182 } 183 184 func Test_getProjectFromRequest(t *testing.T) { 185 fp := newFakeProj() 186 projLister := test.NewFakeProjLister(fp) 187 188 rbacEnforcer := NewRBACPolicyEnforcer(nil, projLister) 189 project := rbacEnforcer.getProjectFromRequest("", "repositories", "create", fp.Name+"/https://github.com/argoproj/argocd-example-apps") 190 191 assert.Equal(t, project.Name, fp.Name) 192 }