Bläddra i källkod

slight update to rbac/policies and case on dry run for api tokens

Alexander Belanger 4 år sedan
förälder
incheckning
af756a53bd

+ 6 - 39
api/server/authz/policy/loader.go

@@ -60,11 +60,11 @@ func (b *RepoPolicyDocumentLoader) LoadPolicyDocuments(
 		// load role based on role kind
 		switch role.Kind {
 		case types.RoleAdmin:
-			return AdminPolicy, nil
+			return types.AdminPolicy, nil
 		case types.RoleDeveloper:
-			return DeveloperPolicy, nil
+			return types.DeveloperPolicy, nil
 		case types.RoleViewer:
-			return ViewerPolicy, nil
+			return types.ViewerPolicy, nil
 		default:
 			return nil, apierrors.NewErrForbidden(
 				fmt.Errorf("%s role not supported for user %d, project %d", string(role.Kind), userID, projectID),
@@ -77,39 +77,6 @@ func (b *RepoPolicyDocumentLoader) LoadPolicyDocuments(
 	)
 }
 
-var AdminPolicy = []*types.PolicyDocument{
-	{
-		Scope: types.ProjectScope,
-		Verbs: types.ReadWriteVerbGroup(),
-	},
-}
-
-var DeveloperPolicy = []*types.PolicyDocument{
-	{
-		Scope: types.ProjectScope,
-		Verbs: types.ReadWriteVerbGroup(),
-		Children: map[types.PermissionScope]*types.PolicyDocument{
-			types.SettingsScope: {
-				Scope: types.SettingsScope,
-				Verbs: types.ReadVerbGroup(),
-			},
-		},
-	},
-}
-
-var ViewerPolicy = []*types.PolicyDocument{
-	{
-		Scope: types.ProjectScope,
-		Verbs: types.ReadVerbGroup(),
-		Children: map[types.PermissionScope]*types.PolicyDocument{
-			types.SettingsScope: {
-				Scope: types.SettingsScope,
-				Verbs: []types.APIVerb{},
-			},
-		},
-	},
-}
-
 func GetAPIPolicyFromUID(policyRepo repository.PolicyRepository, projectID uint, uid string) (*types.APIPolicy, apierrors.RequestError) {
 	switch uid {
 	case "admin":
@@ -118,7 +85,7 @@ func GetAPIPolicyFromUID(policyRepo repository.PolicyRepository, projectID uint,
 				Name: "admin",
 				UID:  "admin",
 			},
-			Policy: AdminPolicy,
+			Policy: types.AdminPolicy,
 		}, nil
 	case "developer":
 		return &types.APIPolicy{
@@ -126,7 +93,7 @@ func GetAPIPolicyFromUID(policyRepo repository.PolicyRepository, projectID uint,
 				Name: "developer",
 				UID:  "developer",
 			},
-			Policy: DeveloperPolicy,
+			Policy: types.DeveloperPolicy,
 		}, nil
 	case "viewer":
 		return &types.APIPolicy{
@@ -134,7 +101,7 @@ func GetAPIPolicyFromUID(policyRepo repository.PolicyRepository, projectID uint,
 				Name: "viewer",
 				UID:  "viewer",
 			},
-			Policy: ViewerPolicy,
+			Policy: types.ViewerPolicy,
 		}, nil
 	default:
 		// look up the policy and make sure it exists

+ 3 - 3
api/server/authz/policy/loader_test.go

@@ -26,17 +26,17 @@ var basicLoaderTests = []basicLoaderTest{
 	{
 		description: "should load admin policy",
 		roleKind:    types.RoleAdmin,
-		expPolicy:   policy.AdminPolicy,
+		expPolicy:   types.AdminPolicy,
 	},
 	{
 		description: "should load developer policy",
 		roleKind:    types.RoleDeveloper,
-		expPolicy:   policy.DeveloperPolicy,
+		expPolicy:   types.DeveloperPolicy,
 	},
 	{
 		description: "should load viewer policy",
 		roleKind:    types.RoleViewer,
-		expPolicy:   policy.ViewerPolicy,
+		expPolicy:   types.ViewerPolicy,
 	},
 	{
 		description:      "should not load custom policy for basic loader",

+ 11 - 1
api/server/authz/policy/policy.go

@@ -117,6 +117,16 @@ func populateAndVerifyPolicyDocument(
 
 	processedChildren := 0
 
+	// by default, we pass the parent's verbs to the child.
+	passedParentVerbs := currDoc.Verbs
+
+	// however, if the current scope is a project scope, we don't pass the parent's verbs to
+	// the child. This is to avoid additional verbs being added later as a child of the ProjectScope,
+	// which would unintentionally grant permission to future-added scopes.
+	if currScope == types.ProjectScope {
+		passedParentVerbs = []types.APIVerb{}
+	}
+
 	for currScope := range subTree {
 		if _, exists := currDoc.Children[currScope]; exists {
 			processedChildren++
@@ -126,7 +136,7 @@ func populateAndVerifyPolicyDocument(
 			currDoc.Children[currScope],
 			subTree,
 			currScope,
-			currDoc.Verbs,
+			passedParentVerbs,
 			reqScopes,
 			matchDocs,
 		)

+ 3 - 3
api/server/authz/policy/policy_test.go

@@ -18,7 +18,7 @@ type testHasScopeAccess struct {
 var hasScopeAccessTests = []testHasScopeAccess{
 	{
 		description: "admin access to project",
-		policy:      policy.AdminPolicy,
+		policy:      types.AdminPolicy,
 		reqScopes: map[types.PermissionScope]*types.RequestAction{
 			types.ProjectScope: {
 				Verb: types.APIVerbGet,
@@ -31,7 +31,7 @@ var hasScopeAccessTests = []testHasScopeAccess{
 	},
 	{
 		description: "viewer access cannot perform write operation",
-		policy:      policy.ViewerPolicy,
+		policy:      types.ViewerPolicy,
 		reqScopes: map[types.PermissionScope]*types.RequestAction{
 			types.ClusterScope: {
 				Verb: types.APIVerbCreate,
@@ -44,7 +44,7 @@ var hasScopeAccessTests = []testHasScopeAccess{
 	},
 	{
 		description: "developer access cannot write settings",
-		policy:      policy.DeveloperPolicy,
+		policy:      types.DeveloperPolicy,
 		reqScopes: map[types.PermissionScope]*types.RequestAction{
 			types.SettingsScope: {
 				Verb: types.APIVerbUpdate,

+ 1 - 1
api/server/authz/policy_test.go

@@ -267,7 +267,7 @@ func (f *failingDocLoader) LoadPolicyDocuments(opts *policy.PolicyLoaderOpts) ([
 type viewerDocLoader struct{}
 
 func (f *viewerDocLoader) LoadPolicyDocuments(opts *policy.PolicyLoaderOpts) ([]*types.PolicyDocument, apierrors.RequestError) {
-	return policy.ViewerPolicy, nil
+	return types.ViewerPolicy, nil
 }
 
 type testHandler struct {

+ 18 - 11
api/server/handlers/release/create.go

@@ -228,16 +228,24 @@ func createGitAction(
 		}
 	}
 
+	isDryRun := release == nil
+
 	repoSplit := strings.Split(request.GitRepo, "/")
 
 	if len(repoSplit) != 2 {
 		return nil, nil, fmt.Errorf("invalid formatting of repo name")
 	}
 
-	encoded, err := getToken(config, userID, projectID, clusterID, request)
+	encoded := ""
+	var err error
 
-	if err != nil {
-		return nil, nil, err
+	// if this isn't a dry run, generate the token
+	if !isDryRun {
+		encoded, err = getToken(config, userID, projectID, clusterID, request)
+
+		if err != nil {
+			return nil, nil, err
+		}
 	}
 
 	// create the commit in the git repo
@@ -262,7 +270,7 @@ func createGitAction(
 		PorterToken:            encoded,
 		Version:                "v0.1.0",
 		ShouldCreateWorkflow:   request.ShouldCreateWorkflow,
-		DryRun:                 release == nil,
+		DryRun:                 isDryRun,
 	}
 
 	// Save the github err for after creating the git action config. However, we
@@ -321,20 +329,19 @@ func getToken(
 	policy := []*types.PolicyDocument{
 		{
 			Scope: types.ProjectScope,
-			// This token allows no API verbs at the project level, meaning child resources need to explicitly
-			// declare granted verbs and scopes. Thus we do not allow repo-scoped tokens to access things like
-			// project settings or infra.
-			Verbs: []types.APIVerb{},
+			Verbs: types.ReadWriteVerbGroup(),
 			Children: map[types.PermissionScope]*types.PolicyDocument{
 				types.ClusterScope: {
 					Scope: types.ClusterScope,
 					Verbs: types.ReadWriteVerbGroup(),
 				},
+				types.RegistryScope: {
+					Scope: types.RegistryScope,
+					Verbs: types.ReadVerbGroup(),
+				},
 				types.HelmRepoScope: {
 					Scope: types.HelmRepoScope,
-					Verbs: []types.APIVerb{
-						types.APIVerbGet, types.APIVerbList,
-					},
+					Verbs: types.ReadVerbGroup(),
 				},
 			},
 		},

+ 66 - 0
api/types/policy.go

@@ -59,6 +59,32 @@ var AdminPolicy = []*PolicyDocument{
 	{
 		Scope: ProjectScope,
 		Verbs: ReadWriteVerbGroup(),
+		Children: map[PermissionScope]*PolicyDocument{
+			ClusterScope: {
+				Scope: ClusterScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			RegistryScope: {
+				Scope: RegistryScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			HelmRepoScope: {
+				Scope: HelmRepoScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			GitInstallationScope: {
+				Scope: GitInstallationScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			InfraScope: {
+				Scope: InfraScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			SettingsScope: {
+				Scope: SettingsScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+		},
 	},
 }
 
@@ -67,6 +93,26 @@ var DeveloperPolicy = []*PolicyDocument{
 		Scope: ProjectScope,
 		Verbs: ReadWriteVerbGroup(),
 		Children: map[PermissionScope]*PolicyDocument{
+			ClusterScope: {
+				Scope: ClusterScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			RegistryScope: {
+				Scope: RegistryScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			HelmRepoScope: {
+				Scope: HelmRepoScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			GitInstallationScope: {
+				Scope: GitInstallationScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
+			InfraScope: {
+				Scope: InfraScope,
+				Verbs: ReadWriteVerbGroup(),
+			},
 			SettingsScope: {
 				Scope: SettingsScope,
 				Verbs: ReadVerbGroup(),
@@ -80,6 +126,26 @@ var ViewerPolicy = []*PolicyDocument{
 		Scope: ProjectScope,
 		Verbs: ReadVerbGroup(),
 		Children: map[PermissionScope]*PolicyDocument{
+			ClusterScope: {
+				Scope: ClusterScope,
+				Verbs: ReadVerbGroup(),
+			},
+			RegistryScope: {
+				Scope: RegistryScope,
+				Verbs: ReadVerbGroup(),
+			},
+			HelmRepoScope: {
+				Scope: HelmRepoScope,
+				Verbs: ReadVerbGroup(),
+			},
+			GitInstallationScope: {
+				Scope: GitInstallationScope,
+				Verbs: ReadVerbGroup(),
+			},
+			InfraScope: {
+				Scope: InfraScope,
+				Verbs: ReadVerbGroup(),
+			},
 			SettingsScope: {
 				Scope: SettingsScope,
 				Verbs: []APIVerb{},

+ 1 - 1
internal/repository/test/api_token.go

@@ -21,7 +21,7 @@ func (repo *APITokenRepository) ListAPITokensByProjectID(projectID uint) ([]*mod
 	panic("unimplemented")
 }
 
-func (repo *APITokenRepository) ReadAPIToken(uid string) (*models.APIToken, error) {
+func (repo *APITokenRepository) ReadAPIToken(projectID uint, uid string) (*models.APIToken, error) {
 	panic("unimplemented")
 }
 

+ 1 - 1
internal/repository/test/policy.go

@@ -23,7 +23,7 @@ func (repo *PolicyRepository) ListPoliciesByProjectID(projectID uint) ([]*models
 	panic("unimplemented")
 }
 
-func (repo *PolicyRepository) ReadPolicy(uid string) (*models.Policy, error) {
+func (repo *PolicyRepository) ReadPolicy(projectID uint, uid string) (*models.Policy, error) {
 	panic("unimplemented")
 }