mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
129 lines
5.2 KiB
Go
129 lines
5.2 KiB
Go
//go:build !race
|
|
|
|
package rbac
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/client-go/kubernetes/fake"
|
|
)
|
|
|
|
// TestPolicyInformer verifies the informer will get updated with a new configmap
|
|
func TestPolicyInformer(t *testing.T) {
|
|
// !race:
|
|
// A BUNCH of data race warnings thrown by running this test and the next... it's tough to guess to what degree this
|
|
// is primarily a casbin issue or a Argo CD RBAC issue... A least one data race is an `rbac.go` with
|
|
// 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`
|
|
//
|
|
// It couldn't hurt to take a look at this code to decide if Argo CD is properly handling concurrent data
|
|
// access here, but in the mean time I have disabled data race testing of this test.
|
|
|
|
cm := fakeConfigMap()
|
|
cm.Data[ConfigMapPolicyCSVKey] = "p, admin, applications, delete, */*, allow"
|
|
kubeclientset := fake.NewClientset(cm)
|
|
enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil)
|
|
|
|
ctx := t.Context()
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
go enf.runInformer(ctx, func(_ *corev1.ConfigMap) error {
|
|
return nil
|
|
})
|
|
|
|
loaded := false
|
|
for i := 1; i <= 20; i++ {
|
|
if enf.Enforce("admin", "applications", "delete", "foo/bar") {
|
|
loaded = true
|
|
break
|
|
}
|
|
time.Sleep(50 * time.Millisecond)
|
|
}
|
|
assert.True(t, loaded, "Policy update failed to load")
|
|
|
|
// update the configmap and update policy
|
|
delete(cm.Data, ConfigMapPolicyCSVKey)
|
|
err := enf.syncUpdate(cm, noOpUpdate)
|
|
require.NoError(t, err)
|
|
assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar"))
|
|
}
|
|
|
|
// TestResourceActionWildcards verifies the ability to use wildcards in resources and actions
|
|
func TestResourceActionWildcards(t *testing.T) {
|
|
// !race:
|
|
// Same as TestPolicyInformer
|
|
|
|
kubeclientset := fake.NewClientset(fakeConfigMap())
|
|
enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil)
|
|
policy := `
|
|
p, alice, *, get, foo/obj, allow
|
|
p, bob, repositories, *, foo/obj, allow
|
|
p, cathy, *, *, foo/obj, allow
|
|
p, dave, applications, get, foo/obj, allow
|
|
p, dave, applications/*, get, foo/obj, allow
|
|
p, eve, *, get, foo/obj, deny
|
|
p, mallory, repositories, *, foo/obj, deny
|
|
p, mallory, repositories, *, foo/obj, allow
|
|
p, mike, *, *, foo/obj, allow
|
|
p, mike, *, *, foo/obj, deny
|
|
p, trudy, applications, get, foo/obj, allow
|
|
p, trudy, applications/*, get, foo/obj, allow
|
|
p, trudy, applications/secrets, get, foo/obj, deny
|
|
p, danny, applications, get, */obj, allow
|
|
p, danny, applications, get, proj1/a*p1, allow
|
|
`
|
|
_ = enf.SetUserPolicy(policy)
|
|
|
|
// Verify the resource wildcard
|
|
assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("alice", "applications/resources", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj"))
|
|
|
|
// Verify action wildcards work
|
|
assert.True(t, enf.Enforce("bob", "repositories", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("bob", "repositories", "delete", "foo/obj"))
|
|
assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj"))
|
|
|
|
// Verify resource and action wildcards work in conjunction
|
|
assert.True(t, enf.Enforce("cathy", "repositories", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("cathy", "repositories", "delete", "foo/obj"))
|
|
assert.True(t, enf.Enforce("cathy", "applications", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("cathy", "applications/resources", "delete", "foo/obj"))
|
|
|
|
// Verify wildcards with sub-resources
|
|
assert.True(t, enf.Enforce("dave", "applications", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("dave", "applications/logs", "get", "foo/obj"))
|
|
|
|
// Verify the resource wildcard
|
|
assert.False(t, enf.Enforce("eve", "applications", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("eve", "applications/resources", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("eve", "applications/resources", "delete", "foo/obj"))
|
|
|
|
// Verify action wildcards work
|
|
assert.False(t, enf.Enforce("mallory", "repositories", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("mallory", "repositories", "delete", "foo/obj"))
|
|
assert.False(t, enf.Enforce("mallory", "applications", "get", "foo/obj"))
|
|
|
|
// Verify resource and action wildcards work in conjunction
|
|
assert.False(t, enf.Enforce("mike", "repositories", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("mike", "repositories", "delete", "foo/obj"))
|
|
assert.False(t, enf.Enforce("mike", "applications", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj"))
|
|
|
|
// Verify wildcards with sub-resources
|
|
assert.True(t, enf.Enforce("trudy", "applications", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("trudy", "applications/logs", "get", "foo/obj"))
|
|
assert.False(t, enf.Enforce("trudy", "applications/secrets", "get", "foo/obj"))
|
|
|
|
// Verify trailing wildcards don't grant full access
|
|
assert.True(t, enf.Enforce("danny", "applications", "get", "foo/obj"))
|
|
assert.True(t, enf.Enforce("danny", "applications", "get", "bar/obj"))
|
|
assert.False(t, enf.Enforce("danny", "applications", "get", "foo/bar"))
|
|
assert.True(t, enf.Enforce("danny", "applications", "get", "proj1/app1"))
|
|
assert.False(t, enf.Enforce("danny", "applications", "get", "proj1/app2"))
|
|
}
|