mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Remove GetByBean method because sometimes it's danger when query condition parameter is zero and also introduce new generic methods (#28220)
The function `GetByBean` has an obvious defect that when the fields are
empty values, it will be ignored. Then users will get a wrong result
which is possibly used to make a security problem.
To avoid the possibility, this PR removed function `GetByBean` and all
references.
And some new generic functions have been introduced to be used.
The recommand usage like below.
```go
// if query an object according id
obj, err := db.GetByID[Object](ctx, id)
// query with other conditions
obj, err := db.Get[Object](ctx, builder.Eq{"a": a, "b":b})
```
			
			
This commit is contained in:
		| @@ -131,24 +131,22 @@ func AddDeployKey(ctx context.Context, repoID int64, name, content string, readO | |||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	pkey := &PublicKey{ | 	pkey, exist, err := db.Get[PublicKey](ctx, builder.Eq{"fingerprint": fingerprint}) | ||||||
| 		Fingerprint: fingerprint, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, pkey) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} else if exist { | ||||||
|  |  | ||||||
| 	if has { |  | ||||||
| 		if pkey.Type != KeyTypeDeploy { | 		if pkey.Type != KeyTypeDeploy { | ||||||
| 			return nil, ErrKeyAlreadyExist{0, fingerprint, ""} | 			return nil, ErrKeyAlreadyExist{0, fingerprint, ""} | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		// First time use this deploy key. | 		// First time use this deploy key. | ||||||
| 		pkey.Mode = accessMode | 		pkey = &PublicKey{ | ||||||
| 		pkey.Type = KeyTypeDeploy | 			Fingerprint: fingerprint, | ||||||
| 		pkey.Content = content | 			Mode:        accessMode, | ||||||
| 		pkey.Name = name | 			Type:        KeyTypeDeploy, | ||||||
|  | 			Content:     content, | ||||||
|  | 			Name:        name, | ||||||
|  | 		} | ||||||
| 		if err = addKey(ctx, pkey); err != nil { | 		if err = addKey(ctx, pkey); err != nil { | ||||||
| 			return nil, fmt.Errorf("addKey: %w", err) | 			return nil, fmt.Errorf("addKey: %w", err) | ||||||
| 		} | 		} | ||||||
| @@ -164,11 +162,10 @@ func AddDeployKey(ctx context.Context, repoID int64, name, content string, readO | |||||||
|  |  | ||||||
| // GetDeployKeyByID returns deploy key by given ID. | // GetDeployKeyByID returns deploy key by given ID. | ||||||
| func GetDeployKeyByID(ctx context.Context, id int64) (*DeployKey, error) { | func GetDeployKeyByID(ctx context.Context, id int64) (*DeployKey, error) { | ||||||
| 	key := new(DeployKey) | 	key, exist, err := db.GetByID[DeployKey](ctx, id) | ||||||
| 	has, err := db.GetEngine(ctx).ID(id).Get(key) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrDeployKeyNotExist{id, 0, 0} | 		return nil, ErrDeployKeyNotExist{id, 0, 0} | ||||||
| 	} | 	} | ||||||
| 	return key, nil | 	return key, nil | ||||||
| @@ -176,14 +173,10 @@ func GetDeployKeyByID(ctx context.Context, id int64) (*DeployKey, error) { | |||||||
|  |  | ||||||
| // GetDeployKeyByRepo returns deploy key by given public key ID and repository ID. | // GetDeployKeyByRepo returns deploy key by given public key ID and repository ID. | ||||||
| func GetDeployKeyByRepo(ctx context.Context, keyID, repoID int64) (*DeployKey, error) { | func GetDeployKeyByRepo(ctx context.Context, keyID, repoID int64) (*DeployKey, error) { | ||||||
| 	key := &DeployKey{ | 	key, exist, err := db.Get[DeployKey](ctx, builder.Eq{"key_id": keyID, "repo_id": repoID}) | ||||||
| 		KeyID:  keyID, |  | ||||||
| 		RepoID: repoID, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, key) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrDeployKeyNotExist{0, keyID, repoID} | 		return nil, ErrDeployKeyNotExist{0, keyID, repoID} | ||||||
| 	} | 	} | ||||||
| 	return key, nil | 	return key, nil | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"golang.org/x/crypto/ssh" | 	"golang.org/x/crypto/ssh" | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ___________.__                                         .__        __ | // ___________.__                                         .__        __ | ||||||
| @@ -31,9 +32,7 @@ import ( | |||||||
| // checkKeyFingerprint only checks if key fingerprint has been used as public key, | // checkKeyFingerprint only checks if key fingerprint has been used as public key, | ||||||
| // it is OK to use same key as deploy key for multiple repositories/users. | // it is OK to use same key as deploy key for multiple repositories/users. | ||||||
| func checkKeyFingerprint(ctx context.Context, fingerprint string) error { | func checkKeyFingerprint(ctx context.Context, fingerprint string) error { | ||||||
| 	has, err := db.GetByBean(ctx, &PublicKey{ | 	has, err := db.Exist[PublicKey](ctx, builder.Eq{"fingerprint": fingerprint}) | ||||||
| 		Fingerprint: fingerprint, |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if has { | 	} else if has { | ||||||
|   | |||||||
| @@ -9,6 +9,8 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Session represents a session compatible for go-chi session | // Session represents a session compatible for go-chi session | ||||||
| @@ -33,34 +35,28 @@ func UpdateSession(ctx context.Context, key string, data []byte) error { | |||||||
|  |  | ||||||
| // ReadSession reads the data for the provided session | // ReadSession reads the data for the provided session | ||||||
| func ReadSession(ctx context.Context, key string) (*Session, error) { | func ReadSession(ctx context.Context, key string) (*Session, error) { | ||||||
| 	session := Session{ |  | ||||||
| 		Key: key, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ctx, committer, err := db.TxContext(ctx) | 	ctx, committer, err := db.TxContext(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if has, err := db.GetByBean(ctx, &session); err != nil { | 	session, exist, err := db.Get[Session](ctx, builder.Eq{"key": key}) | ||||||
|  | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		session.Expiry = timeutil.TimeStampNow() | 		session.Expiry = timeutil.TimeStampNow() | ||||||
| 		if err := db.Insert(ctx, &session); err != nil { | 		if err := db.Insert(ctx, &session); err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return &session, committer.Commit() | 	return session, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // ExistSession checks if a session exists | // ExistSession checks if a session exists | ||||||
| func ExistSession(ctx context.Context, key string) (bool, error) { | func ExistSession(ctx context.Context, key string) (bool, error) { | ||||||
| 	session := Session{ | 	return db.Exist[Session](ctx, builder.Eq{"key": key}) | ||||||
| 		Key: key, |  | ||||||
| 	} |  | ||||||
| 	return db.GetEngine(ctx).Get(&session) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // DestroySession destroys a session | // DestroySession destroys a session | ||||||
| @@ -79,17 +75,13 @@ func RegenerateSession(ctx context.Context, oldKey, newKey string) (*Session, er | |||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if has, err := db.GetByBean(ctx, &Session{ | 	if has, err := db.Exist[Session](ctx, builder.Eq{"key": newKey}); err != nil { | ||||||
| 		Key: newKey, |  | ||||||
| 	}); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if has { | 	} else if has { | ||||||
| 		return nil, fmt.Errorf("session Key: %s already exists", newKey) | 		return nil, fmt.Errorf("session Key: %s already exists", newKey) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if has, err := db.GetByBean(ctx, &Session{ | 	if has, err := db.Exist[Session](ctx, builder.Eq{"key": oldKey}); err != nil { | ||||||
| 		Key: oldKey, |  | ||||||
| 	}); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !has { | ||||||
| 		if err := db.Insert(ctx, &Session{ | 		if err := db.Insert(ctx, &Session{ | ||||||
| @@ -104,14 +96,13 @@ func RegenerateSession(ctx context.Context, oldKey, newKey string) (*Session, er | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	s := Session{ | 	s, _, err := db.Get[Session](ctx, builder.Eq{"key": newKey}) | ||||||
| 		Key: newKey, | 	if err != nil { | ||||||
| 	} | 		// is not exist, it should be impossible | ||||||
| 	if _, err := db.GetByBean(ctx, &s); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return &s, committer.Commit() | 	return s, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // CountSessions returns the number of sessions | // CountSessions returns the number of sessions | ||||||
|   | |||||||
| @@ -265,10 +265,10 @@ func IsSSPIEnabled(ctx context.Context) bool { | |||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	exist, err := db.Exists[Source](ctx, FindSourcesOptions{ | 	exist, err := db.Exist[Source](ctx, FindSourcesOptions{ | ||||||
| 		IsActive:  util.OptionalBoolTrue, | 		IsActive:  util.OptionalBoolTrue, | ||||||
| 		LoginType: SSPI, | 		LoginType: SSPI, | ||||||
| 	}) | 	}.ToConds()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Active SSPI Sources: %v", err) | 		log.Error("Active SSPI Sources: %v", err) | ||||||
| 		return false | 		return false | ||||||
|   | |||||||
| @@ -173,9 +173,44 @@ func Exec(ctx context.Context, sqlAndArgs ...any) (sql.Result, error) { | |||||||
| 	return GetEngine(ctx).Exec(sqlAndArgs...) | 	return GetEngine(ctx).Exec(sqlAndArgs...) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetByBean filled empty fields of the bean according non-empty fields to query in database. | func Get[T any](ctx context.Context, cond builder.Cond) (object *T, exist bool, err error) { | ||||||
| func GetByBean(ctx context.Context, bean any) (bool, error) { | 	if !cond.IsValid() { | ||||||
| 	return GetEngine(ctx).Get(bean) | 		return nil, false, ErrConditionRequired{} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var bean T | ||||||
|  | 	has, err := GetEngine(ctx).Where(cond).NoAutoCondition().Get(&bean) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, false, err | ||||||
|  | 	} else if !has { | ||||||
|  | 		return nil, false, nil | ||||||
|  | 	} | ||||||
|  | 	return &bean, true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetByID[T any](ctx context.Context, id int64) (object *T, exist bool, err error) { | ||||||
|  | 	var bean T | ||||||
|  | 	has, err := GetEngine(ctx).ID(id).NoAutoCondition().Get(&bean) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, false, err | ||||||
|  | 	} else if !has { | ||||||
|  | 		return nil, false, nil | ||||||
|  | 	} | ||||||
|  | 	return &bean, true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Exist[T any](ctx context.Context, cond builder.Cond) (bool, error) { | ||||||
|  | 	if !cond.IsValid() { | ||||||
|  | 		return false, ErrConditionRequired{} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var bean T | ||||||
|  | 	return GetEngine(ctx).Where(cond).NoAutoCondition().Exist(&bean) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ExistByID[T any](ctx context.Context, id int64) (bool, error) { | ||||||
|  | 	var bean T | ||||||
|  | 	return GetEngine(ctx).ID(id).NoAutoCondition().Exist(&bean) | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteByBean deletes all records according non-empty fields of the bean as conditions. | // DeleteByBean deletes all records according non-empty fields of the bean as conditions. | ||||||
| @@ -264,8 +299,3 @@ func inTransaction(ctx context.Context) (*xorm.Session, bool) { | |||||||
| 		return nil, false | 		return nil, false | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func Exists[T any](ctx context.Context, opts FindOptions) (bool, error) { |  | ||||||
| 	var bean T |  | ||||||
| 	return GetEngine(ctx).Where(opts.ToConds()).Exist(&bean) |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -72,3 +72,21 @@ func (err ErrNotExist) Error() string { | |||||||
| func (err ErrNotExist) Unwrap() error { | func (err ErrNotExist) Unwrap() error { | ||||||
| 	return util.ErrNotExist | 	return util.ErrNotExist | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ErrConditionRequired represents an error which require condition. | ||||||
|  | type ErrConditionRequired struct{} | ||||||
|  |  | ||||||
|  | // IsErrConditionRequired checks if an error is an ErrConditionRequired | ||||||
|  | func IsErrConditionRequired(err error) bool { | ||||||
|  | 	_, ok := err.(ErrConditionRequired) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrConditionRequired) Error() string { | ||||||
|  | 	return "condition is required" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Unwrap unwraps this as a ErrNotExist err | ||||||
|  | func (err ErrConditionRequired) Unwrap() error { | ||||||
|  | 	return util.ErrInvalidArgument | ||||||
|  | } | ||||||
|   | |||||||
| @@ -31,11 +31,11 @@ func TestIterate(t *testing.T) { | |||||||
| 	assert.EqualValues(t, cnt, repoUnitCnt) | 	assert.EqualValues(t, cnt, repoUnitCnt) | ||||||
|  |  | ||||||
| 	err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error { | 	err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error { | ||||||
| 		reopUnit2 := repo_model.RepoUnit{ID: repoUnit.ID} | 		has, err := db.ExistByID[repo_model.RepoUnit](ctx, repoUnit.ID) | ||||||
| 		has, err := db.GetByBean(ctx, &reopUnit2) |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} else if !has { | 		} | ||||||
|  | 		if !has { | ||||||
| 			return db.ErrNotExist{Resource: "repo_unit", ID: repoUnit.ID} | 			return db.ErrNotExist{Resource: "repo_unit", ID: repoUnit.ID} | ||||||
| 		} | 		} | ||||||
| 		assert.EqualValues(t, repoUnit.RepoID, repoUnit.RepoID) | 		assert.EqualValues(t, repoUnit.RepoID, repoUnit.RepoID) | ||||||
|   | |||||||
| @@ -135,7 +135,7 @@ var ErrLFSObjectNotExist = db.ErrNotExist{Resource: "LFS Meta object"} | |||||||
|  |  | ||||||
| // NewLFSMetaObject stores a given populated LFSMetaObject structure in the database | // NewLFSMetaObject stores a given populated LFSMetaObject structure in the database | ||||||
| // if it is not already present. | // if it is not already present. | ||||||
| func NewLFSMetaObject(ctx context.Context, m *LFSMetaObject) (*LFSMetaObject, error) { | func NewLFSMetaObject(ctx context.Context, repoID int64, p lfs.Pointer) (*LFSMetaObject, error) { | ||||||
| 	var err error | 	var err error | ||||||
|  |  | ||||||
| 	ctx, committer, err := db.TxContext(ctx) | 	ctx, committer, err := db.TxContext(ctx) | ||||||
| @@ -144,16 +144,15 @@ func NewLFSMetaObject(ctx context.Context, m *LFSMetaObject) (*LFSMetaObject, er | |||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	has, err := db.GetByBean(ctx, m) | 	m, exist, err := db.Get[LFSMetaObject](ctx, builder.Eq{"repository_id": repoID, "oid": p.Oid}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} else if exist { | ||||||
|  |  | ||||||
| 	if has { |  | ||||||
| 		m.Existing = true | 		m.Existing = true | ||||||
| 		return m, committer.Commit() | 		return m, committer.Commit() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	m = &LFSMetaObject{Pointer: p, RepositoryID: repoID} | ||||||
| 	if err = db.Insert(ctx, m); err != nil { | 	if err = db.Insert(ctx, m); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/gobwas/glob" | 	"github.com/gobwas/glob" | ||||||
| 	"github.com/gobwas/glob/syntax" | 	"github.com/gobwas/glob/syntax" | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ErrBranchIsProtected = errors.New("branch is protected") | var ErrBranchIsProtected = errors.New("branch is protected") | ||||||
| @@ -274,12 +275,11 @@ func (protectBranch *ProtectedBranch) IsUnprotectedFile(patterns []glob.Glob, pa | |||||||
|  |  | ||||||
| // GetProtectedBranchRuleByName getting protected branch rule by name | // GetProtectedBranchRuleByName getting protected branch rule by name | ||||||
| func GetProtectedBranchRuleByName(ctx context.Context, repoID int64, ruleName string) (*ProtectedBranch, error) { | func GetProtectedBranchRuleByName(ctx context.Context, repoID int64, ruleName string) (*ProtectedBranch, error) { | ||||||
| 	rel := &ProtectedBranch{RepoID: repoID, RuleName: ruleName} | 	// branch_name is legacy name, it actually is rule name | ||||||
| 	has, err := db.GetByBean(ctx, rel) | 	rel, exist, err := db.Get[ProtectedBranch](ctx, builder.Eq{"repo_id": repoID, "branch_name": ruleName}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} else if !exist { | ||||||
| 	if !has { |  | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	return rel, nil | 	return rel, nil | ||||||
| @@ -287,12 +287,10 @@ func GetProtectedBranchRuleByName(ctx context.Context, repoID int64, ruleName st | |||||||
|  |  | ||||||
| // GetProtectedBranchRuleByID getting protected branch rule by rule ID | // GetProtectedBranchRuleByID getting protected branch rule by rule ID | ||||||
| func GetProtectedBranchRuleByID(ctx context.Context, repoID, ruleID int64) (*ProtectedBranch, error) { | func GetProtectedBranchRuleByID(ctx context.Context, repoID, ruleID int64) (*ProtectedBranch, error) { | ||||||
| 	rel := &ProtectedBranch{ID: ruleID, RepoID: repoID} | 	rel, exist, err := db.Get[ProtectedBranch](ctx, builder.Eq{"repo_id": repoID, "id": ruleID}) | ||||||
| 	has, err := db.GetByBean(ctx, rel) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} else if !exist { | ||||||
| 	if !has { |  | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	return rel, nil | 	return rel, nil | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // IssueAssignees saves all issue assignees | // IssueAssignees saves all issue assignees | ||||||
| @@ -59,7 +61,7 @@ func GetAssigneeIDsByIssue(ctx context.Context, issueID int64) ([]int64, error) | |||||||
|  |  | ||||||
| // IsUserAssignedToIssue returns true when the user is assigned to the issue | // IsUserAssignedToIssue returns true when the user is assigned to the issue | ||||||
| func IsUserAssignedToIssue(ctx context.Context, issue *Issue, user *user_model.User) (isAssigned bool, err error) { | func IsUserAssignedToIssue(ctx context.Context, issue *Issue, user *user_model.User) (isAssigned bool, err error) { | ||||||
| 	return db.GetByBean(ctx, &IssueAssignees{IssueID: issue.ID, AssigneeID: user.ID}) | 	return db.Exist[IssueAssignees](ctx, builder.Eq{"assignee_id": user.ID, "issue_id": issue.ID}) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ToggleIssueAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. | // ToggleIssueAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. | ||||||
|   | |||||||
| @@ -304,15 +304,11 @@ func GetLabelInRepoByName(ctx context.Context, repoID int64, labelName string) ( | |||||||
| 		return nil, ErrRepoLabelNotExist{0, repoID} | 		return nil, ErrRepoLabelNotExist{0, repoID} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	l := &Label{ | 	l, exist, err := db.Get[Label](ctx, builder.Eq{"name": labelName, "repo_id": repoID}) | ||||||
| 		Name:   labelName, |  | ||||||
| 		RepoID: repoID, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, l) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrRepoLabelNotExist{0, l.RepoID} | 		return nil, ErrRepoLabelNotExist{0, repoID} | ||||||
| 	} | 	} | ||||||
| 	return l, nil | 	return l, nil | ||||||
| } | } | ||||||
| @@ -323,15 +319,11 @@ func GetLabelInRepoByID(ctx context.Context, repoID, labelID int64) (*Label, err | |||||||
| 		return nil, ErrRepoLabelNotExist{labelID, repoID} | 		return nil, ErrRepoLabelNotExist{labelID, repoID} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	l := &Label{ | 	l, exist, err := db.Get[Label](ctx, builder.Eq{"id": labelID, "repo_id": repoID}) | ||||||
| 		ID:     labelID, |  | ||||||
| 		RepoID: repoID, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, l) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrRepoLabelNotExist{l.ID, l.RepoID} | 		return nil, ErrRepoLabelNotExist{labelID, repoID} | ||||||
| 	} | 	} | ||||||
| 	return l, nil | 	return l, nil | ||||||
| } | } | ||||||
| @@ -408,15 +400,11 @@ func GetLabelInOrgByName(ctx context.Context, orgID int64, labelName string) (*L | |||||||
| 		return nil, ErrOrgLabelNotExist{0, orgID} | 		return nil, ErrOrgLabelNotExist{0, orgID} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	l := &Label{ | 	l, exist, err := db.Get[Label](ctx, builder.Eq{"name": labelName, "org_id": orgID}) | ||||||
| 		Name:  labelName, |  | ||||||
| 		OrgID: orgID, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, l) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrOrgLabelNotExist{0, l.OrgID} | 		return nil, ErrOrgLabelNotExist{0, orgID} | ||||||
| 	} | 	} | ||||||
| 	return l, nil | 	return l, nil | ||||||
| } | } | ||||||
| @@ -427,15 +415,11 @@ func GetLabelInOrgByID(ctx context.Context, orgID, labelID int64) (*Label, error | |||||||
| 		return nil, ErrOrgLabelNotExist{labelID, orgID} | 		return nil, ErrOrgLabelNotExist{labelID, orgID} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	l := &Label{ | 	l, exist, err := db.Get[Label](ctx, builder.Eq{"id": labelID, "org_id": orgID}) | ||||||
| 		ID:    labelID, |  | ||||||
| 		OrgID: orgID, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, l) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrOrgLabelNotExist{l.ID, l.OrgID} | 		return nil, ErrOrgLabelNotExist{labelID, orgID} | ||||||
| 	} | 	} | ||||||
| 	return l, nil | 	return l, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -660,13 +660,10 @@ func GetPullRequestByIssueIDWithNoAttributes(ctx context.Context, issueID int64) | |||||||
|  |  | ||||||
| // GetPullRequestByIssueID returns pull request by given issue ID. | // GetPullRequestByIssueID returns pull request by given issue ID. | ||||||
| func GetPullRequestByIssueID(ctx context.Context, issueID int64) (*PullRequest, error) { | func GetPullRequestByIssueID(ctx context.Context, issueID int64) (*PullRequest, error) { | ||||||
| 	pr := &PullRequest{ | 	pr, exist, err := db.Get[PullRequest](ctx, builder.Eq{"issue_id": issueID}) | ||||||
| 		IssueID: issueID, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, pr) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrPullRequestNotExist{0, issueID, 0, 0, "", ""} | 		return nil, ErrPullRequestNotExist{0, issueID, 0, 0, "", ""} | ||||||
| 	} | 	} | ||||||
| 	return pr, pr.LoadAttributes(ctx) | 	return pr, pr.LoadAttributes(ctx) | ||||||
|   | |||||||
| @@ -162,7 +162,7 @@ func NewTeam(ctx context.Context, t *organization.Team) (err error) { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	has, err := db.GetEngine(ctx).ID(t.OrgID).Get(new(user_model.User)) | 	has, err := db.ExistByID[user_model.User](ctx, t.OrgID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -171,10 +171,10 @@ func NewTeam(ctx context.Context, t *organization.Team) (err error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	t.LowerName = strings.ToLower(t.Name) | 	t.LowerName = strings.ToLower(t.Name) | ||||||
| 	has, err = db.GetEngine(ctx). | 	has, err = db.Exist[organization.Team](ctx, builder.Eq{ | ||||||
| 		Where("org_id=?", t.OrgID). | 		"org_id":     t.OrgID, | ||||||
| 		And("lower_name=?", t.LowerName). | 		"lower_name": t.LowerName, | ||||||
| 		Get(new(organization.Team)) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -232,20 +232,20 @@ func UpdateTeam(ctx context.Context, t *organization.Team, authChanged, includeA | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
| 	sess := db.GetEngine(ctx) |  | ||||||
|  |  | ||||||
| 	t.LowerName = strings.ToLower(t.Name) | 	t.LowerName = strings.ToLower(t.Name) | ||||||
| 	has, err := sess. | 	has, err := db.Exist[organization.Team](ctx, builder.Eq{ | ||||||
| 		Where("org_id=?", t.OrgID). | 		"org_id":     t.OrgID, | ||||||
| 		And("lower_name=?", t.LowerName). | 		"lower_name": t.LowerName, | ||||||
| 		And("id!=?", t.ID). | 	}.And(builder.Neq{"id": t.ID}), | ||||||
| 		Get(new(organization.Team)) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if has { | 	} else if has { | ||||||
| 		return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName} | 		return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
| 	if _, err = sess.ID(t.ID).Cols("name", "lower_name", "description", | 	if _, err = sess.ID(t.ID).Cols("name", "lower_name", "description", | ||||||
| 		"can_create_org_repo", "authorize", "includes_all_repositories").Update(t); err != nil { | 		"can_create_org_repo", "authorize", "includes_all_repositories").Update(t); err != nil { | ||||||
| 		return fmt.Errorf("update: %w", err) | 		return fmt.Errorf("update: %w", err) | ||||||
|   | |||||||
| @@ -16,6 +16,8 @@ import ( | |||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ___________ | // ___________ | ||||||
| @@ -203,14 +205,10 @@ func IsUsableTeamName(name string) error { | |||||||
|  |  | ||||||
| // GetTeam returns team by given team name and organization. | // GetTeam returns team by given team name and organization. | ||||||
| func GetTeam(ctx context.Context, orgID int64, name string) (*Team, error) { | func GetTeam(ctx context.Context, orgID int64, name string) (*Team, error) { | ||||||
| 	t := &Team{ | 	t, exist, err := db.Get[Team](ctx, builder.Eq{"org_id": orgID, "lower_name": strings.ToLower(name)}) | ||||||
| 		OrgID:     orgID, |  | ||||||
| 		LowerName: strings.ToLower(name), |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, t) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrTeamNotExist{orgID, 0, name} | 		return nil, ErrTeamNotExist{orgID, 0, name} | ||||||
| 	} | 	} | ||||||
| 	return t, nil | 	return t, nil | ||||||
|   | |||||||
| @@ -13,6 +13,8 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Access represents the highest access level of a user to the repository. The only access type | // Access represents the highest access level of a user to the repository. The only access type | ||||||
| @@ -51,9 +53,11 @@ func accessLevel(ctx context.Context, user *user_model.User, repo *repo_model.Re | |||||||
| 		return perm.AccessModeOwner, nil | 		return perm.AccessModeOwner, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	a := &Access{UserID: userID, RepoID: repo.ID} | 	a, exist, err := db.Get[Access](ctx, builder.Eq{"user_id": userID, "repo_id": repo.ID}) | ||||||
| 	if has, err := db.GetByBean(ctx, a); !has || err != nil { | 	if err != nil { | ||||||
| 		return mode, err | 		return mode, err | ||||||
|  | 	} else if !exist { | ||||||
|  | 		return mode, nil | ||||||
| 	} | 	} | ||||||
| 	return a.Mode, nil | 	return a.Mode, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,6 +13,8 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting/config" | 	"code.gitea.io/gitea/modules/setting/config" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Setting struct { | type Setting struct { | ||||||
| @@ -36,16 +38,17 @@ func init() { | |||||||
| const keyRevision = "revision" | const keyRevision = "revision" | ||||||
|  |  | ||||||
| func GetRevision(ctx context.Context) int { | func GetRevision(ctx context.Context) int { | ||||||
| 	revision := &Setting{SettingKey: keyRevision} | 	revision, exist, err := db.Get[Setting](ctx, builder.Eq{"setting_key": keyRevision}) | ||||||
| 	if has, err := db.GetByBean(ctx, revision); err != nil { | 	if err != nil { | ||||||
| 		return 0 | 		return 0 | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		err = db.Insert(ctx, &Setting{SettingKey: keyRevision, Version: 1}) | 		err = db.Insert(ctx, &Setting{SettingKey: keyRevision, Version: 1}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return 0 | 			return 0 | ||||||
| 		} | 		} | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} else if revision.Version <= 0 || revision.Version >= math.MaxInt-1 { | 	} | ||||||
|  | 	if revision.Version <= 0 || revision.Version >= math.MaxInt-1 { | ||||||
| 		_, err = db.Exec(ctx, "UPDATE system_setting SET version=1 WHERE setting_key=?", keyRevision) | 		_, err = db.Exec(ctx, "UPDATE system_setting SET version=1 WHERE setting_key=?", keyRevision) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return 0 | 			return 0 | ||||||
|   | |||||||
| @@ -41,14 +41,11 @@ func TestSettings(t *testing.T) { | |||||||
| 	assert.EqualValues(t, "false", settings[keyName]) | 	assert.EqualValues(t, "false", settings[keyName]) | ||||||
|  |  | ||||||
| 	// setting the same value should not trigger DuplicateKey error, and the "version" should be increased | 	// setting the same value should not trigger DuplicateKey error, and the "version" should be increased | ||||||
| 	setting := &system.Setting{SettingKey: keyName} |  | ||||||
| 	_, err = db.GetByBean(db.DefaultContext, setting) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.EqualValues(t, 2, setting.Version) |  | ||||||
| 	err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"}) | 	err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	setting = &system.Setting{SettingKey: keyName} |  | ||||||
| 	_, err = db.GetByBean(db.DefaultContext, setting) | 	rev, settings, err = system.GetAllSettings(db.DefaultContext) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 3, setting.Version) | 	assert.Len(t, settings, 2) | ||||||
|  | 	assert.EqualValues(t, 4, rev) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -527,12 +527,13 @@ func ActivateUserEmail(ctx context.Context, userID int64, email string, activate | |||||||
|  |  | ||||||
| 	// Activate/deactivate a user's secondary email address | 	// Activate/deactivate a user's secondary email address | ||||||
| 	// First check if there's another user active with the same address | 	// First check if there's another user active with the same address | ||||||
| 	addr := EmailAddress{UID: userID, LowerEmail: strings.ToLower(email)} | 	addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)}) | ||||||
| 	if has, err := db.GetByBean(ctx, &addr); err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return fmt.Errorf("no such email: %d (%s)", userID, email) | 		return fmt.Errorf("no such email: %d (%s)", userID, email) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if addr.IsActivated == activate { | 	if addr.IsActivated == activate { | ||||||
| 		// Already in the desired state; no action | 		// Already in the desired state; no action | ||||||
| 		return nil | 		return nil | ||||||
| @@ -544,25 +545,26 @@ func ActivateUserEmail(ctx context.Context, userID int64, email string, activate | |||||||
| 			return ErrEmailAlreadyUsed{Email: email} | 			return ErrEmailAlreadyUsed{Email: email} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if err = updateActivation(ctx, &addr, activate); err != nil { | 	if err = updateActivation(ctx, addr, activate); err != nil { | ||||||
| 		return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err) | 		return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Activate/deactivate a user's primary email address and account | 	// Activate/deactivate a user's primary email address and account | ||||||
| 	if addr.IsPrimary { | 	if addr.IsPrimary { | ||||||
| 		user := User{ID: userID, Email: email} | 		user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID, "email": email}) | ||||||
| 		if has, err := db.GetByBean(ctx, &user); err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} else if !has { | 		} else if !exist { | ||||||
| 			return fmt.Errorf("no user with ID: %d and Email: %s", userID, email) | 			return fmt.Errorf("no user with ID: %d and Email: %s", userID, email) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// The user's activation state should be synchronized with the primary email | 		// The user's activation state should be synchronized with the primary email | ||||||
| 		if user.IsActive != activate { | 		if user.IsActive != activate { | ||||||
| 			user.IsActive = activate | 			user.IsActive = activate | ||||||
| 			if user.Rands, err = GetUserSalt(); err != nil { | 			if user.Rands, err = GetUserSalt(); err != nil { | ||||||
| 				return fmt.Errorf("unable to generate salt: %w", err) | 				return fmt.Errorf("unable to generate salt: %w", err) | ||||||
| 			} | 			} | ||||||
| 			if err = UpdateUserCols(ctx, &user, "is_active", "rands"); err != nil { | 			if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { | ||||||
| 				return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) | 				return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -98,9 +98,10 @@ func GetExternalLogin(ctx context.Context, externalLoginUser *ExternalLoginUser) | |||||||
|  |  | ||||||
| // LinkExternalToUser link the external user to the user | // LinkExternalToUser link the external user to the user | ||||||
| func LinkExternalToUser(ctx context.Context, user *User, externalLoginUser *ExternalLoginUser) error { | func LinkExternalToUser(ctx context.Context, user *User, externalLoginUser *ExternalLoginUser) error { | ||||||
| 	has, err := db.GetEngine(ctx).Where("external_id=? AND login_source_id=?", externalLoginUser.ExternalID, externalLoginUser.LoginSourceID). | 	has, err := db.Exist[ExternalLoginUser](ctx, builder.Eq{ | ||||||
| 		NoAutoCondition(). | 		"external_id":     externalLoginUser.ExternalID, | ||||||
| 		Exist(externalLoginUser) | 		"login_source_id": externalLoginUser.LoginSourceID, | ||||||
|  | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if has { | 	} else if has { | ||||||
| @@ -145,9 +146,10 @@ func GetUserIDByExternalUserID(ctx context.Context, provider, userID string) (in | |||||||
|  |  | ||||||
| // UpdateExternalUserByExternalID updates an external user's information | // UpdateExternalUserByExternalID updates an external user's information | ||||||
| func UpdateExternalUserByExternalID(ctx context.Context, external *ExternalLoginUser) error { | func UpdateExternalUserByExternalID(ctx context.Context, external *ExternalLoginUser) error { | ||||||
| 	has, err := db.GetEngine(ctx).Where("external_id=? AND login_source_id=?", external.ExternalID, external.LoginSourceID). | 	has, err := db.Exist[ExternalLoginUser](ctx, builder.Eq{ | ||||||
| 		NoAutoCondition(). | 		"external_id":     external.ExternalID, | ||||||
| 		Exist(external) | 		"login_source_id": external.LoginSourceID, | ||||||
|  | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if !has { | 	} else if !has { | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	webhook_module "code.gitea.io/gitea/modules/webhook" | 	webhook_module "code.gitea.io/gitea/modules/webhook" | ||||||
|  |  | ||||||
| 	gouuid "github.com/google/uuid" | 	gouuid "github.com/google/uuid" | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| //   ___ ___                __   ___________              __ | //   ___ ___                __   ___________              __ | ||||||
| @@ -150,14 +151,10 @@ func UpdateHookTask(ctx context.Context, t *HookTask) error { | |||||||
|  |  | ||||||
| // ReplayHookTask copies a hook task to get re-delivered | // ReplayHookTask copies a hook task to get re-delivered | ||||||
| func ReplayHookTask(ctx context.Context, hookID int64, uuid string) (*HookTask, error) { | func ReplayHookTask(ctx context.Context, hookID int64, uuid string) (*HookTask, error) { | ||||||
| 	task := &HookTask{ | 	task, exist, err := db.Get[HookTask](ctx, builder.Eq{"hook_id": hookID, "uuid": uuid}) | ||||||
| 		HookID: hookID, |  | ||||||
| 		UUID:   uuid, |  | ||||||
| 	} |  | ||||||
| 	has, err := db.GetByBean(ctx, task) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else if !has { | 	} else if !exist { | ||||||
| 		return nil, ErrHookTaskNotExist{ | 		return nil, ErrHookTaskNotExist{ | ||||||
| 			HookID: hookID, | 			HookID: hookID, | ||||||
| 			UUID:   uuid, | 			UUID:   uuid, | ||||||
|   | |||||||
| @@ -11,24 +11,27 @@ import ( | |||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { | func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { | ||||||
| 	return db.WithTx(ctx, func(ctx context.Context) error { | 	return db.WithTx(ctx, func(ctx context.Context) error { | ||||||
| 		collaboration := &repo_model.Collaboration{ | 		has, err := db.Exist[repo_model.Collaboration](ctx, builder.Eq{ | ||||||
| 			RepoID: repo.ID, | 			"repo_id": repo.ID, | ||||||
| 			UserID: u.ID, | 			"user_id": u.ID, | ||||||
| 		} | 		}) | ||||||
|  |  | ||||||
| 		has, err := db.GetByBean(ctx, collaboration) |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} else if has { | 		} else if has { | ||||||
| 			return nil | 			return nil | ||||||
| 		} | 		} | ||||||
| 		collaboration.Mode = perm.AccessModeWrite |  | ||||||
|  |  | ||||||
| 		if err = db.Insert(ctx, collaboration); err != nil { | 		if err = db.Insert(ctx, &repo_model.Collaboration{ | ||||||
|  | 			RepoID: repo.ID, | ||||||
|  | 			UserID: u.ID, | ||||||
|  | 			Mode:   perm.AccessModeWrite, | ||||||
|  | 		}); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -409,7 +409,7 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re | |||||||
|  |  | ||||||
| 			defer content.Close() | 			defer content.Close() | ||||||
|  |  | ||||||
| 			_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: p, RepositoryID: repo.ID}) | 			_, err := git_model.NewLFSMetaObject(ctx, repo.ID, p) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, p, err) | 				log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, p, err) | ||||||
| 				return err | 				return err | ||||||
| @@ -456,7 +456,7 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re | |||||||
|  |  | ||||||
| 		if exist { | 		if exist { | ||||||
| 			log.Trace("Repo[%-v]: LFS object %-v already present; creating meta object", repo, pointerBlob.Pointer) | 			log.Trace("Repo[%-v]: LFS object %-v already present; creating meta object", repo, pointerBlob.Pointer) | ||||||
| 			_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: pointerBlob.Pointer, RepositoryID: repo.ID}) | 			_, err := git_model.NewLFSMetaObject(ctx, repo.ID, pointerBlob.Pointer) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, pointerBlob.Pointer, err) | 				log.Error("Repo[%-v]: Error creating LFS meta object %-v: %v", repo, pointerBlob.Pointer, err) | ||||||
| 				return err | 				return err | ||||||
|   | |||||||
| @@ -232,7 +232,7 @@ func BatchHandler(ctx *context.Context) { | |||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				if accessible { | 				if accessible { | ||||||
| 					_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: p, RepositoryID: repository.ID}) | 					_, err := git_model.NewLFSMetaObject(ctx, repository.ID, p) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						log.Error("Unable to create LFS MetaObject [%s] for %s/%s. Error: %v", p.Oid, rc.User, rc.Repo, err) | 						log.Error("Unable to create LFS MetaObject [%s] for %s/%s. Error: %v", p.Oid, rc.User, rc.Repo, err) | ||||||
| 						writeStatus(ctx, http.StatusInternalServerError) | 						writeStatus(ctx, http.StatusInternalServerError) | ||||||
| @@ -325,7 +325,7 @@ func UploadHandler(ctx *context.Context) { | |||||||
| 			log.Error("Error putting LFS MetaObject [%s] into content store. Error: %v", p.Oid, err) | 			log.Error("Error putting LFS MetaObject [%s] into content store. Error: %v", p.Oid, err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		_, err := git_model.NewLFSMetaObject(ctx, &git_model.LFSMetaObject{Pointer: p, RepositoryID: repository.ID}) | 		_, err := git_model.NewLFSMetaObject(ctx, repository.ID, p) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -127,9 +127,7 @@ func createLFSMetaObjectsFromCatFileBatch(ctx context.Context, catFileBatchReade | |||||||
| 		// OK we have a pointer that is associated with the head repo | 		// OK we have a pointer that is associated with the head repo | ||||||
| 		// and is actually a file in the LFS | 		// and is actually a file in the LFS | ||||||
| 		// Therefore it should be associated with the base repo | 		// Therefore it should be associated with the base repo | ||||||
| 		meta := &git_model.LFSMetaObject{Pointer: pointer} | 		if _, err := git_model.NewLFSMetaObject(ctx, pr.BaseRepoID, pointer); err != nil { | ||||||
| 		meta.RepositoryID = pr.BaseRepoID |  | ||||||
| 		if _, err := git_model.NewLFSMetaObject(ctx, meta); err != nil { |  | ||||||
| 			_ = catFileBatchReader.CloseWithError(err) | 			_ = catFileBatchReader.CloseWithError(err) | ||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -438,7 +438,7 @@ func CreateOrUpdateFile(ctx context.Context, t *TemporaryUploadRepository, file | |||||||
|  |  | ||||||
| 	if lfsMetaObject != nil { | 	if lfsMetaObject != nil { | ||||||
| 		// We have an LFS object - create it | 		// We have an LFS object - create it | ||||||
| 		lfsMetaObject, err = git_model.NewLFSMetaObject(ctx, lfsMetaObject) | 		lfsMetaObject, err = git_model.NewLFSMetaObject(ctx, lfsMetaObject.RepositoryID, lfsMetaObject.Pointer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -143,7 +143,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use | |||||||
| 		if infos[i].lfsMetaObject == nil { | 		if infos[i].lfsMetaObject == nil { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		infos[i].lfsMetaObject, err = git_model.NewLFSMetaObject(ctx, infos[i].lfsMetaObject) | 		infos[i].lfsMetaObject, err = git_model.NewLFSMetaObject(ctx, infos[i].lfsMetaObject.RepositoryID, infos[i].lfsMetaObject.Pointer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			// OK Now we need to cleanup | 			// OK Now we need to cleanup | ||||||
| 			return cleanUpAfterFailure(ctx, &infos, t, err) | 			return cleanUpAfterFailure(ctx, &infos, t, err) | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string | |||||||
| 	pointer, err := lfs.GeneratePointer(bytes.NewReader(*content)) | 	pointer, err := lfs.GeneratePointer(bytes.NewReader(*content)) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	_, err = git_model.NewLFSMetaObject(db.DefaultContext, &git_model.LFSMetaObject{Pointer: pointer, RepositoryID: repositoryID}) | 	_, err = git_model.NewLFSMetaObject(db.DefaultContext, repositoryID, pointer) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	contentStore := lfs.NewContentStore() | 	contentStore := lfs.NewContentStore() | ||||||
| 	exist, err := contentStore.Exists(pointer) | 	exist, err := contentStore.Exists(pointer) | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string | |||||||
| 	pointer, err := lfs.GeneratePointer(bytes.NewReader(*content)) | 	pointer, err := lfs.GeneratePointer(bytes.NewReader(*content)) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	_, err = git_model.NewLFSMetaObject(db.DefaultContext, &git_model.LFSMetaObject{Pointer: pointer, RepositoryID: repositoryID}) | 	_, err = git_model.NewLFSMetaObject(db.DefaultContext, repositoryID, pointer) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	contentStore := lfs.NewContentStore() | 	contentStore := lfs.NewContentStore() | ||||||
| 	exist, err := contentStore.Exists(pointer) | 	exist, err := contentStore.Exists(pointer) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user