0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-22 23:54:42 +02:00

refactor the parser

This commit is contained in:
Excellencedev 2026-01-07 12:10:53 +01:00
parent 28dff2a372
commit 43931dc5a1
2 changed files with 59 additions and 17 deletions

View File

@ -92,6 +92,8 @@ func parseRawPermissions(rawPerms *yaml.Node, defaultPerms repo_model.ActionsTok
if node.Kind == yaml.MappingNode { if node.Kind == yaml.MappingNode {
result := defaultPerms // Start with defaults result := defaultPerms // Start with defaults
// Collect all scopes into a map first to handle priority
scopes := make(map[string]perm.AccessMode)
for i := 0; i < len(node.Content); i += 2 { for i := 0; i < len(node.Content); i += 2 {
if i+1 >= len(node.Content) { if i+1 >= len(node.Content) {
break break
@ -103,34 +105,36 @@ func parseRawPermissions(rawPerms *yaml.Node, defaultPerms repo_model.ActionsTok
continue continue
} }
scope := keyNode.Value scopes[keyNode.Value] = parseAccessMode(valueNode.Value)
accessStr := valueNode.Value }
accessMode := parseAccessMode(accessStr)
// Map GitHub Actions scopes to Gitea units // 1. Apply 'contents' first (lower priority)
if mode, ok := scopes["contents"]; ok {
result.Code = mode
result.Releases = mode
}
// 2. Apply all other scopes (overwrites contents if specified)
for scope, mode := range scopes {
switch scope { switch scope {
case "contents": case "contents":
result.Code = accessMode // already handled
result.Releases = accessMode
case "code": case "code":
result.Code = accessMode result.Code = mode
case "issues": case "issues":
result.Issues = accessMode result.Issues = mode
case "pull-requests": case "pull-requests":
result.PullRequests = accessMode result.PullRequests = mode
case "packages": case "packages":
result.Packages = accessMode result.Packages = mode
case "actions": case "actions":
result.Actions = accessMode result.Actions = mode
case "wiki": case "wiki":
result.Wiki = accessMode result.Wiki = mode
case "releases": case "releases":
result.Releases = accessMode result.Releases = mode
case "projects": case "projects":
result.Projects = accessMode result.Projects = mode
// Additional GitHub scopes we don't explicitly handle yet:
// These fall through to defaults
// - deployments, environments, id-token, pages, repository-projects, security-events, statuses
} }
} }

View File

@ -99,6 +99,44 @@ issues: write
assert.Equal(t, perm.AccessModeWrite, result.Wiki) assert.Equal(t, perm.AccessModeWrite, result.Wiki)
} }
func TestParseRawPermissions_Priority(t *testing.T) {
t.Run("granular-wins-over-contents", func(t *testing.T) {
yamlContent := `
contents: read
code: write
releases: none
`
var rawPerms yaml.Node
err := yaml.Unmarshal([]byte(yamlContent), &rawPerms)
assert.NoError(t, err)
defaultPerms := repo_model.ActionsTokenPermissions{}
result := parseRawPermissions(&rawPerms, defaultPerms)
assert.Equal(t, perm.AccessModeWrite, result.Code)
assert.Equal(t, perm.AccessModeNone, result.Releases)
})
t.Run("contents-applied-first", func(t *testing.T) {
yamlContent := `
code: none
releases: write
contents: read
`
var rawPerms yaml.Node
err := yaml.Unmarshal([]byte(yamlContent), &rawPerms)
assert.NoError(t, err)
defaultPerms := repo_model.ActionsTokenPermissions{}
result := parseRawPermissions(&rawPerms, defaultPerms)
// code: none should win over contents: read
assert.Equal(t, perm.AccessModeNone, result.Code)
// releases: write should win over contents: read
assert.Equal(t, perm.AccessModeWrite, result.Releases)
})
}
func TestParseRawPermissions_EmptyNode(t *testing.T) { func TestParseRawPermissions_EmptyNode(t *testing.T) {
var rawPerms yaml.Node var rawPerms yaml.Node
// Empty node // Empty node