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  }