mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-23 21:04:55 +02:00
refactor: migrate protected branch fields into one json column and support system users (#39735)
1. migrate protected branch fields into one json column 2. use the dropdown list for push/force-push user selection, and Actions user can be added into the list now.
This commit is contained in:
1 parent
f270534e83
commit
c6e2513570
25 files changed
+659
-334
No files matched your search
@@ -13,8 +13,12 @@ import (
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func iterateTableByColumn[Bean any](ctx context.Context, colName string, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error {
|
||||
table, err := xormEngine.TableInfo(new(Bean))
|
||||
type sqlTableInfoProvider interface {
|
||||
TableInfo(bean any) (*schemas.Table, error)
|
||||
}
|
||||
|
||||
func IterateTableByColumn[Bean any](ctx context.Context, tableInfo sqlTableInfoProvider, sess SQLSession, colName string, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error {
|
||||
table, err := tableInfo.TableInfo(new(Bean))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -36,7 +40,7 @@ func iterateTableByColumn[Bean any](ctx context.Context, colName string, cond bu
|
||||
}
|
||||
|
||||
beans := make([]*Bean, 0, batchSize)
|
||||
query := GetEngine(ctx).Table(table.Name).Asc(colName)
|
||||
query := sess.Table(table.Name).Asc(colName)
|
||||
|
||||
batchCond := cond
|
||||
if lastColValue != nil {
|
||||
@@ -68,9 +72,9 @@ func iterateTableByColumn[Bean any](ctx context.Context, colName string, cond bu
|
||||
}
|
||||
|
||||
func IterateByColumn[Bean any](ctx context.Context, colName string, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error {
|
||||
return iterateTableByColumn(ctx, colName, cond, f)
|
||||
return IterateTableByColumn(ctx, xormEngine, GetEngine(ctx), colName, cond, f)
|
||||
}
|
||||
|
||||
func Iterate[Bean any](ctx context.Context, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error {
|
||||
return iterateTableByColumn(ctx, "", cond, f)
|
||||
return IterateTableByColumn(ctx, xormEngine, GetEngine(ctx), "", cond, f)
|
||||
}
|
||||
@@ -28,50 +28,53 @@ var ErrBranchIsProtected = util.ErrorWrap(util.ErrPermissionDenied, "branch is p
|
||||
|
||||
// ProtectedBranch struct
|
||||
type ProtectedBranch struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"UNIQUE(s)"`
|
||||
Repo *repo_model.Repository `xorm:"-"`
|
||||
RuleName string `xorm:"'branch_name' UNIQUE(s)"` // a branch name or a glob match to branch name
|
||||
Priority int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
globRule glob.Glob `xorm:"-"`
|
||||
isPlainName bool `xorm:"-"`
|
||||
CanPush bool `xorm:"NOT NULL DEFAULT false"`
|
||||
EnableWhitelist bool
|
||||
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
|
||||
WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
|
||||
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
EnableBypassAllowlist bool `xorm:"NOT NULL DEFAULT false"`
|
||||
BypassAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
BypassAllowlistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
CanForcePush bool `xorm:"NOT NULL DEFAULT false"`
|
||||
EnableForcePushAllowlist bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ForcePushAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
ForcePushAllowlistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
ForcePushAllowlistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
|
||||
EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"`
|
||||
StatusCheckContexts []string `xorm:"JSON TEXT"`
|
||||
EnableApprovalsWhitelist bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
ApprovalsWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
RequiredApprovals int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
BlockOnRejectedReviews bool `xorm:"NOT NULL DEFAULT false"`
|
||||
BlockOnOfficialReviewRequests bool `xorm:"NOT NULL DEFAULT false"`
|
||||
BlockOnCodeownerReviews bool `xorm:"NOT NULL DEFAULT false"`
|
||||
BlockOnOutdatedBranch bool `xorm:"NOT NULL DEFAULT false"`
|
||||
DismissStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`
|
||||
IgnoreStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`
|
||||
RequireSignedCommits bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ProtectedFilePatterns string `xorm:"TEXT"`
|
||||
UnprotectedFilePatterns string `xorm:"TEXT"`
|
||||
BlockAdminMergeOverride bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"UNIQUE(s)"`
|
||||
Repo *repo_model.Repository `xorm:"-"`
|
||||
RuleName string `xorm:"'branch_name' UNIQUE(s)"` // a branch name or a glob match to branch name
|
||||
Priority int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
globRule glob.Glob `xorm:"-"`
|
||||
isPlainName bool `xorm:"-"`
|
||||
ProtectedBranchConfig `xorm:"'config' JSON LONGTEXT"`
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
// ProtectedBranchConfig stores protection settings in a single JSON column.
|
||||
type ProtectedBranchConfig struct {
|
||||
CanPush bool `json:"can_push,omitzero"`
|
||||
EnableWhitelist bool `json:"enable_whitelist,omitzero"`
|
||||
WhitelistUserIDs []int64 `json:"whitelist_user_ids,omitzero"`
|
||||
WhitelistTeamIDs []int64 `json:"whitelist_team_ids,omitzero"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitzero"`
|
||||
MergeWhitelistUserIDs []int64 `json:"merge_whitelist_user_ids,omitzero"`
|
||||
MergeWhitelistTeamIDs []int64 `json:"merge_whitelist_team_ids,omitzero"`
|
||||
EnableBypassAllowlist bool `json:"enable_bypass_allowlist,omitzero"`
|
||||
BypassAllowlistUserIDs []int64 `json:"bypass_allowlist_user_ids,omitzero"`
|
||||
BypassAllowlistTeamIDs []int64 `json:"bypass_allowlist_team_ids,omitzero"`
|
||||
CanForcePush bool `json:"can_force_push,omitzero"`
|
||||
EnableForcePushAllowlist bool `json:"enable_force_push_allowlist,omitzero"`
|
||||
ForcePushAllowlistUserIDs []int64 `json:"force_push_allowlist_user_ids,omitzero"`
|
||||
ForcePushAllowlistTeamIDs []int64 `json:"force_push_allowlist_team_ids,omitzero"`
|
||||
EnableStatusCheck bool `json:"enable_status_check,omitzero"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts,omitzero"`
|
||||
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitzero"`
|
||||
ApprovalsWhitelistUserIDs []int64 `json:"approvals_whitelist_user_ids,omitzero"`
|
||||
ApprovalsWhitelistTeamIDs []int64 `json:"approvals_whitelist_team_ids,omitzero"`
|
||||
RequiredApprovals int64 `json:"required_approvals,omitzero"`
|
||||
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews,omitzero"`
|
||||
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitzero"`
|
||||
BlockOnCodeownerReviews bool `json:"block_on_codeowner_reviews,omitzero"`
|
||||
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch,omitzero"`
|
||||
DismissStaleApprovals bool `json:"dismiss_stale_approvals,omitzero"`
|
||||
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitzero"`
|
||||
RequireSignedCommits bool `json:"require_signed_commits,omitzero"`
|
||||
ProtectedFilePatterns string `json:"protected_file_patterns,omitzero"`
|
||||
UnprotectedFilePatterns string `json:"unprotected_file_patterns,omitzero"`
|
||||
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitzero"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(ProtectedBranch))
|
||||
}
|
||||
@@ -525,13 +528,17 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre
|
||||
|
||||
whitelist = make([]int64, 0, len(newWhitelist))
|
||||
for _, userID := range newWhitelist {
|
||||
if userID == user_model.ActionsUserID || userID == user_model.DeployKeyUserID {
|
||||
whitelist = append(whitelist, userID)
|
||||
continue
|
||||
}
|
||||
user, err := user_model.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %w", userID, repo.ID, err)
|
||||
}
|
||||
perm, err := access_model.GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetIndividualUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
return nil, fmt.Errorf("GetIndividualUserRepoPermission [user_id: %d, repo_id: %d]: %w", userID, repo.ID, err)
|
||||
}
|
||||
|
||||
if !perm.CanWrite(unit.TypeCode) {
|
||||
@@ -589,7 +596,7 @@ func DeleteProtectedBranch(ctx context.Context, repo *repo_model.Repository, id
|
||||
}
|
||||
|
||||
// removeIDsFromProtectedBranch is a helper function to remove IDs from protected branch options
|
||||
func removeIDsFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userID, teamID int64, columnNames []string) error {
|
||||
func removeIDsFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userID, teamID int64) error {
|
||||
lenUserIDs, lenForcePushIDs, lenApprovalIDs, lenMergeIDs := len(p.WhitelistUserIDs), len(p.ForcePushAllowlistUserIDs), len(p.ApprovalsWhitelistUserIDs), len(p.MergeWhitelistUserIDs)
|
||||
lenTeamIDs, lenForcePushTeamIDs, lenApprovalTeamIDs, lenMergeTeamIDs := len(p.WhitelistTeamIDs), len(p.ForcePushAllowlistTeamIDs), len(p.ApprovalsWhitelistTeamIDs), len(p.MergeWhitelistTeamIDs)
|
||||
|
||||
@@ -615,7 +622,7 @@ func removeIDsFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userI
|
||||
lenForcePushTeamIDs != len(p.ForcePushAllowlistTeamIDs) ||
|
||||
lenApprovalTeamIDs != len(p.ApprovalsWhitelistTeamIDs) ||
|
||||
lenMergeTeamIDs != len(p.MergeWhitelistTeamIDs)) {
|
||||
if _, err := db.GetEngine(ctx).ID(p.ID).Cols(columnNames...).Update(p); err != nil {
|
||||
if _, err := db.GetEngine(ctx).ID(p.ID).Cols("config").Update(p); err != nil {
|
||||
return fmt.Errorf("updateProtectedBranches: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -624,22 +631,18 @@ func removeIDsFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userI
|
||||
|
||||
// RemoveUserIDFromProtectedBranch removes all user ids from protected branch options
|
||||
func RemoveUserIDFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userID int64) error {
|
||||
columnNames := []string{
|
||||
"whitelist_user_i_ds",
|
||||
"force_push_allowlist_user_i_ds",
|
||||
"merge_whitelist_user_i_ds",
|
||||
"approvals_whitelist_user_i_ds",
|
||||
}
|
||||
return removeIDsFromProtectedBranch(ctx, p, userID, 0, columnNames)
|
||||
return removeIDsFromProtectedBranch(ctx, p, userID, 0)
|
||||
}
|
||||
|
||||
// RemoveTeamIDFromProtectedBranch removes all team ids from protected branch options
|
||||
func RemoveTeamIDFromProtectedBranch(ctx context.Context, p *ProtectedBranch, teamID int64) error {
|
||||
columnNames := []string{
|
||||
"whitelist_team_i_ds",
|
||||
"force_push_allowlist_team_i_ds",
|
||||
"merge_whitelist_team_i_ds",
|
||||
"approvals_whitelist_team_i_ds",
|
||||
}
|
||||
return removeIDsFromProtectedBranch(ctx, p, 0, teamID, columnNames)
|
||||
return removeIDsFromProtectedBranch(ctx, p, 0, teamID)
|
||||
}
|
||||
|
||||
func (protectBranch *ProtectedBranch) HasDeployKeyPush() bool {
|
||||
return slices.Contains(protectBranch.WhitelistUserIDs, user_model.DeployKeyUserID)
|
||||
}
|
||||
|
||||
func (protectBranch *ProtectedBranch) HasDeployKeyForcePush() bool {
|
||||
return slices.Contains(protectBranch.ForcePushAllowlistUserIDs, user_model.DeployKeyUserID)
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
user_model "gitea.dev/models/user"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBranchRuleMatch(t *testing.T) {
|
||||
@@ -202,3 +203,28 @@ func TestCanBypassBranchProtection(t *testing.T) {
|
||||
// User does not bypass when not in allowlisted teams.
|
||||
testBypass(t, false, pb, user, false)
|
||||
}
|
||||
|
||||
func TestProtectedBranchConfig(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
ctx := t.Context()
|
||||
pb := &ProtectedBranch{
|
||||
RepoID: 1, RuleName: "config-test",
|
||||
ProtectedBranchConfig: ProtectedBranchConfig{
|
||||
CanPush: true, WhitelistUserIDs: []int64{2, 4}, WhitelistTeamIDs: []int64{1, 2}, StatusCheckContexts: []string{},
|
||||
},
|
||||
}
|
||||
require.NoError(t, db.Insert(ctx, pb))
|
||||
loaded := unittest.AssertExistsAndLoadBean(t, &ProtectedBranch{ID: pb.ID})
|
||||
assert.Equal(t, pb.ProtectedBranchConfig, loaded.ProtectedBranchConfig)
|
||||
require.NoError(t, RemoveUserIDFromProtectedBranch(ctx, loaded, 2))
|
||||
require.NoError(t, RemoveTeamIDFromProtectedBranch(ctx, loaded, 1))
|
||||
loaded = unittest.AssertExistsAndLoadBean(t, &ProtectedBranch{ID: pb.ID})
|
||||
assert.Equal(t, []int64{4}, loaded.WhitelistUserIDs)
|
||||
assert.Equal(t, []int64{2}, loaded.WhitelistTeamIDs)
|
||||
assert.True(t, loaded.CanPush)
|
||||
loaded.ProtectedBranchConfig = ProtectedBranchConfig{}
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
require.NoError(t, UpdateProtectBranch(ctx, repo, loaded, WhitelistOptions{}))
|
||||
loaded = unittest.AssertExistsAndLoadBean(t, &ProtectedBranch{ID: pb.ID})
|
||||
assert.Equal(t, ProtectedBranchConfig{}, loaded.ProtectedBranchConfig)
|
||||
}
|
||||
@@ -188,5 +188,5 @@ func MakeIDsFromAPIAssigneesToAdd(ctx context.Context, oneAssignee string, multi
|
||||
}
|
||||
|
||||
// Get the IDs of all assignees
|
||||
return user_model.GetUserIDsByNames(ctx, requestAssignees, false)
|
||||
return user_model.GetDoerUserIDsByNames(ctx, requestAssignees)
|
||||
}
|
||||
@@ -433,7 +433,7 @@ func TestRecalculateReviewsOfficial(t *testing.T) {
|
||||
|
||||
// Once the reviewer is whitelisted, re-evaluating restores the official flag.
|
||||
rule.ApprovalsWhitelistUserIDs = []int64{2, reviewer.ID}
|
||||
_, err = db.GetEngine(t.Context()).ID(rule.ID).Cols("approvals_whitelist_user_i_ds").Update(rule)
|
||||
_, err = db.GetEngine(t.Context()).ID(rule.ID).Cols("config").Update(rule)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NoError(t, issues_model.RecalculateReviewsOfficial(t.Context(), issue))
|
||||
|
||||
+48
-18
@@ -560,13 +560,13 @@ func GetUserSalt() (string, error) {
|
||||
}
|
||||
|
||||
type globalVarsStruct struct {
|
||||
customCharsReplacement *strings.Replacer
|
||||
removeCharsRE *regexp.Regexp
|
||||
transformDiacritics transform.Transformer
|
||||
replaceCharsHyphenRE *regexp.Regexp
|
||||
emailToReplacer *strings.Replacer
|
||||
systemUserNewFuncs map[int64]func() *User
|
||||
systemUserNameIdMap map[string]int64
|
||||
customCharsReplacement *strings.Replacer
|
||||
removeCharsRE *regexp.Regexp
|
||||
transformDiacritics transform.Transformer
|
||||
replaceCharsHyphenRE *regexp.Regexp
|
||||
emailToReplacer *strings.Replacer
|
||||
systemUserNewFuncs map[int64]func() *User
|
||||
systemUserLowerNameIdMap map[string]int64
|
||||
}
|
||||
|
||||
var globalVars = sync.OnceValue(func() *globalVarsStruct {
|
||||
@@ -592,11 +592,11 @@ var globalVars = sync.OnceValue(func() *globalVarsStruct {
|
||||
|
||||
userFuncs := []func() *User{NewGhostUser, NewActionsUser, NewDeployKeyUser, NewCliUser, NewAuthSourceUser}
|
||||
ret.systemUserNewFuncs = map[int64]func() *User{}
|
||||
ret.systemUserNameIdMap = map[string]int64{}
|
||||
ret.systemUserLowerNameIdMap = map[string]int64{}
|
||||
for _, fn := range userFuncs {
|
||||
u := fn()
|
||||
ret.systemUserNewFuncs[u.ID] = fn
|
||||
ret.systemUserNameIdMap[u.LowerName] = u.ID
|
||||
ret.systemUserLowerNameIdMap[u.LowerName] = u.ID
|
||||
}
|
||||
return ret
|
||||
})
|
||||
@@ -1148,20 +1148,50 @@ func GetMailableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]
|
||||
Find(&ous)
|
||||
}
|
||||
|
||||
// GetUserIDsByNames returns a slice of ids corresponds to names.
|
||||
func GetUserIDsByNames(ctx context.Context, names []string, ignoreNonExistent bool) ([]int64, error) {
|
||||
ids := make([]int64, 0, len(names))
|
||||
func getDoerUserIDsByNames(ctx context.Context, names []string, allowSystemDoer bool) ([]int64, error) {
|
||||
namesLower := make([]string, 0, len(names))
|
||||
namesMap := make(map[string]*User, len(names))
|
||||
for _, name := range names {
|
||||
u, err := GetUserByName(ctx, name)
|
||||
if err != nil {
|
||||
if ignoreNonExistent {
|
||||
continue
|
||||
nameLower := strings.ToLower(name)
|
||||
namesLower = append(namesLower, nameLower)
|
||||
namesMap[nameLower] = nil
|
||||
if allowSystemDoer {
|
||||
if id, ok := globalVars().systemUserLowerNameIdMap[nameLower]; ok && id != GhostUserID {
|
||||
namesMap[nameLower] = globalVars().systemUserNewFuncs[id]()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var users []*User
|
||||
err := db.GetEngine(ctx).In("lower_name", namesLower).Where("`type` IN (?,?)", UserTypeIndividual, UserTypeBot).Find(&users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, user := range users {
|
||||
namesMap[user.LowerName] = user
|
||||
}
|
||||
|
||||
ids := make([]int64, 0, len(names))
|
||||
var errFinal error
|
||||
for _, nameLower := range namesLower {
|
||||
u := namesMap[nameLower]
|
||||
if u == nil {
|
||||
errFinal = ErrUserNotExist{Name: nameLower}
|
||||
continue
|
||||
}
|
||||
ids = append(ids, u.ID)
|
||||
}
|
||||
return ids, nil
|
||||
return ids, errFinal
|
||||
}
|
||||
|
||||
func GetDoerUserIDsByNamesWithSystem(ctx context.Context, names []string) ([]int64, error) {
|
||||
return getDoerUserIDsByNames(ctx, names, true)
|
||||
}
|
||||
|
||||
// GetDoerUserIDsByNames returns a slice of ids corresponds to names.
|
||||
// It always returns found user IDs even if some names are not found, but returns an error if any name is not found.
|
||||
func GetDoerUserIDsByNames(ctx context.Context, names []string) ([]int64, error) {
|
||||
return getDoerUserIDsByNames(ctx, names, false)
|
||||
}
|
||||
|
||||
// GetUsersBySource returns a list of Users for a login source
|
||||
|
||||
@@ -73,7 +73,7 @@ func NewActionsUserWithTaskID(id int64) *User {
|
||||
}
|
||||
|
||||
func NewDeployKeyUser() *User {
|
||||
return newSystemUser(DeployKeyUserID, "(deploy-key)", "Deploy Key")
|
||||
return newSystemUser(DeployKeyUserID, "gitea:deploy-key", "Deploy Key")
|
||||
}
|
||||
|
||||
func GetDeployKeyUserDeployKeyID(u *User) (int64, bool) {
|
||||
@@ -94,17 +94,21 @@ func NewDeployKeyUserWithKeyID(id int64) *User {
|
||||
|
||||
func NewCliUser() *User {
|
||||
// for audit log only
|
||||
return newSystemUser(CliUserID, "(gitea-cli)", "Gitea CLI")
|
||||
return newSystemUser(CliUserID, "gitea:cli", "Gitea CLI")
|
||||
}
|
||||
|
||||
func NewAuthSourceUser() *User {
|
||||
// for audit log only
|
||||
return newSystemUser(AuthSourceUserID, "(gitea-auth-source)", "Gitea Auth Source")
|
||||
return newSystemUser(AuthSourceUserID, "gitea:auth-source", "Gitea Auth Source")
|
||||
}
|
||||
|
||||
func GetSystemUserByName(name string) *User {
|
||||
lowerName := strings.ToLower(name)
|
||||
uid := globalVars().systemUserNameIdMap[lowerName]
|
||||
uid := globalVars().systemUserLowerNameIdMap[lowerName]
|
||||
return GetSystemUserByID(uid)
|
||||
}
|
||||
|
||||
func GetSystemUserByID(uid int64) *User {
|
||||
if fn := globalVars().systemUserNewFuncs[uid]; fn != nil {
|
||||
return fn()
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/test"
|
||||
"gitea.dev/modules/timeutil"
|
||||
"gitea.dev/modules/util"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -363,18 +364,15 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
|
||||
assert.LessOrEqual(t, fetched.UpdatedUnix, timestampEnd)
|
||||
}
|
||||
|
||||
func TestGetUserIDsByNames(t *testing.T) {
|
||||
func TestGetDoerUserIDsByNames(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
ids, err := user_model.GetDoerUserIDsByNames(t.Context(), []string{"user1", "user2", "none_existing_user"})
|
||||
assert.ErrorIs(t, err, util.ErrNotExist)
|
||||
assert.Equal(t, []int64{1, 2}, ids)
|
||||
|
||||
// ignore non existing
|
||||
IDs, err := user_model.GetUserIDsByNames(t.Context(), []string{"user1", "user2", "none_existing_user"}, true)
|
||||
ids, err = user_model.GetDoerUserIDsByNamesWithSystem(t.Context(), []string{"gitea-actions", "gitea:deploy-key"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []int64{1, 2}, IDs)
|
||||
|
||||
// ignore non existing
|
||||
IDs, err = user_model.GetUserIDsByNames(t.Context(), []string{"user1", "do_not_exist"}, false)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, []int64(nil), IDs)
|
||||
assert.Equal(t, []int64{-2, -3}, ids)
|
||||
}
|
||||
|
||||
func TestGetMaileableUsersByIDs(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user