初始提交: Gitea 项目代码
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"gitea.dev/models/perm"
|
||||
"gitea.dev/models/unit"
|
||||
"gitea.dev/modules/json"
|
||||
"gitea.dev/modules/util"
|
||||
)
|
||||
|
||||
// ActionsTokenPermissionMode defines the default permission mode for Actions tokens
|
||||
type ActionsTokenPermissionMode string
|
||||
|
||||
const (
|
||||
// ActionsTokenPermissionModePermissive - write access by default (current behavior, backwards compatible)
|
||||
ActionsTokenPermissionModePermissive ActionsTokenPermissionMode = "permissive"
|
||||
// ActionsTokenPermissionModeRestricted - read access by default
|
||||
ActionsTokenPermissionModeRestricted ActionsTokenPermissionMode = "restricted"
|
||||
)
|
||||
|
||||
func (ActionsTokenPermissionMode) EnumValues() []ActionsTokenPermissionMode {
|
||||
return []ActionsTokenPermissionMode{ActionsTokenPermissionModePermissive /* default */, ActionsTokenPermissionModeRestricted}
|
||||
}
|
||||
|
||||
// ActionsTokenPermissions defines the permissions for different repository units
|
||||
type ActionsTokenPermissions struct {
|
||||
UnitAccessModes map[unit.Type]perm.AccessMode `json:"unit_access_modes,omitempty"`
|
||||
}
|
||||
|
||||
var ActionsTokenUnitTypes = []unit.Type{
|
||||
unit.TypeCode,
|
||||
unit.TypeIssues,
|
||||
unit.TypePullRequests,
|
||||
unit.TypePackages,
|
||||
unit.TypeActions,
|
||||
unit.TypeWiki,
|
||||
unit.TypeReleases,
|
||||
unit.TypeProjects,
|
||||
}
|
||||
|
||||
func MakeActionsTokenPermissions(unitAccessMode perm.AccessMode) (ret ActionsTokenPermissions) {
|
||||
ret.UnitAccessModes = make(map[unit.Type]perm.AccessMode)
|
||||
for _, u := range ActionsTokenUnitTypes {
|
||||
ret.UnitAccessModes[u] = unitAccessMode
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ClampActionsTokenPermissions ensures that the given permissions don't exceed the maximum
|
||||
func ClampActionsTokenPermissions(p1, p2 ActionsTokenPermissions) (ret ActionsTokenPermissions) {
|
||||
ret.UnitAccessModes = make(map[unit.Type]perm.AccessMode)
|
||||
for _, ut := range ActionsTokenUnitTypes {
|
||||
ret.UnitAccessModes[ut] = min(p1.UnitAccessModes[ut], p2.UnitAccessModes[ut])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// MakeRestrictedPermissions returns the restricted permissions
|
||||
func MakeRestrictedPermissions() ActionsTokenPermissions {
|
||||
ret := MakeActionsTokenPermissions(perm.AccessModeNone)
|
||||
ret.UnitAccessModes[unit.TypeCode] = perm.AccessModeRead
|
||||
ret.UnitAccessModes[unit.TypePackages] = perm.AccessModeRead
|
||||
ret.UnitAccessModes[unit.TypeReleases] = perm.AccessModeRead
|
||||
return ret
|
||||
}
|
||||
|
||||
type ActionsConfig struct {
|
||||
DisabledWorkflows []string
|
||||
// CollaborativeOwnerIDs is a list of owner IDs used to share actions from private repos.
|
||||
// Only workflows from the private repos whose owners are in CollaborativeOwnerIDs can access the current repo's actions.
|
||||
CollaborativeOwnerIDs []int64
|
||||
// TokenPermissionMode defines the default permission mode (permissive, restricted, or custom)
|
||||
TokenPermissionMode ActionsTokenPermissionMode `json:"token_permission_mode,omitempty"`
|
||||
// MaxTokenPermissions defines the absolute maximum permissions any token can have in this context.
|
||||
// Workflow YAML "permissions" keywords can reduce permissions but never exceed this ceiling.
|
||||
MaxTokenPermissions *ActionsTokenPermissions `json:"max_token_permissions,omitempty"`
|
||||
// OverrideOwnerConfig indicates if this repository should override the owner-level configuration (User or Org)
|
||||
OverrideOwnerConfig bool `json:"override_owner_config,omitempty"`
|
||||
}
|
||||
|
||||
func (cfg *ActionsConfig) EnableWorkflow(file string) {
|
||||
cfg.DisabledWorkflows = util.SliceRemoveAll(cfg.DisabledWorkflows, file)
|
||||
}
|
||||
|
||||
func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool {
|
||||
return slices.Contains(cfg.DisabledWorkflows, file)
|
||||
}
|
||||
|
||||
func (cfg *ActionsConfig) DisableWorkflow(file string) {
|
||||
if slices.Contains(cfg.DisabledWorkflows, file) {
|
||||
return
|
||||
}
|
||||
|
||||
cfg.DisabledWorkflows = append(cfg.DisabledWorkflows, file)
|
||||
}
|
||||
|
||||
func (cfg *ActionsConfig) AddCollaborativeOwner(ownerID int64) {
|
||||
if !slices.Contains(cfg.CollaborativeOwnerIDs, ownerID) {
|
||||
cfg.CollaborativeOwnerIDs = append(cfg.CollaborativeOwnerIDs, ownerID)
|
||||
}
|
||||
}
|
||||
|
||||
func (cfg *ActionsConfig) RemoveCollaborativeOwner(ownerID int64) {
|
||||
cfg.CollaborativeOwnerIDs = util.SliceRemoveAll(cfg.CollaborativeOwnerIDs, ownerID)
|
||||
}
|
||||
|
||||
func (cfg *ActionsConfig) IsCollaborativeOwner(ownerID int64) bool {
|
||||
return slices.Contains(cfg.CollaborativeOwnerIDs, ownerID)
|
||||
}
|
||||
|
||||
// GetDefaultTokenPermissions returns the default token permissions by its TokenPermissionMode.
|
||||
// It does not apply MaxTokenPermissions; callers must clamp if needed.
|
||||
func (cfg *ActionsConfig) GetDefaultTokenPermissions() ActionsTokenPermissions {
|
||||
switch cfg.TokenPermissionMode {
|
||||
case ActionsTokenPermissionModeRestricted:
|
||||
return MakeRestrictedPermissions()
|
||||
case ActionsTokenPermissionModePermissive:
|
||||
return MakeActionsTokenPermissions(perm.AccessModeWrite)
|
||||
default:
|
||||
return ActionsTokenPermissions{}
|
||||
}
|
||||
}
|
||||
|
||||
// GetMaxTokenPermissions returns the maximum allowed permissions
|
||||
func (cfg *ActionsConfig) GetMaxTokenPermissions() ActionsTokenPermissions {
|
||||
if cfg.MaxTokenPermissions != nil {
|
||||
return *cfg.MaxTokenPermissions
|
||||
}
|
||||
// Default max is write for everything
|
||||
return MakeActionsTokenPermissions(perm.AccessModeWrite)
|
||||
}
|
||||
|
||||
// ClampPermissions ensures that the given permissions don't exceed the maximum
|
||||
func (cfg *ActionsConfig) ClampPermissions(perms ActionsTokenPermissions) ActionsTokenPermissions {
|
||||
maxPerms := cfg.GetMaxTokenPermissions()
|
||||
return ClampActionsTokenPermissions(perms, maxPerms)
|
||||
}
|
||||
|
||||
// FromDB fills up a ActionsConfig from serialized format.
|
||||
func (cfg *ActionsConfig) FromDB(bs []byte) error {
|
||||
_ = json.UnmarshalHandleDoubleEncode(bs, &cfg)
|
||||
cfg.TokenPermissionMode, _ = util.EnumValue(cfg.TokenPermissionMode)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToDB exports a ActionsConfig to a serialized format.
|
||||
func (cfg *ActionsConfig) ToDB() ([]byte, error) {
|
||||
return json.Marshal(cfg)
|
||||
}
|
||||
Reference in New Issue
Block a user