github.com/argoproj/argo-cd/v3@v3.2.1/util/rbac/rbac_norace_test.go (about) 1 //go:build !race 2 // +build !race 3 4 package rbac 5 6 import ( 7 "context" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 corev1 "k8s.io/api/core/v1" 14 "k8s.io/client-go/kubernetes/fake" 15 ) 16 17 // TestPolicyInformer verifies the informer will get updated with a new configmap 18 func TestPolicyInformer(t *testing.T) { 19 // !race: 20 // A BUNCH of data race warnings thrown by running this test and the next... it's tough to guess to what degree this 21 // is primarily a casbin issue or a Argo CD RBAC issue... A least one data race is an `rbac.go` with 22 // itself, a bunch are in casbin. You can see the full list by doing a `go test -race github.com/argoproj/argo-cd/util/rbac` 23 // 24 // It couldn't hurt to take a look at this code to decide if Argo CD is properly handling concurrent data 25 // access here, but in the mean time I have disabled data race testing of this test. 26 27 cm := fakeConfigMap() 28 cm.Data[ConfigMapPolicyCSVKey] = "p, admin, applications, delete, */*, allow" 29 kubeclientset := fake.NewClientset(cm) 30 enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) 31 32 ctx := t.Context() 33 ctx, cancel := context.WithCancel(ctx) 34 defer cancel() 35 go enf.runInformer(ctx, func(_ *corev1.ConfigMap) error { 36 return nil 37 }) 38 39 loaded := false 40 for i := 1; i <= 20; i++ { 41 if enf.Enforce("admin", "applications", "delete", "foo/bar") { 42 loaded = true 43 break 44 } 45 time.Sleep(50 * time.Millisecond) 46 } 47 assert.True(t, loaded, "Policy update failed to load") 48 49 // update the configmap and update policy 50 delete(cm.Data, ConfigMapPolicyCSVKey) 51 err := enf.syncUpdate(cm, noOpUpdate) 52 require.NoError(t, err) 53 assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar")) 54 } 55 56 // TestResourceActionWildcards verifies the ability to use wildcards in resources and actions 57 func TestResourceActionWildcards(t *testing.T) { 58 // !race: 59 // Same as TestPolicyInformer 60 61 kubeclientset := fake.NewClientset(fakeConfigMap()) 62 enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) 63 policy := ` 64 p, alice, *, get, foo/obj, allow 65 p, bob, repositories, *, foo/obj, allow 66 p, cathy, *, *, foo/obj, allow 67 p, dave, applications, get, foo/obj, allow 68 p, dave, applications/*, get, foo/obj, allow 69 p, eve, *, get, foo/obj, deny 70 p, mallory, repositories, *, foo/obj, deny 71 p, mallory, repositories, *, foo/obj, allow 72 p, mike, *, *, foo/obj, allow 73 p, mike, *, *, foo/obj, deny 74 p, trudy, applications, get, foo/obj, allow 75 p, trudy, applications/*, get, foo/obj, allow 76 p, trudy, applications/secrets, get, foo/obj, deny 77 p, danny, applications, get, */obj, allow 78 p, danny, applications, get, proj1/a*p1, allow 79 ` 80 _ = enf.SetUserPolicy(policy) 81 82 // Verify the resource wildcard 83 assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj")) 84 assert.True(t, enf.Enforce("alice", "applications/resources", "get", "foo/obj")) 85 assert.False(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj")) 86 87 // Verify action wildcards work 88 assert.True(t, enf.Enforce("bob", "repositories", "get", "foo/obj")) 89 assert.True(t, enf.Enforce("bob", "repositories", "delete", "foo/obj")) 90 assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj")) 91 92 // Verify resource and action wildcards work in conjunction 93 assert.True(t, enf.Enforce("cathy", "repositories", "get", "foo/obj")) 94 assert.True(t, enf.Enforce("cathy", "repositories", "delete", "foo/obj")) 95 assert.True(t, enf.Enforce("cathy", "applications", "get", "foo/obj")) 96 assert.True(t, enf.Enforce("cathy", "applications/resources", "delete", "foo/obj")) 97 98 // Verify wildcards with sub-resources 99 assert.True(t, enf.Enforce("dave", "applications", "get", "foo/obj")) 100 assert.True(t, enf.Enforce("dave", "applications/logs", "get", "foo/obj")) 101 102 // Verify the resource wildcard 103 assert.False(t, enf.Enforce("eve", "applications", "get", "foo/obj")) 104 assert.False(t, enf.Enforce("eve", "applications/resources", "get", "foo/obj")) 105 assert.False(t, enf.Enforce("eve", "applications/resources", "delete", "foo/obj")) 106 107 // Verify action wildcards work 108 assert.False(t, enf.Enforce("mallory", "repositories", "get", "foo/obj")) 109 assert.False(t, enf.Enforce("mallory", "repositories", "delete", "foo/obj")) 110 assert.False(t, enf.Enforce("mallory", "applications", "get", "foo/obj")) 111 112 // Verify resource and action wildcards work in conjunction 113 assert.False(t, enf.Enforce("mike", "repositories", "get", "foo/obj")) 114 assert.False(t, enf.Enforce("mike", "repositories", "delete", "foo/obj")) 115 assert.False(t, enf.Enforce("mike", "applications", "get", "foo/obj")) 116 assert.False(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj")) 117 118 // Verify wildcards with sub-resources 119 assert.True(t, enf.Enforce("trudy", "applications", "get", "foo/obj")) 120 assert.True(t, enf.Enforce("trudy", "applications/logs", "get", "foo/obj")) 121 assert.False(t, enf.Enforce("trudy", "applications/secrets", "get", "foo/obj")) 122 123 // Verify trailing wildcards don't grant full access 124 assert.True(t, enf.Enforce("danny", "applications", "get", "foo/obj")) 125 assert.True(t, enf.Enforce("danny", "applications", "get", "bar/obj")) 126 assert.False(t, enf.Enforce("danny", "applications", "get", "foo/bar")) 127 assert.True(t, enf.Enforce("danny", "applications", "get", "proj1/app1")) 128 assert.False(t, enf.Enforce("danny", "applications", "get", "proj1/app2")) 129 }