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
+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