0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-01-23 21:49:21 +01:00

Final core implementation changes

This commit is contained in:
Excellencedev 2025-12-18 13:37:15 +01:00
parent 2a204e36a7
commit 297ecef8da
7 changed files with 241 additions and 16 deletions

View File

@ -313,6 +313,7 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito
// Get effective token permissions from repository settings
effectivePerms := actionsCfg.GetEffectiveTokenPermissions(task.IsForkPullRequest)
effectivePerms = actionsCfg.ClampPermissions(effectivePerms)
// Set up per-unit access modes based on configured permissions
perm.units = repo.Units

View File

@ -3960,6 +3960,8 @@ general.token_permissions.cross_repo_desc = Allow workflows in this organization
general.token_permissions.custom = Custom permissions
general.token_permissions.custom.description = Configure permissions for each scope individually.
general.token_permissions.individual = Individual Permissions
general.token_permissions.maximum = Maximum Permissions
general.token_permissions.maximum.description = Configure the maximum permissions that can be requested by a workflow.
[projects]
deleted.display_name = Deleted Project

View File

@ -103,8 +103,13 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
}
if task.RepoID != packageRepoID {
// Not linked to the running repo.
// Check Org Policy
// 1. Private packages MUST be linked to a repository
if packageRepoID == 0 {
ctx.HTTPError(http.StatusForbidden, "reqPackageAccess", "private package must be linked to a repository to be accessed by Actions")
return
}
// 2. Check Org Cross-Repo Access Policy
if ctx.Package.Owner.IsOrganization() {
cfg, err := actions_model.GetOrgActionsConfig(ctx, ctx.Package.Owner.ID)
if err != nil {
@ -116,16 +121,11 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
ctx.HTTPError(http.StatusForbidden, "reqPackageAccess", "cross-repository package access is disabled")
return
}
} else {
// For user-owned packages, maybe stricter? Or same?
// Issue says "only when they have been linked".
// If Owner is User, Cross-Repo setting is not available (it's Org setting).
// Default to Strict for Users?
if task.RepoID != ctx.Package.RepoID {
ctx.HTTPError(http.StatusForbidden, "reqPackageAccess", "package must be linked to the repository")
return
}
}
// 3. Fallthrough to GetActionsUserRepoPermission
// We rely on the backend permission check below to handle other Cross-Repository restrictions
// (e.g., User collaborative owners, token scopes).
}
}
}

View File

@ -9,12 +9,12 @@ import (
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/services/context"
)
const (
tplSettingsActionsGeneral base.TplName = "org/settings/actions_general"
tplSettingsActionsGeneral templates.TplName = "org/settings/actions_general"
)
// ActionsGeneral renders the actions general settings page
@ -24,7 +24,7 @@ func ActionsGeneral(ctx *context.Context) {
ctx.Data["PageIsOrgSettingsActions"] = true
// Load Org Actions Config
actionsCfg, err := actions_model.GetOrgActionsConfig(ctx, ctx.Org.Organization.ID)
actionsCfg, err := actions_model.GetOrgActionsConfig(ctx, ctx.Org.Organization.AsUser().ID)
if err != nil {
ctx.ServerError("GetOrgActionsConfig", err)
return
@ -35,6 +35,7 @@ func ActionsGeneral(ctx *context.Context) {
ctx.Data["TokenPermissionModeRestricted"] = repo_model.ActionsTokenPermissionModeRestricted
ctx.Data["TokenPermissionModeCustom"] = repo_model.ActionsTokenPermissionModeCustom
ctx.Data["DefaultTokenPermissions"] = actionsCfg.GetEffectiveTokenPermissions(false)
ctx.Data["MaxTokenPermissions"] = actionsCfg.GetMaxTokenPermissions()
ctx.Data["AllowCrossRepoAccess"] = actionsCfg.AllowCrossRepoAccess
@ -47,7 +48,7 @@ func ActionsGeneralPost(ctx *context.Context) {
ctx.Data["PageIsOrgSettings"] = true
ctx.Data["PageIsOrgSettingsActions"] = true
actionsCfg, err := actions_model.GetOrgActionsConfig(ctx, ctx.Org.Organization.ID)
actionsCfg, err := actions_model.GetOrgActionsConfig(ctx, ctx.Org.Organization.AsUser().ID)
if err != nil {
ctx.ServerError("GetOrgActionsConfig", err)
return
@ -84,10 +85,30 @@ func ActionsGeneralPost(ctx *context.Context) {
actionsCfg.DefaultTokenPermissions = nil
}
// Update Maximum Permissions
parseMaxPerm := func(name string) perm.AccessMode {
if ctx.FormBool("max_" + name + "_write") {
return perm.AccessModeWrite
}
if ctx.FormBool("max_" + name + "_read") {
return perm.AccessModeRead
}
return perm.AccessModeNone
}
actionsCfg.MaxTokenPermissions = &repo_model.ActionsTokenPermissions{
Actions: parseMaxPerm("actions"),
Contents: parseMaxPerm("contents"),
Issues: parseMaxPerm("issues"),
Packages: parseMaxPerm("packages"),
PullRequests: parseMaxPerm("pull_requests"),
Wiki: parseMaxPerm("wiki"),
}
// Update Cross-Repo Access
actionsCfg.AllowCrossRepoAccess = ctx.FormBool("allow_cross_repo_access")
if err := actions_model.SetOrgActionsConfig(ctx, ctx.Org.Organization.ID, actionsCfg); err != nil {
if err := actions_model.SetOrgActionsConfig(ctx, ctx.Org.Organization.AsUser().ID, actionsCfg); err != nil {
ctx.ServerError("SetOrgActionsConfig", err)
return
}

View File

@ -43,6 +43,7 @@ func ActionsGeneralSettings(ctx *context.Context) {
ctx.Data["TokenPermissionModeRestricted"] = repo_model.ActionsTokenPermissionModeRestricted
ctx.Data["TokenPermissionModeCustom"] = repo_model.ActionsTokenPermissionModeCustom
ctx.Data["DefaultTokenPermissions"] = actionsCfg.GetEffectiveTokenPermissions(false)
ctx.Data["MaxTokenPermissions"] = actionsCfg.GetMaxTokenPermissions()
if ctx.Repo.Repository.IsPrivate {
collaborativeOwnerIDs := actionsCfg.CollaborativeOwnerIDs
@ -177,6 +178,26 @@ func UpdateTokenPermissions(ctx *context.Context) {
actionsCfg.DefaultTokenPermissions = nil
}
// Update Maximum Permissions
parseMaxPerm := func(name string) perm.AccessMode {
if ctx.FormBool("max_" + name + "_write") {
return perm.AccessModeWrite
}
if ctx.FormBool("max_" + name + "_read") {
return perm.AccessModeRead
}
return perm.AccessModeNone
}
actionsCfg.MaxTokenPermissions = &repo_model.ActionsTokenPermissions{
Actions: parseMaxPerm("actions"),
Contents: parseMaxPerm("contents"),
Issues: parseMaxPerm("issues"),
Packages: parseMaxPerm("packages"),
PullRequests: parseMaxPerm("pull_requests"),
Wiki: parseMaxPerm("wiki"),
}
if err := repo_model.UpdateRepoUnit(ctx, actionsUnit); err != nil {
ctx.ServerError("UpdateRepoUnit", err)
return

View File

@ -139,6 +139,96 @@
</form>
</div>
</div>
<div class="divider"></div>
<h5 class="ui header">{{ctx.Locale.Tr "general.token_permissions.maximum"}}</h5>
<p class="tw-text-secondary">{{ctx.Locale.Tr "general.token_permissions.maximum.description"}}</p>
<div class="ui grid">
<!-- Actions -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "actions.actions"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_actions_read" {{if call $.MaxTokenPermissions.HasRead "actions"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_actions_write" {{if call $.MaxTokenPermissions.HasWrite "actions"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Contents -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.contents"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_contents_read" {{if call $.MaxTokenPermissions.HasRead "contents"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_contents_write" {{if call $.MaxTokenPermissions.HasWrite "contents"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Issues -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.issues"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_issues_read" {{if call $.MaxTokenPermissions.HasRead "issues"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_issues_write" {{if call $.MaxTokenPermissions.HasWrite "issues"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Packages -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.packages"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_packages_read" {{if call $.MaxTokenPermissions.HasRead "packages"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_packages_write" {{if call $.MaxTokenPermissions.HasWrite "packages"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Pull Requests -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.pull_requests"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_pull_requests_read" {{if call $.MaxTokenPermissions.HasRead "pull_requests"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_pull_requests_write" {{if call $.MaxTokenPermissions.HasWrite "pull_requests"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Wiki -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.wiki"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_wiki_read" {{if call $.MaxTokenPermissions.HasRead "wiki"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_wiki_write" {{if call $.MaxTokenPermissions.HasWrite "wiki"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
</div>
</div>
</div>
{{template "org/settings/layout_footer" .}}

View File

@ -195,6 +195,96 @@
</div>
</div>
<div class="divider"></div>
<h5 class="ui header">{{ctx.Locale.Tr "general.token_permissions.maximum"}}</h5>
<p class="tw-text-secondary">{{ctx.Locale.Tr "general.token_permissions.maximum.description"}}</p>
<div class="ui grid">
<!-- Actions -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "actions.actions"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_actions_read" {{if call $.MaxTokenPermissions.HasRead "actions"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_actions_write" {{if call $.MaxTokenPermissions.HasWrite "actions"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Contents -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.contents"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_contents_read" {{if call $.MaxTokenPermissions.HasRead "contents"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_contents_write" {{if call $.MaxTokenPermissions.HasWrite "contents"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Issues -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.issues"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_issues_read" {{if call $.MaxTokenPermissions.HasRead "issues"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_issues_write" {{if call $.MaxTokenPermissions.HasWrite "issues"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Packages -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.packages"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_packages_read" {{if call $.MaxTokenPermissions.HasRead "packages"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_packages_write" {{if call $.MaxTokenPermissions.HasWrite "packages"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Pull Requests -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.pull_requests"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_pull_requests_read" {{if call $.MaxTokenPermissions.HasRead "pull_requests"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_pull_requests_write" {{if call $.MaxTokenPermissions.HasWrite "pull_requests"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
<!-- Wiki -->
<div class="eight wide column">
<div class="field">
<label>{{ctx.Locale.Tr "general.token_permissions.wiki"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="max_wiki_read" {{if call $.MaxTokenPermissions.HasRead "wiki"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_read"}}</label>
</div>
<div class="ui checkbox">
<input type="checkbox" name="max_wiki_write" {{if call $.MaxTokenPermissions.HasWrite "wiki"}}checked{{end}}>
<label>{{ctx.Locale.Tr "general.token_permissions.access_write"}}</label>
</div>
</div>
</div>
</div>
<div class="ui info message">
<p>{{ctx.Locale.Tr "actions.general.token_permissions.fork_pr_note"}}</p>
</div>