Compare commits

..

6 Commits

Author SHA1 Message Date
GiteaBot
f8a1094406 [skip ci] Updated translations via Crowdin 2023-09-15 00:22:32 +00:00
JakobDev
76659b1114
Reduce usage of db.DefaultContext (#27073)
Part of #27065

This reduces the usage of `db.DefaultContext`. I think I've got enough
files for the first PR. When this is merged, I will continue working on
this.

Considering how many files this PR affect, I hope it won't take to long
to merge, so I don't end up in the merge conflict hell.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-09-14 17:09:32 +00:00
Nanguan Lin
0de09d3afc
Remove the useless function GetUserIssueStats and move relevant tests to indexer_test.go (#27067)
Since the issue indexer has been refactored, the issue overview webpage
is built by the `buildIssueOverview` function and underlying
`indexer.Search` function and `GetIssueStats` instead of
`GetUserIssueStats`. So the function is no longer used.
I moved the relevant tests to `indexer_test.go` and since the search
option changed from `IssueOptions` to `SearchOptions`, most of the tests
are useless now.
We need more tests about the db indexer because those tests are highly
connected with the issue overview webpage and now this page has several
bugs.
Any advice about those test cases is appreciated.

---------

Co-authored-by: CaiCandong <50507092+CaiCandong@users.noreply.github.com>
2023-09-14 12:35:53 -04:00
JakobDev
8d0343e028
Fix issue templates when blank isses are disabled (#27061)
Fixes #27060

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: delvh <dev.lh@web.de>
2023-09-14 14:20:16 +00:00
Lunny Xiao
198a9ca635
Display all user types and org types on admin management UI (#27050)
Follow #24026 

<img width="1049" alt="图片"
src="https://github.com/go-gitea/gitea/assets/81045/d3fc5159-b5e7-411a-b6f8-4a111a027e6b">

---------

Co-authored-by: delvh <dev.lh@web.de>
2023-09-14 06:53:36 +00:00
Nanguan Lin
a457eb9415
Apply lng2020 to maintainers (#27068)
Hi all,

I've very much enjoyed working on Gitea and was hoping to make it
official by requesting maintainership. 

My [merged PRs
list](https://github.com/go-gitea/gitea/pulls?q=is%3Apr+sort%3Aupdated-desc+author%3Alng2020+is%3Amerged)
2023-09-14 12:10:12 +08:00
92 changed files with 472 additions and 654 deletions

View File

@ -56,3 +56,4 @@ Denys Konovalov <kontakt@denyskon.de> (@denyskon)
Punit Inani <punitinani1@gmail.com> (@puni9869) Punit Inani <punitinani1@gmail.com> (@puni9869)
CaiCandong <1290147055@qq.com> (@caicandong) CaiCandong <1290147055@qq.com> (@caicandong)
Rui Chen <rui@chenrui.dev> (@chenrui333) Rui Chen <rui@chenrui.dev> (@chenrui333)
Nanguan Lin <nanguanlin6@gmail.com> (@lng2020)

View File

@ -115,7 +115,7 @@ func runCreateUser(c *cli.Context) error {
// If this is the first user being created. // If this is the first user being created.
// Take it as the admin and don't force a password update. // Take it as the admin and don't force a password update.
if n := user_model.CountUsers(nil); n == 0 { if n := user_model.CountUsers(ctx, nil); n == 0 {
changePassword = false changePassword = false
} }
@ -146,7 +146,7 @@ func runCreateUser(c *cli.Context) error {
IsRestricted: restricted, IsRestricted: restricted,
} }
if err := user_model.CreateUser(u, overwriteDefault); err != nil { if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
return fmt.Errorf("CreateUser: %w", err) return fmt.Errorf("CreateUser: %w", err)
} }

View File

@ -33,7 +33,7 @@ func runListUsers(c *cli.Context) error {
return err return err
} }
users, err := user_model.GetAllUsers() users, err := user_model.GetAllUsers(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -48,7 +48,7 @@ func runListUsers(c *cli.Context) error {
} }
} }
} else { } else {
twofa := user_model.UserList(users).GetTwoFaStatus() twofa := user_model.UserList(users).GetTwoFaStatus(ctx)
fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\t2FA\n") fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\t2FA\n")
for _, u := range users { for _, u := range users {
fmt.Fprintf(w, "%d\t%s\t%s\t%t\t%t\t%t\n", u.ID, u.Name, u.Email, u.IsActive, u.IsAdmin, twofa[u.ID]) fmt.Fprintf(w, "%d\t%s\t%s\t%t\t%t\t%t\n", u.ID, u.Name, u.Email, u.IsActive, u.IsAdmin, twofa[u.ID])

View File

@ -4,6 +4,8 @@
package activities package activities
import ( import (
"context"
asymkey_model "code.gitea.io/gitea/models/asymkey" asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -47,12 +49,12 @@ type IssueByRepositoryCount struct {
} }
// GetStatistic returns the database statistics // GetStatistic returns the database statistics
func GetStatistic() (stats Statistic) { func GetStatistic(ctx context.Context) (stats Statistic) {
e := db.GetEngine(db.DefaultContext) e := db.GetEngine(ctx)
stats.Counter.User = user_model.CountUsers(nil) stats.Counter.User = user_model.CountUsers(ctx, nil)
stats.Counter.Org, _ = organization.CountOrgs(organization.FindOrgOptions{IncludePrivate: true}) stats.Counter.Org, _ = organization.CountOrgs(organization.FindOrgOptions{IncludePrivate: true})
stats.Counter.PublicKey, _ = e.Count(new(asymkey_model.PublicKey)) stats.Counter.PublicKey, _ = e.Count(new(asymkey_model.PublicKey))
stats.Counter.Repo, _ = repo_model.CountRepositories(db.DefaultContext, repo_model.CountRepositoryOptions{}) stats.Counter.Repo, _ = repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{})
stats.Counter.Watch, _ = e.Count(new(repo_model.Watch)) stats.Counter.Watch, _ = e.Count(new(repo_model.Watch))
stats.Counter.Star, _ = e.Count(new(repo_model.Star)) stats.Counter.Star, _ = e.Count(new(repo_model.Star))
stats.Counter.Access, _ = e.Count(new(access_model.Access)) stats.Counter.Access, _ = e.Count(new(access_model.Access))

View File

@ -144,7 +144,7 @@ func parseSubGPGKey(ownerID int64, primaryID string, pubkey *packet.PublicKey, e
} }
// parseGPGKey parse a PrimaryKey entity (primary key + subs keys + self-signature) // parseGPGKey parse a PrimaryKey entity (primary key + subs keys + self-signature)
func parseGPGKey(ownerID int64, e *openpgp.Entity, verified bool) (*GPGKey, error) { func parseGPGKey(ctx context.Context, ownerID int64, e *openpgp.Entity, verified bool) (*GPGKey, error) {
pubkey := e.PrimaryKey pubkey := e.PrimaryKey
expiry := getExpiryTime(e) expiry := getExpiryTime(e)
@ -159,7 +159,7 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity, verified bool) (*GPGKey, erro
} }
// Check emails // Check emails
userEmails, err := user_model.GetEmailAddresses(ownerID) userEmails, err := user_model.GetEmailAddresses(ctx, ownerID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -251,7 +251,7 @@ func DeleteGPGKey(doer *user_model.User, id int64) (err error) {
return committer.Commit() return committer.Commit()
} }
func checkKeyEmails(email string, keys ...*GPGKey) (bool, string) { func checkKeyEmails(ctx context.Context, email string, keys ...*GPGKey) (bool, string) {
uid := int64(0) uid := int64(0)
var userEmails []*user_model.EmailAddress var userEmails []*user_model.EmailAddress
var user *user_model.User var user *user_model.User
@ -263,10 +263,10 @@ func checkKeyEmails(email string, keys ...*GPGKey) (bool, string) {
} }
if key.Verified && key.OwnerID != 0 { if key.Verified && key.OwnerID != 0 {
if uid != key.OwnerID { if uid != key.OwnerID {
userEmails, _ = user_model.GetEmailAddresses(key.OwnerID) userEmails, _ = user_model.GetEmailAddresses(ctx, key.OwnerID)
uid = key.OwnerID uid = key.OwnerID
user = &user_model.User{ID: uid} user = &user_model.User{ID: uid}
_, _ = user_model.GetUser(user) _, _ = user_model.GetUser(ctx, user)
} }
for _, e := range userEmails { for _, e := range userEmails {
if e.IsActivated && (email == "" || strings.EqualFold(e.Email, email)) { if e.IsActivated && (email == "" || strings.EqualFold(e.Email, email)) {

View File

@ -153,7 +153,7 @@ func AddGPGKey(ownerID int64, content, token, signature string) ([]*GPGKey, erro
// Get DB session // Get DB session
key, err := parseGPGKey(ownerID, ekey, verified) key, err := parseGPGKey(ctx, ownerID, ekey, verified)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -125,7 +125,7 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
// If this a SSH signature handle it differently // If this a SSH signature handle it differently
if strings.HasPrefix(c.Signature.Signature, "-----BEGIN SSH SIGNATURE-----") { if strings.HasPrefix(c.Signature.Signature, "-----BEGIN SSH SIGNATURE-----") {
return ParseCommitWithSSHSignature(c, committer) return ParseCommitWithSSHSignature(ctx, c, committer)
} }
// Parsing signature // Parsing signature
@ -150,6 +150,7 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
// First check if the sig has a keyID and if so just look at that // First check if the sig has a keyID and if so just look at that
if commitVerification := hashAndVerifyForKeyID( if commitVerification := hashAndVerifyForKeyID(
ctx,
sig, sig,
c.Signature.Payload, c.Signature.Payload,
committer, committer,
@ -165,7 +166,7 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
// Now try to associate the signature with the committer, if present // Now try to associate the signature with the committer, if present
if committer.ID != 0 { if committer.ID != 0 {
keys, err := ListGPGKeys(db.DefaultContext, committer.ID, db.ListOptions{}) keys, err := ListGPGKeys(ctx, committer.ID, db.ListOptions{})
if err != nil { // Skipping failed to get gpg keys of user if err != nil { // Skipping failed to get gpg keys of user
log.Error("ListGPGKeys: %v", err) log.Error("ListGPGKeys: %v", err)
return &CommitVerification{ return &CommitVerification{
@ -175,7 +176,7 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
} }
} }
committerEmailAddresses, _ := user_model.GetEmailAddresses(committer.ID) committerEmailAddresses, _ := user_model.GetEmailAddresses(ctx, committer.ID)
activated := false activated := false
for _, e := range committerEmailAddresses { for _, e := range committerEmailAddresses {
if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) { if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) {
@ -222,7 +223,7 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
} }
if err := gpgSettings.LoadPublicKeyContent(); err != nil { if err := gpgSettings.LoadPublicKeyContent(); err != nil {
log.Error("Error getting default signing key: %s %v", gpgSettings.KeyID, err) log.Error("Error getting default signing key: %s %v", gpgSettings.KeyID, err)
} else if commitVerification := verifyWithGPGSettings(&gpgSettings, sig, c.Signature.Payload, committer, keyID); commitVerification != nil { } else if commitVerification := verifyWithGPGSettings(ctx, &gpgSettings, sig, c.Signature.Payload, committer, keyID); commitVerification != nil {
if commitVerification.Reason == BadSignature { if commitVerification.Reason == BadSignature {
defaultReason = BadSignature defaultReason = BadSignature
} else { } else {
@ -237,7 +238,7 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
} else if defaultGPGSettings == nil { } else if defaultGPGSettings == nil {
log.Warn("Unable to get defaultGPGSettings for unattached commit: %s", c.ID.String()) log.Warn("Unable to get defaultGPGSettings for unattached commit: %s", c.ID.String())
} else if defaultGPGSettings.Sign { } else if defaultGPGSettings.Sign {
if commitVerification := verifyWithGPGSettings(defaultGPGSettings, sig, c.Signature.Payload, committer, keyID); commitVerification != nil { if commitVerification := verifyWithGPGSettings(ctx, defaultGPGSettings, sig, c.Signature.Payload, committer, keyID); commitVerification != nil {
if commitVerification.Reason == BadSignature { if commitVerification.Reason == BadSignature {
defaultReason = BadSignature defaultReason = BadSignature
} else { } else {
@ -257,9 +258,9 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
} }
} }
func verifyWithGPGSettings(gpgSettings *git.GPGSettings, sig *packet.Signature, payload string, committer *user_model.User, keyID string) *CommitVerification { func verifyWithGPGSettings(ctx context.Context, gpgSettings *git.GPGSettings, sig *packet.Signature, payload string, committer *user_model.User, keyID string) *CommitVerification {
// First try to find the key in the db // First try to find the key in the db
if commitVerification := hashAndVerifyForKeyID(sig, payload, committer, gpgSettings.KeyID, gpgSettings.Name, gpgSettings.Email); commitVerification != nil { if commitVerification := hashAndVerifyForKeyID(ctx, sig, payload, committer, gpgSettings.KeyID, gpgSettings.Name, gpgSettings.Email); commitVerification != nil {
return commitVerification return commitVerification
} }
@ -387,7 +388,7 @@ func hashAndVerifyWithSubKeysCommitVerification(sig *packet.Signature, payload s
return nil return nil
} }
func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *user_model.User, keyID, name, email string) *CommitVerification { func hashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload string, committer *user_model.User, keyID, name, email string) *CommitVerification {
if keyID == "" { if keyID == "" {
return nil return nil
} }
@ -417,7 +418,7 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
} }
} }
activated, email := checkKeyEmails(email, append([]*GPGKey{key}, primaryKeys...)...) activated, email := checkKeyEmails(ctx, email, append([]*GPGKey{key}, primaryKeys...)...)
if !activated { if !activated {
continue continue
} }
@ -427,7 +428,7 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
Email: email, Email: email,
} }
if key.OwnerID != 0 { if key.OwnerID != 0 {
owner, err := user_model.GetUserByID(db.DefaultContext, key.OwnerID) owner, err := user_model.GetUserByID(ctx, key.OwnerID)
if err == nil { if err == nil {
signer = owner signer = owner
} else if !user_model.IsErrUserNotExist(err) { } else if !user_model.IsErrUserNotExist(err) {

View File

@ -5,6 +5,7 @@ package asymkey
import ( import (
"bytes" "bytes"
"context"
"fmt" "fmt"
"strings" "strings"
@ -17,7 +18,7 @@ import (
) )
// ParseCommitWithSSHSignature check if signature is good against keystore. // ParseCommitWithSSHSignature check if signature is good against keystore.
func ParseCommitWithSSHSignature(c *git.Commit, committer *user_model.User) *CommitVerification { func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *user_model.User) *CommitVerification {
// Now try to associate the signature with the committer, if present // Now try to associate the signature with the committer, if present
if committer.ID != 0 { if committer.ID != 0 {
keys, err := ListPublicKeys(committer.ID, db.ListOptions{}) keys, err := ListPublicKeys(committer.ID, db.ListOptions{})
@ -30,7 +31,7 @@ func ParseCommitWithSSHSignature(c *git.Commit, committer *user_model.User) *Com
} }
} }
committerEmailAddresses, err := user_model.GetEmailAddresses(committer.ID) committerEmailAddresses, err := user_model.GetEmailAddresses(ctx, committer.ID)
if err != nil { if err != nil {
log.Error("GetEmailAddresses: %v", err) log.Error("GetEmailAddresses: %v", err)
} }

View File

@ -4,6 +4,7 @@
package asymkey package asymkey
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
@ -63,7 +64,7 @@ func AddPrincipalKey(ownerID int64, content string, authSourceID int64) (*Public
} }
// CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines // CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
func CheckPrincipalKeyString(user *user_model.User, content string) (_ string, err error) { func CheckPrincipalKeyString(ctx context.Context, user *user_model.User, content string) (_ string, err error) {
if setting.SSH.Disabled { if setting.SSH.Disabled {
return "", db.ErrSSHDisabled{} return "", db.ErrSSHDisabled{}
} }
@ -80,7 +81,7 @@ func CheckPrincipalKeyString(user *user_model.User, content string) (_ string, e
case "anything": case "anything":
return content, nil return content, nil
case "email": case "email":
emails, err := user_model.GetEmailAddresses(user.ID) emails, err := user_model.GetEmailAddresses(ctx, user.ID)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -5,7 +5,6 @@ package issues
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -181,195 +180,6 @@ func applyIssuesOptions(sess *xorm.Session, opts *IssuesOptions, issueIDs []int6
return sess return sess
} }
// GetUserIssueStats returns issue statistic information for dashboard by given conditions.
func GetUserIssueStats(filterMode int, opts IssuesOptions) (*IssueStats, error) {
if opts.User == nil {
return nil, errors.New("issue stats without user")
}
if opts.IsPull.IsNone() {
return nil, errors.New("unaccepted ispull option")
}
var err error
stats := &IssueStats{}
cond := builder.NewCond()
cond = cond.And(builder.Eq{"issue.is_pull": opts.IsPull.IsTrue()})
if len(opts.RepoIDs) > 0 {
cond = cond.And(builder.In("issue.repo_id", opts.RepoIDs))
}
if len(opts.IssueIDs) > 0 {
cond = cond.And(builder.In("issue.id", opts.IssueIDs))
}
if opts.RepoCond != nil {
cond = cond.And(opts.RepoCond)
}
if opts.User != nil {
cond = cond.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.IsTrue()))
}
sess := func(cond builder.Cond) *xorm.Session {
s := db.GetEngine(db.DefaultContext).
Join("INNER", "repository", "`issue`.repo_id = `repository`.id").
Where(cond)
if len(opts.LabelIDs) > 0 {
s.Join("INNER", "issue_label", "issue_label.issue_id = issue.id").
In("issue_label.label_id", opts.LabelIDs)
}
if opts.IsArchived != util.OptionalBoolNone {
s.And(builder.Eq{"repository.is_archived": opts.IsArchived.IsTrue()})
}
return s
}
switch filterMode {
case FilterModeAll, FilterModeYourRepositories:
stats.OpenCount, err = sess(cond).
And("issue.is_closed = ?", false).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = sess(cond).
And("issue.is_closed = ?", true).
Count(new(Issue))
if err != nil {
return nil, err
}
case FilterModeAssign:
stats.OpenCount, err = applyAssigneeCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", false).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = applyAssigneeCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", true).
Count(new(Issue))
if err != nil {
return nil, err
}
case FilterModeCreate:
stats.OpenCount, err = applyPosterCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", false).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = applyPosterCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", true).
Count(new(Issue))
if err != nil {
return nil, err
}
case FilterModeMention:
stats.OpenCount, err = applyMentionedCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", false).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = applyMentionedCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", true).
Count(new(Issue))
if err != nil {
return nil, err
}
case FilterModeReviewRequested:
stats.OpenCount, err = applyReviewRequestedCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", false).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = applyReviewRequestedCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", true).
Count(new(Issue))
if err != nil {
return nil, err
}
case FilterModeReviewed:
stats.OpenCount, err = applyReviewedCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", false).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = applyReviewedCondition(sess(cond), opts.User.ID).
And("issue.is_closed = ?", true).
Count(new(Issue))
if err != nil {
return nil, err
}
}
cond = cond.And(builder.Eq{"issue.is_closed": opts.IsClosed.IsTrue()})
stats.AssignCount, err = applyAssigneeCondition(sess(cond), opts.User.ID).Count(new(Issue))
if err != nil {
return nil, err
}
stats.CreateCount, err = applyPosterCondition(sess(cond), opts.User.ID).Count(new(Issue))
if err != nil {
return nil, err
}
stats.MentionCount, err = applyMentionedCondition(sess(cond), opts.User.ID).Count(new(Issue))
if err != nil {
return nil, err
}
stats.YourRepositoriesCount, err = sess(cond).Count(new(Issue))
if err != nil {
return nil, err
}
stats.ReviewRequestedCount, err = applyReviewRequestedCondition(sess(cond), opts.User.ID).Count(new(Issue))
if err != nil {
return nil, err
}
stats.ReviewedCount, err = applyReviewedCondition(sess(cond), opts.User.ID).Count(new(Issue))
if err != nil {
return nil, err
}
return stats, nil
}
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen, numClosed int64) {
countSession := func(isClosed, isPull bool, repoID int64) *xorm.Session {
sess := db.GetEngine(db.DefaultContext).
Where("is_closed = ?", isClosed).
And("is_pull = ?", isPull).
And("repo_id = ?", repoID)
return sess
}
openCountSession := countSession(false, isPull, repoID)
closedCountSession := countSession(true, isPull, repoID)
switch filterMode {
case FilterModeAssign:
applyAssigneeCondition(openCountSession, uid)
applyAssigneeCondition(closedCountSession, uid)
case FilterModeCreate:
applyPosterCondition(openCountSession, uid)
applyPosterCondition(closedCountSession, uid)
}
openResult, _ := openCountSession.Count(new(Issue))
closedResult, _ := closedCountSession.Count(new(Issue))
return openResult, closedResult
}
// CountOrphanedIssues count issues without a repo // CountOrphanedIssues count issues without a repo
func CountOrphanedIssues(ctx context.Context) (int64, error) { func CountOrphanedIssues(ctx context.Context) (int64, error) {
return db.GetEngine(ctx). return db.GetEngine(ctx).

View File

@ -13,12 +13,10 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"xorm.io/builder" "xorm.io/builder"
@ -204,128 +202,6 @@ func TestIssues(t *testing.T) {
} }
} }
func TestGetUserIssueStats(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
for _, test := range []struct {
FilterMode int
Opts issues_model.IssuesOptions
ExpectedIssueStats issues_model.IssueStats
}{
{
issues_model.FilterModeAll,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}),
RepoIDs: []int64{1},
IsPull: util.OptionalBoolFalse,
},
issues_model.IssueStats{
YourRepositoriesCount: 1, // 6
AssignCount: 1, // 6
CreateCount: 1, // 6
OpenCount: 1, // 6
ClosedCount: 1, // 1
},
},
{
issues_model.FilterModeAll,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}),
RepoIDs: []int64{1},
IsPull: util.OptionalBoolFalse,
IsClosed: util.OptionalBoolTrue,
},
issues_model.IssueStats{
YourRepositoriesCount: 1, // 6
AssignCount: 0,
CreateCount: 0,
OpenCount: 1, // 6
ClosedCount: 1, // 1
},
},
{
issues_model.FilterModeAssign,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}),
IsPull: util.OptionalBoolFalse,
},
issues_model.IssueStats{
YourRepositoriesCount: 1, // 6
AssignCount: 1, // 6
CreateCount: 1, // 6
OpenCount: 1, // 6
ClosedCount: 0,
},
},
{
issues_model.FilterModeCreate,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}),
IsPull: util.OptionalBoolFalse,
},
issues_model.IssueStats{
YourRepositoriesCount: 1, // 6
AssignCount: 1, // 6
CreateCount: 1, // 6
OpenCount: 1, // 6
ClosedCount: 0,
},
},
{
issues_model.FilterModeMention,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}),
IsPull: util.OptionalBoolFalse,
},
issues_model.IssueStats{
YourRepositoriesCount: 1, // 6
AssignCount: 1, // 6
CreateCount: 1, // 6
MentionCount: 0,
OpenCount: 0,
ClosedCount: 0,
},
},
{
issues_model.FilterModeCreate,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}),
IssueIDs: []int64{1},
IsPull: util.OptionalBoolFalse,
},
issues_model.IssueStats{
YourRepositoriesCount: 1, // 1
AssignCount: 1, // 1
CreateCount: 1, // 1
OpenCount: 1, // 1
ClosedCount: 0,
},
},
{
issues_model.FilterModeAll,
issues_model.IssuesOptions{
User: unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}),
Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}),
Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}),
IsPull: util.OptionalBoolFalse,
},
issues_model.IssueStats{
YourRepositoriesCount: 2,
AssignCount: 1,
CreateCount: 1,
OpenCount: 2,
},
},
} {
t.Run(fmt.Sprintf("%#v", test.Opts), func(t *testing.T) {
stats, err := issues_model.GetUserIssueStats(test.FilterMode, test.Opts)
if !assert.NoError(t, err) {
return
}
assert.Equal(t, test.ExpectedIssueStats, *stats)
})
}
}
func TestIssue_loadTotalTimes(t *testing.T) { func TestIssue_loadTotalTimes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
ms, err := issues_model.GetIssueByID(db.DefaultContext, 2) ms, err := issues_model.GetIssueByID(db.DefaultContext, 2)

View File

@ -73,8 +73,8 @@ func addAllRepositories(ctx context.Context, t *organization.Team) error {
} }
// AddAllRepositories adds all repositories to the team // AddAllRepositories adds all repositories to the team
func AddAllRepositories(t *organization.Team) (err error) { func AddAllRepositories(ctx context.Context, t *organization.Team) (err error) {
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -88,12 +88,12 @@ func AddAllRepositories(t *organization.Team) (err error) {
} }
// RemoveAllRepositories removes all repositories from team and recalculates access // RemoveAllRepositories removes all repositories from team and recalculates access
func RemoveAllRepositories(t *organization.Team) (err error) { func RemoveAllRepositories(ctx context.Context, t *organization.Team) (err error) {
if t.IncludesAllRepositories { if t.IncludesAllRepositories {
return nil return nil
} }
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -153,7 +153,7 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error
// NewTeam creates a record of new team. // NewTeam creates a record of new team.
// It's caller's responsibility to assign organization ID. // It's caller's responsibility to assign organization ID.
func NewTeam(t *organization.Team) (err error) { func NewTeam(ctx context.Context, t *organization.Team) (err error) {
if len(t.Name) == 0 { if len(t.Name) == 0 {
return util.NewInvalidArgumentErrorf("empty team name") return util.NewInvalidArgumentErrorf("empty team name")
} }
@ -162,7 +162,7 @@ func NewTeam(t *organization.Team) (err error) {
return err return err
} }
has, err := db.GetEngine(db.DefaultContext).ID(t.OrgID).Get(new(user_model.User)) has, err := db.GetEngine(ctx).ID(t.OrgID).Get(new(user_model.User))
if err != nil { if err != nil {
return err return err
} }
@ -171,7 +171,7 @@ func NewTeam(t *organization.Team) (err error) {
} }
t.LowerName = strings.ToLower(t.Name) t.LowerName = strings.ToLower(t.Name)
has, err = db.GetEngine(db.DefaultContext). has, err = db.GetEngine(ctx).
Where("org_id=?", t.OrgID). Where("org_id=?", t.OrgID).
And("lower_name=?", t.LowerName). And("lower_name=?", t.LowerName).
Get(new(organization.Team)) Get(new(organization.Team))
@ -182,7 +182,7 @@ func NewTeam(t *organization.Team) (err error) {
return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName} return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName}
} }
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -218,7 +218,7 @@ func NewTeam(t *organization.Team) (err error) {
} }
// UpdateTeam updates information of team. // UpdateTeam updates information of team.
func UpdateTeam(t *organization.Team, authChanged, includeAllChanged bool) (err error) { func UpdateTeam(ctx context.Context, t *organization.Team, authChanged, includeAllChanged bool) (err error) {
if len(t.Name) == 0 { if len(t.Name) == 0 {
return util.NewInvalidArgumentErrorf("empty team name") return util.NewInvalidArgumentErrorf("empty team name")
} }
@ -227,7 +227,7 @@ func UpdateTeam(t *organization.Team, authChanged, includeAllChanged bool) (err
t.Description = t.Description[:255] t.Description = t.Description[:255]
} }
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -293,8 +293,8 @@ func UpdateTeam(t *organization.Team, authChanged, includeAllChanged bool) (err
// DeleteTeam deletes given team. // DeleteTeam deletes given team.
// It's caller's responsibility to assign organization ID. // It's caller's responsibility to assign organization ID.
func DeleteTeam(t *organization.Team) error { func DeleteTeam(ctx context.Context, t *organization.Team) error {
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -356,8 +356,8 @@ func DeleteTeam(t *organization.Team) error {
// AddTeamMember adds new membership of given team to given organization, // AddTeamMember adds new membership of given team to given organization,
// the user will have membership to given organization automatically when needed. // the user will have membership to given organization automatically when needed.
func AddTeamMember(team *organization.Team, userID int64) error { func AddTeamMember(ctx context.Context, team *organization.Team, userID int64) error {
isAlreadyMember, err := organization.IsTeamMember(db.DefaultContext, team.OrgID, team.ID, userID) isAlreadyMember, err := organization.IsTeamMember(ctx, team.OrgID, team.ID, userID)
if err != nil || isAlreadyMember { if err != nil || isAlreadyMember {
return err return err
} }
@ -366,7 +366,7 @@ func AddTeamMember(team *organization.Team, userID int64) error {
return err return err
} }
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -423,18 +423,14 @@ func AddTeamMember(team *organization.Team, userID int64) error {
} }
} }
if err := committer.Commit(); err != nil {
return err
}
committer.Close()
// this behaviour may spend much time so run it in a goroutine // this behaviour may spend much time so run it in a goroutine
// FIXME: Update watch repos batchly // FIXME: Update watch repos batchly
if setting.Service.AutoWatchNewRepos { if setting.Service.AutoWatchNewRepos {
// Get team and its repositories. // Get team and its repositories.
if err := team.LoadRepositories(db.DefaultContext); err != nil { if err := team.LoadRepositories(ctx); err != nil {
log.Error("getRepositories failed: %v", err) log.Error("getRepositories failed: %v", err)
} }
// FIXME: in the goroutine, it can't access the "ctx", it could only use db.DefaultContext at the moment
go func(repos []*repo_model.Repository) { go func(repos []*repo_model.Repository) {
for _, repo := range repos { for _, repo := range repos {
if err = repo_model.WatchRepo(db.DefaultContext, userID, repo.ID, true); err != nil { if err = repo_model.WatchRepo(db.DefaultContext, userID, repo.ID, true); err != nil {
@ -444,7 +440,7 @@ func AddTeamMember(team *organization.Team, userID int64) error {
}(team.Repos) }(team.Repos)
} }
return nil return committer.Commit()
} }
func removeTeamMember(ctx context.Context, team *organization.Team, userID int64) error { func removeTeamMember(ctx context.Context, team *organization.Team, userID int64) error {
@ -512,8 +508,8 @@ func removeInvalidOrgUser(ctx context.Context, userID, orgID int64) error {
} }
// RemoveTeamMember removes member from given team of given organization. // RemoveTeamMember removes member from given team of given organization.
func RemoveTeamMember(team *organization.Team, userID int64) error { func RemoveTeamMember(ctx context.Context, team *organization.Team, userID int64) error {
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -23,7 +23,7 @@ func TestTeam_AddMember(t *testing.T) {
test := func(teamID, userID int64) { test := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, AddTeamMember(team, userID)) assert.NoError(t, AddTeamMember(db.DefaultContext, team, userID))
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID})
} }
@ -37,7 +37,7 @@ func TestTeam_RemoveMember(t *testing.T) {
testSuccess := func(teamID, userID int64) { testSuccess := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, RemoveTeamMember(team, userID)) assert.NoError(t, RemoveTeamMember(db.DefaultContext, team, userID))
unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID})
} }
@ -47,7 +47,7 @@ func TestTeam_RemoveMember(t *testing.T) {
testSuccess(3, unittest.NonexistentID) testSuccess(3, unittest.NonexistentID)
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
err := RemoveTeamMember(team, 2) err := RemoveTeamMember(db.DefaultContext, team, 2)
assert.True(t, organization.IsErrLastOrgOwner(err)) assert.True(t, organization.IsErrLastOrgOwner(err))
} }
@ -61,7 +61,7 @@ func TestNewTeam(t *testing.T) {
const teamName = "newTeamName" const teamName = "newTeamName"
team := &organization.Team{Name: teamName, OrgID: 3} team := &organization.Team{Name: teamName, OrgID: 3}
assert.NoError(t, NewTeam(team)) assert.NoError(t, NewTeam(db.DefaultContext, team))
unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: teamName}) unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: teamName})
unittest.CheckConsistencyFor(t, &organization.Team{}, &user_model.User{ID: team.OrgID}) unittest.CheckConsistencyFor(t, &organization.Team{}, &user_model.User{ID: team.OrgID})
} }
@ -75,7 +75,7 @@ func TestUpdateTeam(t *testing.T) {
team.Name = "newName" team.Name = "newName"
team.Description = strings.Repeat("A long description!", 100) team.Description = strings.Repeat("A long description!", 100)
team.AccessMode = perm.AccessModeAdmin team.AccessMode = perm.AccessModeAdmin
assert.NoError(t, UpdateTeam(team, true, false)) assert.NoError(t, UpdateTeam(db.DefaultContext, team, true, false))
team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}) team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"})
assert.True(t, strings.HasPrefix(team.Description, "A long description!")) assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
@ -94,7 +94,7 @@ func TestUpdateTeam2(t *testing.T) {
team.LowerName = "owners" team.LowerName = "owners"
team.Name = "Owners" team.Name = "Owners"
team.Description = strings.Repeat("A long description!", 100) team.Description = strings.Repeat("A long description!", 100)
err := UpdateTeam(team, true, false) err := UpdateTeam(db.DefaultContext, team, true, false)
assert.True(t, organization.IsErrTeamAlreadyExist(err)) assert.True(t, organization.IsErrTeamAlreadyExist(err))
unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
@ -104,7 +104,7 @@ func TestDeleteTeam(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
assert.NoError(t, DeleteTeam(team)) assert.NoError(t, DeleteTeam(db.DefaultContext, team))
unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID}) unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID})
unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID}) unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID})
unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID})
@ -122,7 +122,7 @@ func TestAddTeamMember(t *testing.T) {
test := func(teamID, userID int64) { test := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, AddTeamMember(team, userID)) assert.NoError(t, AddTeamMember(db.DefaultContext, team, userID))
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID})
} }
@ -136,7 +136,7 @@ func TestRemoveTeamMember(t *testing.T) {
testSuccess := func(teamID, userID int64) { testSuccess := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, RemoveTeamMember(team, userID)) assert.NoError(t, RemoveTeamMember(db.DefaultContext, team, userID))
unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID})
} }
@ -146,7 +146,7 @@ func TestRemoveTeamMember(t *testing.T) {
testSuccess(3, unittest.NonexistentID) testSuccess(3, unittest.NonexistentID)
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
err := RemoveTeamMember(team, 2) err := RemoveTeamMember(db.DefaultContext, team, 2)
assert.True(t, organization.IsErrLastOrgOwner(err)) assert.True(t, organization.IsErrLastOrgOwner(err))
} }
@ -161,7 +161,7 @@ func TestRepository_RecalculateAccesses3(t *testing.T) {
// adding user29 to team5 should add an explicit access row for repo 23 // adding user29 to team5 should add an explicit access row for repo 23
// even though repo 23 is public // even though repo 23 is public
assert.NoError(t, AddTeamMember(team5, user29.ID)) assert.NoError(t, AddTeamMember(db.DefaultContext, team5, user29.ID))
has, err = db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23}) has, err = db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23})
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -140,8 +140,8 @@ func (org *Organization) LoadTeams() ([]*Team, error) {
} }
// GetMembers returns all members of organization. // GetMembers returns all members of organization.
func (org *Organization) GetMembers() (user_model.UserList, map[int64]bool, error) { func (org *Organization) GetMembers(ctx context.Context) (user_model.UserList, map[int64]bool, error) {
return FindOrgMembers(&FindOrgMembersOpts{ return FindOrgMembers(ctx, &FindOrgMembersOpts{
OrgID: org.ID, OrgID: org.ID,
}) })
} }
@ -208,8 +208,8 @@ func CountOrgMembers(opts *FindOrgMembersOpts) (int64, error) {
} }
// FindOrgMembers loads organization members according conditions // FindOrgMembers loads organization members according conditions
func FindOrgMembers(opts *FindOrgMembersOpts) (user_model.UserList, map[int64]bool, error) { func FindOrgMembers(ctx context.Context, opts *FindOrgMembersOpts) (user_model.UserList, map[int64]bool, error) {
ous, err := GetOrgUsersByOrgID(db.DefaultContext, opts) ous, err := GetOrgUsersByOrgID(ctx, opts)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -221,7 +221,7 @@ func FindOrgMembers(opts *FindOrgMembersOpts) (user_model.UserList, map[int64]bo
idsIsPublic[ou.UID] = ou.IsPublic idsIsPublic[ou.UID] = ou.IsPublic
} }
users, err := user_model.GetUsersByIDs(ids) users, err := user_model.GetUsersByIDs(ctx, ids)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -520,10 +520,10 @@ func HasOrgsVisible(orgs []*Organization, user *user_model.User) bool {
// GetOrgsCanCreateRepoByUserID returns a list of organizations where given user ID // GetOrgsCanCreateRepoByUserID returns a list of organizations where given user ID
// are allowed to create repos. // are allowed to create repos.
func GetOrgsCanCreateRepoByUserID(userID int64) ([]*Organization, error) { func GetOrgsCanCreateRepoByUserID(ctx context.Context, userID int64) ([]*Organization, error) {
orgs := make([]*Organization, 0, 10) orgs := make([]*Organization, 0, 10)
return orgs, db.GetEngine(db.DefaultContext).Where(builder.In("id", builder.Select("`user`.id").From("`user`"). return orgs, db.GetEngine(ctx).Where(builder.In("id", builder.Select("`user`.id").From("`user`").
Join("INNER", "`team_user`", "`team_user`.org_id = `user`.id"). Join("INNER", "`team_user`", "`team_user`.org_id = `user`.id").
Join("INNER", "`team`", "`team`.id = `team_user`.team_id"). Join("INNER", "`team`", "`team`.id = `team_user`.team_id").
Where(builder.Eq{"`team_user`.uid": userID}). Where(builder.Eq{"`team_user`.uid": userID}).

View File

@ -103,7 +103,7 @@ func TestUser_GetTeams(t *testing.T) {
func TestUser_GetMembers(t *testing.T) { func TestUser_GetMembers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
members, _, err := org.GetMembers() members, _, err := org.GetMembers(db.DefaultContext)
assert.NoError(t, err) assert.NoError(t, err)
if assert.Len(t, members, 3) { if assert.Len(t, members, 3) {
assert.Equal(t, int64(2), members[0].ID) assert.Equal(t, int64(2), members[0].ID)

View File

@ -94,7 +94,7 @@ func TestUserListIsPublicMember(t *testing.T) {
func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) { func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) {
org, err := organization.GetOrgByID(db.DefaultContext, orgID) org, err := organization.GetOrgByID(db.DefaultContext, orgID)
assert.NoError(t, err) assert.NoError(t, err)
_, membersIsPublic, err := org.GetMembers() _, membersIsPublic, err := org.GetMembers(db.DefaultContext)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, expected, membersIsPublic) assert.Equal(t, expected, membersIsPublic)
} }
@ -121,7 +121,7 @@ func TestUserListIsUserOrgOwner(t *testing.T) {
func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) { func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) {
org, err := organization.GetOrgByID(db.DefaultContext, orgID) org, err := organization.GetOrgByID(db.DefaultContext, orgID)
assert.NoError(t, err) assert.NoError(t, err)
members, _, err := org.GetMembers() members, _, err := org.GetMembers(db.DefaultContext)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, expected, organization.IsUserOrgOwner(members, orgID)) assert.Equal(t, expected, organization.IsUserOrgOwner(members, orgID))
} }

View File

@ -21,9 +21,9 @@ func GetRepositoriesByForkID(ctx context.Context, forkID int64) ([]*Repository,
} }
// GetForkedRepo checks if given user has already forked a repository with given ID. // GetForkedRepo checks if given user has already forked a repository with given ID.
func GetForkedRepo(ownerID, repoID int64) *Repository { func GetForkedRepo(ctx context.Context, ownerID, repoID int64) *Repository {
repo := new(Repository) repo := new(Repository)
has, _ := db.GetEngine(db.DefaultContext). has, _ := db.GetEngine(ctx).
Where("owner_id=? AND fork_id=?", ownerID, repoID). Where("owner_id=? AND fork_id=?", ownerID, repoID).
Get(repo) Get(repo)
if has { if has {
@ -33,8 +33,8 @@ func GetForkedRepo(ownerID, repoID int64) *Repository {
} }
// HasForkedRepo checks if given user has already forked a repository with given ID. // HasForkedRepo checks if given user has already forked a repository with given ID.
func HasForkedRepo(ownerID, repoID int64) bool { func HasForkedRepo(ctx context.Context, ownerID, repoID int64) bool {
has, _ := db.GetEngine(db.DefaultContext). has, _ := db.GetEngine(ctx).
Table("repository"). Table("repository").
Where("owner_id=? AND fork_id=?", ownerID, repoID). Where("owner_id=? AND fork_id=?", ownerID, repoID).
Exist() Exist()
@ -55,10 +55,10 @@ func GetUserFork(ctx context.Context, repoID, userID int64) (*Repository, error)
} }
// GetForks returns all the forks of the repository // GetForks returns all the forks of the repository
func GetForks(repo *Repository, listOptions db.ListOptions) ([]*Repository, error) { func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions) ([]*Repository, error) {
if listOptions.Page == 0 { if listOptions.Page == 0 {
forks := make([]*Repository, 0, repo.NumForks) forks := make([]*Repository, 0, repo.NumForks)
return forks, db.GetEngine(db.DefaultContext).Find(&forks, &Repository{ForkID: repo.ID}) return forks, db.GetEngine(ctx).Find(&forks, &Repository{ForkID: repo.ID})
} }
sess := db.GetPaginatedSession(&listOptions) sess := db.GetPaginatedSession(&listOptions)

View File

@ -4,6 +4,8 @@
package repo package repo
import ( import (
"context"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
) )
@ -26,7 +28,7 @@ const (
) )
// UpdateDefaultBranch updates the default branch // UpdateDefaultBranch updates the default branch
func UpdateDefaultBranch(repo *Repository) error { func UpdateDefaultBranch(ctx context.Context, repo *Repository) error {
_, err := db.GetEngine(db.DefaultContext).ID(repo.ID).Cols("default_branch").Update(repo) _, err := db.GetEngine(ctx).ID(repo.ID).Cols("default_branch").Update(repo)
return err return err
} }

View File

@ -178,9 +178,9 @@ func ValidateEmail(email string) error {
} }
// GetEmailAddresses returns all email addresses belongs to given user. // GetEmailAddresses returns all email addresses belongs to given user.
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) { func GetEmailAddresses(ctx context.Context, uid int64) ([]*EmailAddress, error) {
emails := make([]*EmailAddress, 0, 5) emails := make([]*EmailAddress, 0, 5)
if err := db.GetEngine(db.DefaultContext). if err := db.GetEngine(ctx).
Where("uid=?", uid). Where("uid=?", uid).
Asc("id"). Asc("id").
Find(&emails); err != nil { Find(&emails); err != nil {
@ -190,10 +190,10 @@ func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
} }
// GetEmailAddressByID gets a user's email address by ID // GetEmailAddressByID gets a user's email address by ID
func GetEmailAddressByID(uid, id int64) (*EmailAddress, error) { func GetEmailAddressByID(ctx context.Context, uid, id int64) (*EmailAddress, error) {
// User ID is required for security reasons // User ID is required for security reasons
email := &EmailAddress{UID: uid} email := &EmailAddress{UID: uid}
if has, err := db.GetEngine(db.DefaultContext).ID(id).Get(email); err != nil { if has, err := db.GetEngine(ctx).ID(id).Get(email); err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, nil return nil, nil
@ -253,7 +253,7 @@ func AddEmailAddress(ctx context.Context, email *EmailAddress) error {
} }
// AddEmailAddresses adds an email address to given user. // AddEmailAddresses adds an email address to given user.
func AddEmailAddresses(emails []*EmailAddress) error { func AddEmailAddresses(ctx context.Context, emails []*EmailAddress) error {
if len(emails) == 0 { if len(emails) == 0 {
return nil return nil
} }
@ -261,7 +261,7 @@ func AddEmailAddresses(emails []*EmailAddress) error {
// Check if any of them has been used // Check if any of them has been used
for i := range emails { for i := range emails {
emails[i].Email = strings.TrimSpace(emails[i].Email) emails[i].Email = strings.TrimSpace(emails[i].Email)
used, err := IsEmailUsed(db.DefaultContext, emails[i].Email) used, err := IsEmailUsed(ctx, emails[i].Email)
if err != nil { if err != nil {
return err return err
} else if used { } else if used {
@ -272,7 +272,7 @@ func AddEmailAddresses(emails []*EmailAddress) error {
} }
} }
if err := db.Insert(db.DefaultContext, emails); err != nil { if err := db.Insert(ctx, emails); err != nil {
return fmt.Errorf("Insert: %w", err) return fmt.Errorf("Insert: %w", err)
} }
@ -280,7 +280,7 @@ func AddEmailAddresses(emails []*EmailAddress) error {
} }
// DeleteEmailAddress deletes an email address of given user. // DeleteEmailAddress deletes an email address of given user.
func DeleteEmailAddress(email *EmailAddress) (err error) { func DeleteEmailAddress(ctx context.Context, email *EmailAddress) (err error) {
if email.IsPrimary { if email.IsPrimary {
return ErrPrimaryEmailCannotDelete{Email: email.Email} return ErrPrimaryEmailCannotDelete{Email: email.Email}
} }
@ -291,12 +291,12 @@ func DeleteEmailAddress(email *EmailAddress) (err error) {
UID: email.UID, UID: email.UID,
} }
if email.ID > 0 { if email.ID > 0 {
deleted, err = db.GetEngine(db.DefaultContext).ID(email.ID).Delete(&address) deleted, err = db.GetEngine(ctx).ID(email.ID).Delete(&address)
} else { } else {
if email.Email != "" && email.LowerEmail == "" { if email.Email != "" && email.LowerEmail == "" {
email.LowerEmail = strings.ToLower(email.Email) email.LowerEmail = strings.ToLower(email.Email)
} }
deleted, err = db.GetEngine(db.DefaultContext). deleted, err = db.GetEngine(ctx).
Where("lower_email=?", email.LowerEmail). Where("lower_email=?", email.LowerEmail).
Delete(&address) Delete(&address)
} }
@ -310,9 +310,9 @@ func DeleteEmailAddress(email *EmailAddress) (err error) {
} }
// DeleteEmailAddresses deletes multiple email addresses // DeleteEmailAddresses deletes multiple email addresses
func DeleteEmailAddresses(emails []*EmailAddress) (err error) { func DeleteEmailAddresses(ctx context.Context, emails []*EmailAddress) (err error) {
for i := range emails { for i := range emails {
if err = DeleteEmailAddress(emails[i]); err != nil { if err = DeleteEmailAddress(ctx, emails[i]); err != nil {
return err return err
} }
} }
@ -329,8 +329,8 @@ func DeleteInactiveEmailAddresses(ctx context.Context) error {
} }
// ActivateEmail activates the email address to given user. // ActivateEmail activates the email address to given user.
func ActivateEmail(email *EmailAddress) error { func ActivateEmail(ctx context.Context, email *EmailAddress) error {
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -357,8 +357,8 @@ func updateActivation(ctx context.Context, email *EmailAddress, activate bool) e
} }
// MakeEmailPrimary sets primary email address of given user. // MakeEmailPrimary sets primary email address of given user.
func MakeEmailPrimary(email *EmailAddress) error { func MakeEmailPrimary(ctx context.Context, email *EmailAddress) error {
has, err := db.GetEngine(db.DefaultContext).Get(email) has, err := db.GetEngine(ctx).Get(email)
if err != nil { if err != nil {
return err return err
} else if !has { } else if !has {
@ -370,7 +370,7 @@ func MakeEmailPrimary(email *EmailAddress) error {
} }
user := &User{} user := &User{}
has, err = db.GetEngine(db.DefaultContext).ID(email.UID).Get(user) has, err = db.GetEngine(ctx).ID(email.UID).Get(user)
if err != nil { if err != nil {
return err return err
} else if !has { } else if !has {
@ -381,7 +381,7 @@ func MakeEmailPrimary(email *EmailAddress) error {
} }
} }
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -411,17 +411,17 @@ func MakeEmailPrimary(email *EmailAddress) error {
} }
// VerifyActiveEmailCode verifies active email code when active account // VerifyActiveEmailCode verifies active email code when active account
func VerifyActiveEmailCode(code, email string) *EmailAddress { func VerifyActiveEmailCode(ctx context.Context, code, email string) *EmailAddress {
minutes := setting.Service.ActiveCodeLives minutes := setting.Service.ActiveCodeLives
if user := GetVerifyUser(code); user != nil { if user := GetVerifyUser(ctx, code); user != nil {
// time limit code // time limit code
prefix := code[:base.TimeLimitCodeLength] prefix := code[:base.TimeLimitCodeLength]
data := fmt.Sprintf("%d%s%s%s%s", user.ID, email, user.LowerName, user.Passwd, user.Rands) data := fmt.Sprintf("%d%s%s%s%s", user.ID, email, user.LowerName, user.Passwd, user.Rands)
if base.VerifyTimeLimitCode(data, minutes, prefix) { if base.VerifyTimeLimitCode(data, minutes, prefix) {
emailAddress := &EmailAddress{UID: user.ID, Email: email} emailAddress := &EmailAddress{UID: user.ID, Email: email}
if has, _ := db.GetEngine(db.DefaultContext).Get(emailAddress); has { if has, _ := db.GetEngine(ctx).Get(emailAddress); has {
return emailAddress return emailAddress
} }
} }
@ -466,7 +466,7 @@ type SearchEmailResult struct {
// SearchEmails takes options i.e. keyword and part of email name to search, // SearchEmails takes options i.e. keyword and part of email name to search,
// it returns results in given range and number of total results. // it returns results in given range and number of total results.
func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error) { func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error) {
var cond builder.Cond = builder.Eq{"`user`.`type`": UserTypeIndividual} var cond builder.Cond = builder.Eq{"`user`.`type`": UserTypeIndividual}
if len(opts.Keyword) > 0 { if len(opts.Keyword) > 0 {
likeStr := "%" + strings.ToLower(opts.Keyword) + "%" likeStr := "%" + strings.ToLower(opts.Keyword) + "%"
@ -491,7 +491,7 @@ func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error)
cond = cond.And(builder.Eq{"email_address.is_activated": false}) cond = cond.And(builder.Eq{"email_address.is_activated": false})
} }
count, err := db.GetEngine(db.DefaultContext).Join("INNER", "`user`", "`user`.ID = email_address.uid"). count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid").
Where(cond).Count(new(EmailAddress)) Where(cond).Count(new(EmailAddress))
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("Count: %w", err) return nil, 0, fmt.Errorf("Count: %w", err)
@ -505,7 +505,7 @@ func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error)
opts.SetDefaultValues() opts.SetDefaultValues()
emails := make([]*SearchEmailResult, 0, opts.PageSize) emails := make([]*SearchEmailResult, 0, opts.PageSize)
err = db.GetEngine(db.DefaultContext).Table("email_address"). err = db.GetEngine(ctx).Table("email_address").
Select("email_address.*, `user`.name, `user`.full_name"). Select("email_address.*, `user`.name, `user`.full_name").
Join("INNER", "`user`", "`user`.ID = email_address.uid"). Join("INNER", "`user`", "`user`.ID = email_address.uid").
Where(cond). Where(cond).
@ -518,8 +518,8 @@ func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error)
// ActivateUserEmail will change the activated state of an email address, // ActivateUserEmail will change the activated state of an email address,
// either primary or secondary (all in the email_address table) // either primary or secondary (all in the email_address table)
func ActivateUserEmail(userID int64, email string, activate bool) (err error) { func ActivateUserEmail(ctx context.Context, userID int64, email string, activate bool) (err error) {
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -17,14 +17,14 @@ import (
func TestGetEmailAddresses(t *testing.T) { func TestGetEmailAddresses(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
emails, _ := user_model.GetEmailAddresses(int64(1)) emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1))
if assert.Len(t, emails, 3) { if assert.Len(t, emails, 3) {
assert.True(t, emails[0].IsPrimary) assert.True(t, emails[0].IsPrimary)
assert.True(t, emails[2].IsActivated) assert.True(t, emails[2].IsActivated)
assert.False(t, emails[2].IsPrimary) assert.False(t, emails[2].IsPrimary)
} }
emails, _ = user_model.GetEmailAddresses(int64(2)) emails, _ = user_model.GetEmailAddresses(db.DefaultContext, int64(2))
if assert.Len(t, emails, 2) { if assert.Len(t, emails, 2) {
assert.True(t, emails[0].IsPrimary) assert.True(t, emails[0].IsPrimary)
assert.True(t, emails[0].IsActivated) assert.True(t, emails[0].IsActivated)
@ -76,10 +76,10 @@ func TestAddEmailAddresses(t *testing.T) {
LowerEmail: "user5678@example.com", LowerEmail: "user5678@example.com",
IsActivated: true, IsActivated: true,
} }
assert.NoError(t, user_model.AddEmailAddresses(emails)) assert.NoError(t, user_model.AddEmailAddresses(db.DefaultContext, emails))
// ErrEmailAlreadyUsed // ErrEmailAlreadyUsed
err := user_model.AddEmailAddresses(emails) err := user_model.AddEmailAddresses(db.DefaultContext, emails)
assert.Error(t, err) assert.Error(t, err)
assert.True(t, user_model.IsErrEmailAlreadyUsed(err)) assert.True(t, user_model.IsErrEmailAlreadyUsed(err))
} }
@ -87,21 +87,21 @@ func TestAddEmailAddresses(t *testing.T) {
func TestDeleteEmailAddress(t *testing.T) { func TestDeleteEmailAddress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
assert.NoError(t, user_model.DeleteEmailAddress(&user_model.EmailAddress{ assert.NoError(t, user_model.DeleteEmailAddress(db.DefaultContext, &user_model.EmailAddress{
UID: int64(1), UID: int64(1),
ID: int64(33), ID: int64(33),
Email: "user1-2@example.com", Email: "user1-2@example.com",
LowerEmail: "user1-2@example.com", LowerEmail: "user1-2@example.com",
})) }))
assert.NoError(t, user_model.DeleteEmailAddress(&user_model.EmailAddress{ assert.NoError(t, user_model.DeleteEmailAddress(db.DefaultContext, &user_model.EmailAddress{
UID: int64(1), UID: int64(1),
Email: "user1-3@example.com", Email: "user1-3@example.com",
LowerEmail: "user1-3@example.com", LowerEmail: "user1-3@example.com",
})) }))
// Email address does not exist // Email address does not exist
err := user_model.DeleteEmailAddress(&user_model.EmailAddress{ err := user_model.DeleteEmailAddress(db.DefaultContext, &user_model.EmailAddress{
UID: int64(1), UID: int64(1),
Email: "user1234567890@example.com", Email: "user1234567890@example.com",
LowerEmail: "user1234567890@example.com", LowerEmail: "user1234567890@example.com",
@ -125,10 +125,10 @@ func TestDeleteEmailAddresses(t *testing.T) {
Email: "user2-2@example.com", Email: "user2-2@example.com",
LowerEmail: "user2-2@example.com", LowerEmail: "user2-2@example.com",
} }
assert.NoError(t, user_model.DeleteEmailAddresses(emails)) assert.NoError(t, user_model.DeleteEmailAddresses(db.DefaultContext, emails))
// ErrEmailAlreadyUsed // ErrEmailAlreadyUsed
err := user_model.DeleteEmailAddresses(emails) err := user_model.DeleteEmailAddresses(db.DefaultContext, emails)
assert.Error(t, err) assert.Error(t, err)
} }
@ -138,28 +138,28 @@ func TestMakeEmailPrimary(t *testing.T) {
email := &user_model.EmailAddress{ email := &user_model.EmailAddress{
Email: "user567890@example.com", Email: "user567890@example.com",
} }
err := user_model.MakeEmailPrimary(email) err := user_model.MakeEmailPrimary(db.DefaultContext, email)
assert.Error(t, err) assert.Error(t, err)
assert.EqualError(t, err, user_model.ErrEmailAddressNotExist{Email: email.Email}.Error()) assert.EqualError(t, err, user_model.ErrEmailAddressNotExist{Email: email.Email}.Error())
email = &user_model.EmailAddress{ email = &user_model.EmailAddress{
Email: "user11@example.com", Email: "user11@example.com",
} }
err = user_model.MakeEmailPrimary(email) err = user_model.MakeEmailPrimary(db.DefaultContext, email)
assert.Error(t, err) assert.Error(t, err)
assert.EqualError(t, err, user_model.ErrEmailNotActivated.Error()) assert.EqualError(t, err, user_model.ErrEmailNotActivated.Error())
email = &user_model.EmailAddress{ email = &user_model.EmailAddress{
Email: "user9999999@example.com", Email: "user9999999@example.com",
} }
err = user_model.MakeEmailPrimary(email) err = user_model.MakeEmailPrimary(db.DefaultContext, email)
assert.Error(t, err) assert.Error(t, err)
assert.True(t, user_model.IsErrUserNotExist(err)) assert.True(t, user_model.IsErrUserNotExist(err))
email = &user_model.EmailAddress{ email = &user_model.EmailAddress{
Email: "user101@example.com", Email: "user101@example.com",
} }
err = user_model.MakeEmailPrimary(email) err = user_model.MakeEmailPrimary(db.DefaultContext, email)
assert.NoError(t, err) assert.NoError(t, err)
user, _ := user_model.GetUserByID(db.DefaultContext, int64(10)) user, _ := user_model.GetUserByID(db.DefaultContext, int64(10))
@ -174,9 +174,9 @@ func TestActivate(t *testing.T) {
UID: int64(1), UID: int64(1),
Email: "user11@example.com", Email: "user11@example.com",
} }
assert.NoError(t, user_model.ActivateEmail(email)) assert.NoError(t, user_model.ActivateEmail(db.DefaultContext, email))
emails, _ := user_model.GetEmailAddresses(int64(1)) emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1))
assert.Len(t, emails, 3) assert.Len(t, emails, 3)
assert.True(t, emails[0].IsActivated) assert.True(t, emails[0].IsActivated)
assert.True(t, emails[0].IsPrimary) assert.True(t, emails[0].IsPrimary)
@ -194,7 +194,7 @@ func TestListEmails(t *testing.T) {
PageSize: 10000, PageSize: 10000,
}, },
} }
emails, count, err := user_model.SearchEmails(opts) emails, count, err := user_model.SearchEmails(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEqual(t, int64(0), count) assert.NotEqual(t, int64(0), count)
assert.True(t, count > 5) assert.True(t, count > 5)
@ -214,13 +214,13 @@ func TestListEmails(t *testing.T) {
// Must find no records // Must find no records
opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"} opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"}
emails, count, err = user_model.SearchEmails(opts) emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int64(0), count) assert.Equal(t, int64(0), count)
// Must find users 'user2', 'user28', etc. // Must find users 'user2', 'user28', etc.
opts = &user_model.SearchEmailOptions{Keyword: "user2"} opts = &user_model.SearchEmailOptions{Keyword: "user2"}
emails, count, err = user_model.SearchEmails(opts) emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEqual(t, int64(0), count) assert.NotEqual(t, int64(0), count)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 })) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 }))
@ -228,14 +228,14 @@ func TestListEmails(t *testing.T) {
// Must find only primary addresses (i.e. from the `user` table) // Must find only primary addresses (i.e. from the `user` table)
opts = &user_model.SearchEmailOptions{IsPrimary: util.OptionalBoolTrue} opts = &user_model.SearchEmailOptions{IsPrimary: util.OptionalBoolTrue}
emails, _, err = user_model.SearchEmails(opts) emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary })) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary })) assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary }))
// Must find only inactive addresses (i.e. not validated) // Must find only inactive addresses (i.e. not validated)
opts = &user_model.SearchEmailOptions{IsActivated: util.OptionalBoolFalse} opts = &user_model.SearchEmailOptions{IsActivated: util.OptionalBoolFalse}
emails, _, err = user_model.SearchEmails(opts) emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated })) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated })) assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated }))
@ -247,7 +247,7 @@ func TestListEmails(t *testing.T) {
Page: 1, Page: 1,
}, },
} }
emails, count, err = user_model.SearchEmails(opts) emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, emails, 5) assert.Len(t, emails, 5)
assert.Greater(t, count, int64(len(emails))) assert.Greater(t, count, int64(len(emails)))

View File

@ -25,19 +25,19 @@ func (users UserList) GetUserIDs() []int64 {
} }
// GetTwoFaStatus return state of 2FA enrollement // GetTwoFaStatus return state of 2FA enrollement
func (users UserList) GetTwoFaStatus() map[int64]bool { func (users UserList) GetTwoFaStatus(ctx context.Context) map[int64]bool {
results := make(map[int64]bool, len(users)) results := make(map[int64]bool, len(users))
for _, user := range users { for _, user := range users {
results[user.ID] = false // Set default to false results[user.ID] = false // Set default to false
} }
if tokenMaps, err := users.loadTwoFactorStatus(db.DefaultContext); err == nil { if tokenMaps, err := users.loadTwoFactorStatus(ctx); err == nil {
for _, token := range tokenMaps { for _, token := range tokenMaps {
results[token.UID] = true results[token.UID] = true
} }
} }
if ids, err := users.userIDsWithWebAuthn(db.DefaultContext); err == nil { if ids, err := users.userIDsWithWebAuthn(ctx); err == nil {
for _, id := range ids { for _, id := range ids {
results[id] = true results[id] = true
} }
@ -71,12 +71,12 @@ func (users UserList) userIDsWithWebAuthn(ctx context.Context) ([]int64, error)
} }
// GetUsersByIDs returns all resolved users from a list of Ids. // GetUsersByIDs returns all resolved users from a list of Ids.
func GetUsersByIDs(ids []int64) (UserList, error) { func GetUsersByIDs(ctx context.Context, ids []int64) (UserList, error) {
ous := make([]*User, 0, len(ids)) ous := make([]*User, 0, len(ids))
if len(ids) == 0 { if len(ids) == 0 {
return ous, nil return ous, nil
} }
err := db.GetEngine(db.DefaultContext).In("id", ids). err := db.GetEngine(ctx).In("id", ids).
Asc("name"). Asc("name").
Find(&ous) Find(&ous)
return ous, err return ous, err

View File

@ -4,6 +4,7 @@
package user package user
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
@ -34,12 +35,26 @@ type SearchUserOptions struct {
IsRestricted util.OptionalBool IsRestricted util.OptionalBool
IsTwoFactorEnabled util.OptionalBool IsTwoFactorEnabled util.OptionalBool
IsProhibitLogin util.OptionalBool IsProhibitLogin util.OptionalBool
IncludeReserved bool
ExtraParamStrings map[string]string ExtraParamStrings map[string]string
} }
func (opts *SearchUserOptions) toSearchQueryBase() *xorm.Session { func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Session {
var cond builder.Cond = builder.Eq{"type": opts.Type} var cond builder.Cond
cond = builder.Eq{"type": opts.Type}
if opts.IncludeReserved {
if opts.Type == UserTypeIndividual {
cond = cond.Or(builder.Eq{"type": UserTypeUserReserved}).Or(
builder.Eq{"type": UserTypeBot},
).Or(
builder.Eq{"type": UserTypeRemoteUser},
)
} else if opts.Type == UserTypeOrganization {
cond = cond.Or(builder.Eq{"type": UserTypeOrganizationReserved})
}
}
if len(opts.Keyword) > 0 { if len(opts.Keyword) > 0 {
lowerKeyword := strings.ToLower(opts.Keyword) lowerKeyword := strings.ToLower(opts.Keyword)
keywordCond := builder.Or( keywordCond := builder.Or(
@ -87,7 +102,7 @@ func (opts *SearchUserOptions) toSearchQueryBase() *xorm.Session {
cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.IsTrue()}) cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.IsTrue()})
} }
e := db.GetEngine(db.DefaultContext) e := db.GetEngine(ctx)
if opts.IsTwoFactorEnabled.IsNone() { if opts.IsTwoFactorEnabled.IsNone() {
return e.Where(cond) return e.Where(cond)
} }
@ -108,8 +123,8 @@ func (opts *SearchUserOptions) toSearchQueryBase() *xorm.Session {
// SearchUsers takes options i.e. keyword and part of user name to search, // SearchUsers takes options i.e. keyword and part of user name to search,
// it returns results in given range and number of total results. // it returns results in given range and number of total results.
func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) { func SearchUsers(ctx context.Context, opts *SearchUserOptions) (users []*User, _ int64, _ error) {
sessCount := opts.toSearchQueryBase() sessCount := opts.toSearchQueryBase(ctx)
defer sessCount.Close() defer sessCount.Close()
count, err := sessCount.Count(new(User)) count, err := sessCount.Count(new(User))
if err != nil { if err != nil {
@ -120,7 +135,7 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
opts.OrderBy = db.SearchOrderByAlphabetically opts.OrderBy = db.SearchOrderByAlphabetically
} }
sessQuery := opts.toSearchQueryBase().OrderBy(opts.OrderBy.String()) sessQuery := opts.toSearchQueryBase(ctx).OrderBy(opts.OrderBy.String())
defer sessQuery.Close() defer sessQuery.Close()
if opts.Page != 0 { if opts.Page != 0 {
sessQuery = db.SetSessionPagination(sessQuery, opts) sessQuery = db.SetSessionPagination(sessQuery, opts)

View File

@ -192,15 +192,15 @@ func (u *User) SetLastLogin() {
} }
// UpdateUserDiffViewStyle updates the users diff view style // UpdateUserDiffViewStyle updates the users diff view style
func UpdateUserDiffViewStyle(u *User, style string) error { func UpdateUserDiffViewStyle(ctx context.Context, u *User, style string) error {
u.DiffViewStyle = style u.DiffViewStyle = style
return UpdateUserCols(db.DefaultContext, u, "diff_view_style") return UpdateUserCols(ctx, u, "diff_view_style")
} }
// UpdateUserTheme updates a users' theme irrespective of the site wide theme // UpdateUserTheme updates a users' theme irrespective of the site wide theme
func UpdateUserTheme(u *User, themeName string) error { func UpdateUserTheme(ctx context.Context, u *User, themeName string) error {
u.Theme = themeName u.Theme = themeName
return UpdateUserCols(db.DefaultContext, u, "theme") return UpdateUserCols(ctx, u, "theme")
} }
// GetPlaceholderEmail returns an noreply email // GetPlaceholderEmail returns an noreply email
@ -218,9 +218,9 @@ func (u *User) GetEmail() string {
} }
// GetAllUsers returns a slice of all individual users found in DB. // GetAllUsers returns a slice of all individual users found in DB.
func GetAllUsers() ([]*User, error) { func GetAllUsers(ctx context.Context) ([]*User, error) {
users := make([]*User, 0) users := make([]*User, 0)
return users, db.GetEngine(db.DefaultContext).OrderBy("id").Where("type = ?", UserTypeIndividual).Find(&users) return users, db.GetEngine(ctx).OrderBy("id").Where("type = ?", UserTypeIndividual).Find(&users)
} }
// IsLocal returns true if user login type is LoginPlain. // IsLocal returns true if user login type is LoginPlain.
@ -478,9 +478,9 @@ func (u *User) EmailNotifications() string {
} }
// SetEmailNotifications sets the user's email notification preference // SetEmailNotifications sets the user's email notification preference
func SetEmailNotifications(u *User, set string) error { func SetEmailNotifications(ctx context.Context, u *User, set string) error {
u.EmailNotificationsPreference = set u.EmailNotificationsPreference = set
if err := UpdateUserCols(db.DefaultContext, u, "email_notifications_preference"); err != nil { if err := UpdateUserCols(ctx, u, "email_notifications_preference"); err != nil {
log.Error("SetEmailNotifications: %v", err) log.Error("SetEmailNotifications: %v", err)
return err return err
} }
@ -582,7 +582,7 @@ type CreateUserOverwriteOptions struct {
} }
// CreateUser creates record of a new user. // CreateUser creates record of a new user.
func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err error) { func CreateUser(ctx context.Context, u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err error) {
if err = IsUsableUsername(u.Name); err != nil { if err = IsUsableUsername(u.Name); err != nil {
return err return err
} }
@ -640,7 +640,7 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
return err return err
} }
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -711,8 +711,8 @@ type CountUserFilter struct {
} }
// CountUsers returns number of users. // CountUsers returns number of users.
func CountUsers(opts *CountUserFilter) int64 { func CountUsers(ctx context.Context, opts *CountUserFilter) int64 {
return countUsers(db.DefaultContext, opts) return countUsers(ctx, opts)
} }
func countUsers(ctx context.Context, opts *CountUserFilter) int64 { func countUsers(ctx context.Context, opts *CountUserFilter) int64 {
@ -727,7 +727,7 @@ func countUsers(ctx context.Context, opts *CountUserFilter) int64 {
} }
// GetVerifyUser get user by verify code // GetVerifyUser get user by verify code
func GetVerifyUser(code string) (user *User) { func GetVerifyUser(ctx context.Context, code string) (user *User) {
if len(code) <= base.TimeLimitCodeLength { if len(code) <= base.TimeLimitCodeLength {
return nil return nil
} }
@ -735,7 +735,7 @@ func GetVerifyUser(code string) (user *User) {
// use tail hex username query user // use tail hex username query user
hexStr := code[base.TimeLimitCodeLength:] hexStr := code[base.TimeLimitCodeLength:]
if b, err := hex.DecodeString(hexStr); err == nil { if b, err := hex.DecodeString(hexStr); err == nil {
if user, err = GetUserByName(db.DefaultContext, string(b)); user != nil { if user, err = GetUserByName(ctx, string(b)); user != nil {
return user return user
} }
log.Error("user.getVerifyUser: %v", err) log.Error("user.getVerifyUser: %v", err)
@ -745,10 +745,10 @@ func GetVerifyUser(code string) (user *User) {
} }
// VerifyUserActiveCode verifies active code when active account // VerifyUserActiveCode verifies active code when active account
func VerifyUserActiveCode(code string) (user *User) { func VerifyUserActiveCode(ctx context.Context, code string) (user *User) {
minutes := setting.Service.ActiveCodeLives minutes := setting.Service.ActiveCodeLives
if user = GetVerifyUser(code); user != nil { if user = GetVerifyUser(ctx, code); user != nil {
// time limit code // time limit code
prefix := code[:base.TimeLimitCodeLength] prefix := code[:base.TimeLimitCodeLength]
data := fmt.Sprintf("%d%s%s%s%s", user.ID, user.Email, user.LowerName, user.Passwd, user.Rands) data := fmt.Sprintf("%d%s%s%s%s", user.ID, user.Email, user.LowerName, user.Passwd, user.Rands)
@ -872,8 +872,8 @@ func UpdateUserCols(ctx context.Context, u *User, cols ...string) error {
} }
// UpdateUserSetting updates user's settings. // UpdateUserSetting updates user's settings.
func UpdateUserSetting(u *User) (err error) { func UpdateUserSetting(ctx context.Context, u *User) (err error) {
ctx, committer, err := db.TxContext(db.DefaultContext) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -1021,9 +1021,9 @@ func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([
} }
// GetUserNamesByIDs returns usernames for all resolved users from a list of Ids. // GetUserNamesByIDs returns usernames for all resolved users from a list of Ids.
func GetUserNamesByIDs(ids []int64) ([]string, error) { func GetUserNamesByIDs(ctx context.Context, ids []int64) ([]string, error) {
unames := make([]string, 0, len(ids)) unames := make([]string, 0, len(ids))
err := db.GetEngine(db.DefaultContext).In("id", ids). err := db.GetEngine(ctx).In("id", ids).
Table("user"). Table("user").
Asc("name"). Asc("name").
Cols("name"). Cols("name").
@ -1062,9 +1062,9 @@ func GetUserIDsByNames(ctx context.Context, names []string, ignoreNonExistent bo
} }
// GetUsersBySource returns a list of Users for a login source // GetUsersBySource returns a list of Users for a login source
func GetUsersBySource(s *auth.Source) ([]*User, error) { func GetUsersBySource(ctx context.Context, s *auth.Source) ([]*User, error) {
var users []*User var users []*User
err := db.GetEngine(db.DefaultContext).Where("login_type = ? AND login_source = ?", s.Type, s.ID).Find(&users) err := db.GetEngine(ctx).Where("login_type = ? AND login_source = ?", s.Type, s.ID).Find(&users)
return users, err return users, err
} }
@ -1145,12 +1145,12 @@ func GetUserByEmail(ctx context.Context, email string) (*User, error) {
} }
// GetUser checks if a user already exists // GetUser checks if a user already exists
func GetUser(user *User) (bool, error) { func GetUser(ctx context.Context, user *User) (bool, error) {
return db.GetEngine(db.DefaultContext).Get(user) return db.GetEngine(ctx).Get(user)
} }
// GetUserByOpenID returns the user object by given OpenID if exists. // GetUserByOpenID returns the user object by given OpenID if exists.
func GetUserByOpenID(uri string) (*User, error) { func GetUserByOpenID(ctx context.Context, uri string) (*User, error) {
if len(uri) == 0 { if len(uri) == 0 {
return nil, ErrUserNotExist{0, uri, 0} return nil, ErrUserNotExist{0, uri, 0}
} }
@ -1164,12 +1164,12 @@ func GetUserByOpenID(uri string) (*User, error) {
// Otherwise, check in openid table // Otherwise, check in openid table
oid := &UserOpenID{} oid := &UserOpenID{}
has, err := db.GetEngine(db.DefaultContext).Where("uri=?", uri).Get(oid) has, err := db.GetEngine(ctx).Where("uri=?", uri).Get(oid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if has { if has {
return GetUserByID(db.DefaultContext, oid.UID) return GetUserByID(ctx, oid.UID)
} }
return nil, ErrUserNotExist{0, uri, 0} return nil, ErrUserNotExist{0, uri, 0}
@ -1279,13 +1279,13 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
} }
// CountWrongUserType count OrgUser who have wrong type // CountWrongUserType count OrgUser who have wrong type
func CountWrongUserType() (int64, error) { func CountWrongUserType(ctx context.Context) (int64, error) {
return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Count(new(User)) return db.GetEngine(ctx).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Count(new(User))
} }
// FixWrongUserType fix OrgUser who have wrong type // FixWrongUserType fix OrgUser who have wrong type
func FixWrongUserType() (int64, error) { func FixWrongUserType(ctx context.Context) (int64, error) {
return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&User{Type: 1}) return db.GetEngine(ctx).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&User{Type: 1})
} }
func GetOrderByName() string { func GetOrderByName() string {

View File

@ -63,7 +63,7 @@ func TestCanCreateOrganization(t *testing.T) {
func TestSearchUsers(t *testing.T) { func TestSearchUsers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(opts *user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) { testSuccess := func(opts *user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) {
users, _, err := user_model.SearchUsers(opts) users, _, err := user_model.SearchUsers(db.DefaultContext, opts)
assert.NoError(t, err) assert.NoError(t, err)
cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts) cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts)
if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) { if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) {
@ -150,16 +150,16 @@ func TestEmailNotificationPreferences(t *testing.T) {
assert.Equal(t, test.expected, user.EmailNotifications()) assert.Equal(t, test.expected, user.EmailNotifications())
// Try all possible settings // Try all possible settings
assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsEnabled)) assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsEnabled))
assert.Equal(t, user_model.EmailNotificationsEnabled, user.EmailNotifications()) assert.Equal(t, user_model.EmailNotificationsEnabled, user.EmailNotifications())
assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsOnMention)) assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsOnMention))
assert.Equal(t, user_model.EmailNotificationsOnMention, user.EmailNotifications()) assert.Equal(t, user_model.EmailNotificationsOnMention, user.EmailNotifications())
assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsDisabled)) assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsDisabled))
assert.Equal(t, user_model.EmailNotificationsDisabled, user.EmailNotifications()) assert.Equal(t, user_model.EmailNotificationsDisabled, user.EmailNotifications())
assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsAndYourOwn)) assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsAndYourOwn))
assert.Equal(t, user_model.EmailNotificationsAndYourOwn, user.EmailNotifications()) assert.Equal(t, user_model.EmailNotificationsAndYourOwn, user.EmailNotifications())
} }
} }
@ -239,7 +239,7 @@ func TestCreateUserInvalidEmail(t *testing.T) {
MustChangePassword: false, MustChangePassword: false,
} }
err := user_model.CreateUser(user) err := user_model.CreateUser(db.DefaultContext, user)
assert.Error(t, err) assert.Error(t, err)
assert.True(t, user_model.IsErrEmailCharIsNotSupported(err)) assert.True(t, user_model.IsErrEmailCharIsNotSupported(err))
} }
@ -253,7 +253,7 @@ func TestCreateUserEmailAlreadyUsed(t *testing.T) {
user.Name = "testuser" user.Name = "testuser"
user.LowerName = strings.ToLower(user.Name) user.LowerName = strings.ToLower(user.Name)
user.ID = 0 user.ID = 0
err := user_model.CreateUser(user) err := user_model.CreateUser(db.DefaultContext, user)
assert.Error(t, err) assert.Error(t, err)
assert.True(t, user_model.IsErrEmailAlreadyUsed(err)) assert.True(t, user_model.IsErrEmailAlreadyUsed(err))
} }
@ -270,7 +270,7 @@ func TestCreateUserCustomTimestamps(t *testing.T) {
user.ID = 0 user.ID = 0
user.Email = "unique@example.com" user.Email = "unique@example.com"
user.CreatedUnix = creationTimestamp user.CreatedUnix = creationTimestamp
err := user_model.CreateUser(user) err := user_model.CreateUser(db.DefaultContext, user)
assert.NoError(t, err) assert.NoError(t, err)
fetched, err := user_model.GetUserByID(context.Background(), user.ID) fetched, err := user_model.GetUserByID(context.Background(), user.ID)
@ -295,7 +295,7 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
user.Email = "unique@example.com" user.Email = "unique@example.com"
user.CreatedUnix = 0 user.CreatedUnix = 0
user.UpdatedUnix = 0 user.UpdatedUnix = 0
err := user_model.CreateUser(user) err := user_model.CreateUser(db.DefaultContext, user)
assert.NoError(t, err) assert.NoError(t, err)
timestampEnd := time.Now().Unix() timestampEnd := time.Now().Unix()
@ -429,17 +429,17 @@ func TestNewUserRedirect3(t *testing.T) {
func TestGetUserByOpenID(t *testing.T) { func TestGetUserByOpenID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
_, err := user_model.GetUserByOpenID("https://unknown") _, err := user_model.GetUserByOpenID(db.DefaultContext, "https://unknown")
if assert.Error(t, err) { if assert.Error(t, err) {
assert.True(t, user_model.IsErrUserNotExist(err)) assert.True(t, user_model.IsErrUserNotExist(err))
} }
user, err := user_model.GetUserByOpenID("https://user1.domain1.tld") user, err := user_model.GetUserByOpenID(db.DefaultContext, "https://user1.domain1.tld")
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, int64(1), user.ID) assert.Equal(t, int64(1), user.ID)
} }
user, err = user_model.GetUserByOpenID("https://domain1.tld/user2/") user, err = user_model.GetUserByOpenID(db.DefaultContext, "https://domain1.tld/user2/")
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, int64(2), user.ID) assert.Equal(t, int64(2), user.ID)
} }

View File

@ -561,7 +561,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(unit_model.TypeIssues) ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(unit_model.TypeIssues)
ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(unit_model.TypePullRequests) ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(unit_model.TypePullRequests)
canSignedUserFork, err := repo_module.CanUserForkRepo(ctx.Doer, ctx.Repo.Repository) canSignedUserFork, err := repo_module.CanUserForkRepo(ctx, ctx.Doer, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.ServerError("CanUserForkRepo", err) ctx.ServerError("CanUserForkRepo", err)
return nil return nil
@ -703,7 +703,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
// People who have push access or have forked repository can propose a new pull request. // People who have push access or have forked repository can propose a new pull request.
canPush := ctx.Repo.CanWrite(unit_model.TypeCode) || canPush := ctx.Repo.CanWrite(unit_model.TypeCode) ||
(ctx.IsSigned && repo_model.HasForkedRepo(ctx.Doer.ID, ctx.Repo.Repository.ID)) (ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID))
canCompare := false canCompare := false
// Pull request is allowed if this is a fork repository // Pull request is allowed if this is a fork repository

View File

@ -29,7 +29,7 @@ func fixOwnerTeamCreateOrgRepo(ctx context.Context, logger log.Logger, autofix b
return nil return nil
} }
return models.UpdateTeam(team, false, false) return models.UpdateTeam(ctx, team, false, false)
}, },
) )
if err != nil { if err != nil {

View File

@ -11,14 +11,14 @@ import (
) )
func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error { func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error {
count, err := user_model.CountWrongUserType() count, err := user_model.CountWrongUserType(ctx)
if err != nil { if err != nil {
logger.Critical("Error: %v whilst counting wrong user types") logger.Critical("Error: %v whilst counting wrong user types")
return err return err
} }
if count > 0 { if count > 0 {
if autofix { if autofix {
if count, err = user_model.FixWrongUserType(); err != nil { if count, err = user_model.FixWrongUserType(ctx); err != nil {
logger.Critical("Error: %v whilst fixing wrong user types") logger.Critical("Error: %v whilst fixing wrong user types")
return err return err
} }

View File

@ -5,6 +5,7 @@ package issues
import ( import (
"context" "context"
"fmt"
"path" "path"
"path/filepath" "path/filepath"
"testing" "testing"
@ -13,6 +14,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/indexer/issues/bleve" "code.gitea.io/gitea/modules/indexer/issues/bleve"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
_ "code.gitea.io/gitea/models" _ "code.gitea.io/gitea/models"
_ "code.gitea.io/gitea/models/actions" _ "code.gitea.io/gitea/models/actions"
@ -89,7 +91,7 @@ func TestBleveSearchIssues(t *testing.T) {
}) })
} }
func TestDBSearchIssues(t *testing.T) { func TestDBSearchIssuesWithKeyword(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
setting.Indexer.IssueType = "db" setting.Indexer.IssueType = "db"
@ -131,3 +133,82 @@ func TestDBSearchIssues(t *testing.T) {
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)
}) })
} }
// TODO: add more tests
func TestDBSearchIssueWithoutKeyword(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
setting.Indexer.IssueType = "db"
InitIssueIndexer(true)
int64Pointer := func(x int64) *int64 {
return &x
}
for _, test := range []struct {
opts SearchOptions
expectedIDs []int64
}{
{
SearchOptions{
RepoIDs: []int64{1},
},
[]int64{11, 5, 3, 2, 1},
},
{
SearchOptions{
RepoIDs: []int64{1},
AssigneeID: int64Pointer(1),
},
[]int64{1},
},
{
SearchOptions{
RepoIDs: []int64{1},
PosterID: int64Pointer(1),
},
[]int64{11, 3, 2, 1},
},
{
SearchOptions{
RepoIDs: []int64{1},
IsClosed: util.OptionalBoolFalse,
},
[]int64{11, 3, 2, 1},
},
{
SearchOptions{
RepoIDs: []int64{1},
IsClosed: util.OptionalBoolTrue,
},
[]int64{5},
},
{
SearchOptions{
RepoIDs: []int64{1},
},
[]int64{11, 5, 3, 2, 1},
},
{
SearchOptions{
RepoIDs: []int64{1},
AssigneeID: int64Pointer(1),
},
[]int64{1},
},
{
SearchOptions{
RepoIDs: []int64{1},
PosterID: int64Pointer(1),
},
[]int64{11, 3, 2, 1},
},
} {
t.Run(fmt.Sprintf("%#v", test.opts), func(t *testing.T) {
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
if !assert.NoError(t, err) {
return
}
assert.Equal(t, test.expectedIDs, issueIDs)
})
}
}

View File

@ -7,6 +7,7 @@ import (
"runtime" "runtime"
activities_model "code.gitea.io/gitea/models/activities" activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@ -232,7 +233,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) {
// Collect returns the metrics with values // Collect returns the metrics with values
func (c Collector) Collect(ch chan<- prometheus.Metric) { func (c Collector) Collect(ch chan<- prometheus.Metric) {
stats := activities_model.GetStatistic() stats := activities_model.GetStatistic(db.DefaultContext)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.Accesses, c.Accesses,

View File

@ -4,25 +4,27 @@
package repository package repository
import ( import (
"context"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
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"
) )
// CanUserForkRepo returns true if specified user can fork repository. // CanUserForkRepo returns true if specified user can fork repository.
func CanUserForkRepo(user *user_model.User, repo *repo_model.Repository) (bool, error) { func CanUserForkRepo(ctx context.Context, user *user_model.User, repo *repo_model.Repository) (bool, error) {
if user == nil { if user == nil {
return false, nil return false, nil
} }
if repo.OwnerID != user.ID && !repo_model.HasForkedRepo(user.ID, repo.ID) { if repo.OwnerID != user.ID && !repo_model.HasForkedRepo(ctx, user.ID, repo.ID) {
return true, nil return true, nil
} }
ownedOrgs, err := organization.GetOrgsCanCreateRepoByUserID(user.ID) ownedOrgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx, user.ID)
if err != nil { if err != nil {
return false, err return false, err
} }
for _, org := range ownedOrgs { for _, org := range ownedOrgs {
if repo.OwnerID != org.ID && !repo_model.HasForkedRepo(org.ID, repo.ID) { if repo.OwnerID != org.ID && !repo_model.HasForkedRepo(ctx, org.ID, repo.ID) {
return true, nil return true, nil
} }
} }

View File

@ -2780,6 +2780,9 @@ users.full_name = Full Name
users.activated = Activated users.activated = Activated
users.admin = Admin users.admin = Admin
users.restricted = Restricted users.restricted = Restricted
users.reserved = Reserved
users.bot = Bot
users.remote = Remote
users.2fa = 2FA users.2fa = 2FA
users.repos = Repos users.repos = Repos
users.created = Created users.created = Created

View File

@ -3230,6 +3230,7 @@ desc=リポジトリ パッケージを管理します。
empty=パッケージはまだありません。 empty=パッケージはまだありません。
empty.documentation=パッケージレジストリの詳細については、 <a target="_blank" rel="noopener noreferrer" href="%s">ドキュメント</a> を参照してください。 empty.documentation=パッケージレジストリの詳細については、 <a target="_blank" rel="noopener noreferrer" href="%s">ドキュメント</a> を参照してください。
empty.repo=パッケージはアップロードしたけども、ここに表示されない? <a href="%[1]s">パッケージ設定</a>を開いて、パッケージをこのリポジトリにリンクしてください。 empty.repo=パッケージはアップロードしたけども、ここに表示されない? <a href="%[1]s">パッケージ設定</a>を開いて、パッケージをこのリポジトリにリンクしてください。
registry.documentation=%sレジストリの詳細については、 <a target="_blank" rel="noopener noreferrer" href="%s">ドキュメント</a> を参照してください。
filter.type=タイプ filter.type=タイプ
filter.type.all=すべて filter.type.all=すべて
filter.no_result=フィルタの結果、空になりました。 filter.no_result=フィルタの結果、空になりました。
@ -3319,6 +3320,8 @@ pub.install=Dart を使用してパッケージをインストールするには
pypi.requires=必要なPython pypi.requires=必要なPython
pypi.install=pip を使用してパッケージをインストールするには、次のコマンドを実行します: pypi.install=pip を使用してパッケージをインストールするには、次のコマンドを実行します:
rpm.registry=このレジストリをコマンドラインからセットアップします: rpm.registry=このレジストリをコマンドラインからセットアップします:
rpm.distros.redhat=RedHat系ディストリビューションの場合
rpm.distros.suse=SUSE系ディストリビューションの場合
rpm.install=パッケージをインストールするには、次のコマンドを実行します: rpm.install=パッケージをインストールするには、次のコマンドを実行します:
rubygems.install=gem を使用してパッケージをインストールするには、次のコマンドを実行します: rubygems.install=gem を使用してパッケージをインストールするには、次のコマンドを実行します:
rubygems.install2=または Gemfile に追加します: rubygems.install2=または Gemfile に追加します:
@ -3416,6 +3419,7 @@ runners.labels=ラベル
runners.last_online=最終オンライン時刻 runners.last_online=最終オンライン時刻
runners.runner_title=ランナー runners.runner_title=ランナー
runners.task_list=このランナーの最近のタスク runners.task_list=このランナーの最近のタスク
runners.task_list.no_tasks=タスクはまだありません。
runners.task_list.run=実行 runners.task_list.run=実行
runners.task_list.status=ステータス runners.task_list.status=ステータス
runners.task_list.repository=リポジトリ runners.task_list.repository=リポジトリ

View File

@ -37,7 +37,7 @@ func GetAllEmails(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)
emails, maxResults, err := user_model.SearchEmails(&user_model.SearchEmailOptions{ emails, maxResults, err := user_model.SearchEmails(ctx, &user_model.SearchEmailOptions{
Keyword: ctx.Params(":email"), Keyword: ctx.Params(":email"),
ListOptions: listOptions, ListOptions: listOptions,
}) })

View File

@ -101,7 +101,7 @@ func GetAllOrgs(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)
users, maxResults, err := user_model.SearchUsers(&user_model.SearchUserOptions{ users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer, Actor: ctx.Doer,
Type: user_model.UserTypeOrganization, Type: user_model.UserTypeOrganization,
OrderBy: db.SearchOrderByAlphabetically, OrderBy: db.SearchOrderByAlphabetically,

View File

@ -128,7 +128,7 @@ func CreateUser(ctx *context.APIContext) {
u.UpdatedUnix = u.CreatedUnix u.UpdatedUnix = u.CreatedUnix
} }
if err := user_model.CreateUser(u, overwriteDefault); err != nil { if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
if user_model.IsErrUserAlreadyExist(err) || if user_model.IsErrUserAlreadyExist(err) ||
user_model.IsErrEmailAlreadyUsed(err) || user_model.IsErrEmailAlreadyUsed(err) ||
db.IsErrNameReserved(err) || db.IsErrNameReserved(err) ||
@ -450,7 +450,7 @@ func SearchUsers(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)
users, maxResults, err := user_model.SearchUsers(&user_model.SearchUserOptions{ users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer, Actor: ctx.Doer,
Type: user_model.UserTypeIndividual, Type: user_model.UserTypeIndividual,
LoginName: ctx.FormTrim("login_name"), LoginName: ctx.FormTrim("login_name"),

View File

@ -34,12 +34,12 @@ func NodeInfo(ctx *context.APIContext) {
nodeInfoUsage, cached = ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage) nodeInfoUsage, cached = ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage)
} }
if !cached { if !cached {
usersTotal := int(user_model.CountUsers(nil)) usersTotal := int(user_model.CountUsers(ctx, nil))
now := time.Now() now := time.Now()
timeOneMonthAgo := now.AddDate(0, -1, 0).Unix() timeOneMonthAgo := now.AddDate(0, -1, 0).Unix()
timeHaveYearAgo := now.AddDate(0, -6, 0).Unix() timeHaveYearAgo := now.AddDate(0, -6, 0).Unix()
usersActiveMonth := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeOneMonthAgo})) usersActiveMonth := int(user_model.CountUsers(ctx, &user_model.CountUserFilter{LastLoginSince: &timeOneMonthAgo}))
usersActiveHalfyear := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeHaveYearAgo})) usersActiveHalfyear := int(user_model.CountUsers(ctx, &user_model.CountUserFilter{LastLoginSince: &timeHaveYearAgo}))
allIssues, _ := issues_model.CountIssues(ctx, &issues_model.IssuesOptions{}) allIssues, _ := issues_model.CountIssues(ctx, &issues_model.IssuesOptions{})
allComments, _ := issues_model.CountComments(&issues_model.FindCommentsOptions{}) allComments, _ := issues_model.CountComments(&issues_model.FindCommentsOptions{})

View File

@ -31,7 +31,7 @@ func listMembers(ctx *context.APIContext, publicOnly bool) {
return return
} }
members, _, err := organization.FindOrgMembers(opts) members, _, err := organization.FindOrgMembers(ctx, opts)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return

View File

@ -203,7 +203,7 @@ func GetAll(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)
publicOrgs, maxResults, err := user_model.SearchUsers(&user_model.SearchUserOptions{ publicOrgs, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer, Actor: ctx.Doer,
ListOptions: listOptions, ListOptions: listOptions,
Type: user_model.UserTypeOrganization, Type: user_model.UserTypeOrganization,

View File

@ -239,7 +239,7 @@ func CreateTeam(ctx *context.APIContext) {
attachAdminTeamUnits(team) attachAdminTeamUnits(team)
} }
if err := models.NewTeam(team); err != nil { if err := models.NewTeam(ctx, team); err != nil {
if organization.IsErrTeamAlreadyExist(err) { if organization.IsErrTeamAlreadyExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err) ctx.Error(http.StatusUnprocessableEntity, "", err)
} else { } else {
@ -330,7 +330,7 @@ func EditTeam(ctx *context.APIContext) {
attachAdminTeamUnits(team) attachAdminTeamUnits(team)
} }
if err := models.UpdateTeam(team, isAuthChanged, isIncludeAllChanged); err != nil { if err := models.UpdateTeam(ctx, team, isAuthChanged, isIncludeAllChanged); err != nil {
ctx.Error(http.StatusInternalServerError, "EditTeam", err) ctx.Error(http.StatusInternalServerError, "EditTeam", err)
return return
} }
@ -361,7 +361,7 @@ func DeleteTeam(ctx *context.APIContext) {
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
if err := models.DeleteTeam(ctx.Org.Team); err != nil { if err := models.DeleteTeam(ctx, ctx.Org.Team); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteTeam", err) ctx.Error(http.StatusInternalServerError, "DeleteTeam", err)
return return
} }
@ -493,7 +493,7 @@ func AddTeamMember(ctx *context.APIContext) {
if ctx.Written() { if ctx.Written() {
return return
} }
if err := models.AddTeamMember(ctx.Org.Team, u.ID); err != nil { if err := models.AddTeamMember(ctx, ctx.Org.Team, u.ID); err != nil {
ctx.Error(http.StatusInternalServerError, "AddMember", err) ctx.Error(http.StatusInternalServerError, "AddMember", err)
return return
} }
@ -530,7 +530,7 @@ func RemoveTeamMember(ctx *context.APIContext) {
return return
} }
if err := models.RemoveTeamMember(ctx.Org.Team, u.ID); err != nil { if err := models.RemoveTeamMember(ctx, ctx.Org.Team, u.ID); err != nil {
ctx.Error(http.StatusInternalServerError, "RemoveTeamMember", err) ctx.Error(http.StatusInternalServerError, "RemoveTeamMember", err)
return return
} }

View File

@ -447,7 +447,7 @@ func GetBranchProtection(ctx *context.APIContext) {
return return
} }
ctx.JSON(http.StatusOK, convert.ToBranchProtection(bp)) ctx.JSON(http.StatusOK, convert.ToBranchProtection(ctx, bp))
} }
// ListBranchProtections list branch protections for a repo // ListBranchProtections list branch protections for a repo
@ -480,7 +480,7 @@ func ListBranchProtections(ctx *context.APIContext) {
} }
apiBps := make([]*api.BranchProtection, len(bps)) apiBps := make([]*api.BranchProtection, len(bps))
for i := range bps { for i := range bps {
apiBps[i] = convert.ToBranchProtection(bps[i]) apiBps[i] = convert.ToBranchProtection(ctx, bps[i])
} }
ctx.JSON(http.StatusOK, apiBps) ctx.JSON(http.StatusOK, apiBps)
@ -688,7 +688,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
return return
} }
ctx.JSON(http.StatusCreated, convert.ToBranchProtection(bp)) ctx.JSON(http.StatusCreated, convert.ToBranchProtection(ctx, bp))
} }
// EditBranchProtection edits a branch protection for a repo // EditBranchProtection edits a branch protection for a repo
@ -960,7 +960,7 @@ func EditBranchProtection(ctx *context.APIContext) {
return return
} }
ctx.JSON(http.StatusOK, convert.ToBranchProtection(bp)) ctx.JSON(http.StatusOK, convert.ToBranchProtection(ctx, bp))
} }
// DeleteBranchProtection deletes a branch protection for a repo // DeleteBranchProtection deletes a branch protection for a repo

View File

@ -55,7 +55,7 @@ func ListForks(ctx *context.APIContext) {
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
forks, err := repo_model.GetForks(ctx.Repo.Repository, utils.GetListOptions(ctx)) forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx))
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "GetForks", err) ctx.Error(http.StatusInternalServerError, "GetForks", err)
return return

View File

@ -273,7 +273,7 @@ func GetIssueSubscribers(ctx *context.APIContext) {
userIDs = append(userIDs, iw.UserID) userIDs = append(userIDs, iw.UserID)
} }
users, err := user_model.GetUsersByIDs(userIDs) users, err := user_model.GetUsersByIDs(ctx, userIDs)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUsersByIDs", err) ctx.Error(http.StatusInternalServerError, "GetUsersByIDs", err)
return return

View File

@ -985,7 +985,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
} }
// Check if current user has fork of repository or in the same repository. // Check if current user has fork of repository or in the same repository.
headRepo := repo_model.GetForkedRepo(headUser.ID, baseRepo.ID) headRepo := repo_model.GetForkedRepo(ctx, headUser.ID, baseRepo.ID)
if headRepo == nil && !isSameRepo { if headRepo == nil && !isSameRepo {
log.Trace("parseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID) log.Trace("parseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID)
ctx.NotFound("GetForkedRepo") ctx.NotFound("GetForkedRepo")

View File

@ -27,7 +27,7 @@ func ListEmails(ctx *context.APIContext) {
// "200": // "200":
// "$ref": "#/responses/EmailList" // "$ref": "#/responses/EmailList"
emails, err := user_model.GetEmailAddresses(ctx.Doer.ID) emails, err := user_model.GetEmailAddresses(ctx, ctx.Doer.ID)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "GetEmailAddresses", err) ctx.Error(http.StatusInternalServerError, "GetEmailAddresses", err)
return return
@ -71,7 +71,7 @@ func AddEmail(ctx *context.APIContext) {
} }
} }
if err := user_model.AddEmailAddresses(emails); err != nil { if err := user_model.AddEmailAddresses(ctx, emails); err != nil {
if user_model.IsErrEmailAlreadyUsed(err) { if user_model.IsErrEmailAlreadyUsed(err) {
ctx.Error(http.StatusUnprocessableEntity, "", "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email) ctx.Error(http.StatusUnprocessableEntity, "", "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email)
} else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) { } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) {
@ -129,7 +129,7 @@ func DeleteEmail(ctx *context.APIContext) {
} }
} }
if err := user_model.DeleteEmailAddresses(emails); err != nil { if err := user_model.DeleteEmailAddresses(ctx, emails); err != nil {
if user_model.IsErrEmailAddressNotExist(err) { if user_model.IsErrEmailAddressNotExist(err) {
ctx.Error(http.StatusNotFound, "DeleteEmailAddresses", err) ctx.Error(http.StatusNotFound, "DeleteEmailAddresses", err)
return return

View File

@ -54,7 +54,7 @@ func Search(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)
users, maxResults, err := user_model.SearchUsers(&user_model.SearchUserOptions{ users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer, Actor: ctx.Doer,
Keyword: ctx.FormTrim("q"), Keyword: ctx.FormTrim("q"),
UID: ctx.FormInt64("uid"), UID: ctx.FormInt64("uid"),

View File

@ -536,7 +536,7 @@ func SubmitInstall(ctx *context.Context) {
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,
} }
if err = user_model.CreateUser(u, overwriteDefault); err != nil { if err = user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
if !user_model.IsErrUserAlreadyExist(err) { if !user_model.IsErrUserAlreadyExist(err) {
setting.InstallLock = false setting.InstallLock = false
ctx.Data["Err_AdminName"] = true ctx.Data["Err_AdminName"] = true

View File

@ -29,7 +29,7 @@ func SetDefaultBranch(ctx *gitea_context.PrivateContext) {
} }
} }
if err := repo_model.UpdateDefaultBranch(ctx.Repo.Repository); err != nil { if err := repo_model.UpdateDefaultBranch(ctx, ctx.Repo.Repository); err != nil {
ctx.JSON(http.StatusInternalServerError, private.Response{ ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err), Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err),
}) })

View File

@ -182,7 +182,7 @@ func CronTasks(ctx *context.Context) {
func MonitorStats(ctx *context.Context) { func MonitorStats(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.monitor.stats") ctx.Data["Title"] = ctx.Tr("admin.monitor.stats")
ctx.Data["PageIsAdminMonitorStats"] = true ctx.Data["PageIsAdminMonitorStats"] = true
bs, err := json.Marshal(activities_model.GetStatistic().Counter) bs, err := json.Marshal(activities_model.GetStatistic(ctx).Counter)
if err != nil { if err != nil {
ctx.ServerError("MonitorStats", err) ctx.ServerError("MonitorStats", err)
return return

View File

@ -75,7 +75,7 @@ func Emails(ctx *context.Context) {
} }
if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
baseEmails, count, err = user_model.SearchEmails(opts) baseEmails, count, err = user_model.SearchEmails(ctx, opts)
if err != nil { if err != nil {
ctx.ServerError("SearchEmails", err) ctx.ServerError("SearchEmails", err)
return return
@ -121,7 +121,7 @@ func ActivateEmail(ctx *context.Context) {
log.Info("Changing activation for User ID: %d, email: %s, primary: %v to %v", uid, email, primary, activate) log.Info("Changing activation for User ID: %d, email: %s, primary: %v to %v", uid, email, primary, activate)
if err := user_model.ActivateUserEmail(uid, email, activate); err != nil { if err := user_model.ActivateUserEmail(ctx, uid, email, activate); err != nil {
log.Error("ActivateUserEmail(%v,%v,%v): %v", uid, email, activate, err) log.Error("ActivateUserEmail(%v,%v,%v): %v", uid, email, activate, err)
if user_model.IsErrEmailAlreadyUsed(err) { if user_model.IsErrEmailAlreadyUsed(err) {
ctx.Flash.Error(ctx.Tr("admin.emails.duplicate_active")) ctx.Flash.Error(ctx.Tr("admin.emails.duplicate_active"))

View File

@ -28,8 +28,9 @@ func Organizations(ctx *context.Context) {
} }
explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{ explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer, Actor: ctx.Doer,
Type: user_model.UserTypeOrganization, Type: user_model.UserTypeOrganization,
IncludeReserved: true, // administrator needs to list all acounts include reserved
ListOptions: db.ListOptions{ ListOptions: db.ListOptions{
PageSize: setting.UI.Admin.OrgPagingNum, PageSize: setting.UI.Admin.OrgPagingNum,
}, },

View File

@ -77,6 +77,7 @@ func Users(ctx *context.Context) {
IsRestricted: util.OptionalBoolParse(statusFilterMap["is_restricted"]), IsRestricted: util.OptionalBoolParse(statusFilterMap["is_restricted"]),
IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]), IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]),
IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]), IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]),
IncludeReserved: true, // administrator needs to list all acounts include reserved, bot, remote ones
ExtraParamStrings: extraParamStrings, ExtraParamStrings: extraParamStrings,
}, tplUsers) }, tplUsers)
} }
@ -169,7 +170,7 @@ func NewUserPost(ctx *context.Context) {
u.MustChangePassword = form.MustChangePassword u.MustChangePassword = form.MustChangePassword
} }
if err := user_model.CreateUser(u, overwriteDefault); err != nil { if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
switch { switch {
case user_model.IsErrUserAlreadyExist(err): case user_model.IsErrUserAlreadyExist(err):
ctx.Data["Err_UserName"] = true ctx.Data["Err_UserName"] = true
@ -281,7 +282,7 @@ func ViewUser(ctx *context.Context) {
ctx.Data["Repos"] = repos ctx.Data["Repos"] = repos
ctx.Data["ReposTotal"] = int(count) ctx.Data["ReposTotal"] = int(count)
emails, err := user_model.GetEmailAddresses(u.ID) emails, err := user_model.GetEmailAddresses(ctx, u.ID)
if err != nil { if err != nil {
ctx.ServerError("GetEmailAddresses", err) ctx.ServerError("GetEmailAddresses", err)
return return

View File

@ -199,7 +199,7 @@ func SignInPost(ctx *context.Context) {
} }
} }
u, source, err := auth_service.UserSignIn(form.UserName, form.Password) u, source, err := auth_service.UserSignIn(ctx, form.UserName, form.Password)
if err != nil { if err != nil {
if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) { if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) {
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form) ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
@ -509,15 +509,15 @@ func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form any
// createUserInContext creates a user and handles errors within a given context. // createUserInContext creates a user and handles errors within a given context.
// Optionally a template can be specified. // Optionally a template can be specified.
func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) (ok bool) { func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) (ok bool) {
if err := user_model.CreateUser(u, overwrites); err != nil { if err := user_model.CreateUser(ctx, u, overwrites); err != nil {
if allowLink && (user_model.IsErrUserAlreadyExist(err) || user_model.IsErrEmailAlreadyUsed(err)) { if allowLink && (user_model.IsErrUserAlreadyExist(err) || user_model.IsErrEmailAlreadyUsed(err)) {
if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingAuto { if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingAuto {
var user *user_model.User var user *user_model.User
user = &user_model.User{Name: u.Name} user = &user_model.User{Name: u.Name}
hasUser, err := user_model.GetUser(user) hasUser, err := user_model.GetUser(ctx, user)
if !hasUser || err != nil { if !hasUser || err != nil {
user = &user_model.User{Email: u.Email} user = &user_model.User{Email: u.Email}
hasUser, err = user_model.GetUser(user) hasUser, err = user_model.GetUser(ctx, user)
if !hasUser || err != nil { if !hasUser || err != nil {
ctx.ServerError("UserLinkAccount", err) ctx.ServerError("UserLinkAccount", err)
return false return false
@ -576,7 +576,7 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *us
// sends a confirmation email if required. // sends a confirmation email if required.
func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) { func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) {
// Auto-set admin for the only user. // Auto-set admin for the only user.
if user_model.CountUsers(nil) == 1 { if user_model.CountUsers(ctx, nil) == 1 {
u.IsAdmin = true u.IsAdmin = true
u.IsActive = true u.IsActive = true
u.SetLastLogin() u.SetLastLogin()
@ -652,7 +652,7 @@ func Activate(ctx *context.Context) {
return return
} }
user := user_model.VerifyUserActiveCode(code) user := user_model.VerifyUserActiveCode(ctx, code)
// if code is wrong // if code is wrong
if user == nil { if user == nil {
ctx.Data["IsCodeInvalid"] = true ctx.Data["IsCodeInvalid"] = true
@ -679,7 +679,7 @@ func ActivatePost(ctx *context.Context) {
return return
} }
user := user_model.VerifyUserActiveCode(code) user := user_model.VerifyUserActiveCode(ctx, code)
// if code is wrong // if code is wrong
if user == nil { if user == nil {
ctx.Data["IsCodeInvalid"] = true ctx.Data["IsCodeInvalid"] = true
@ -722,7 +722,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) {
return return
} }
if err := user_model.ActivateUserEmail(user.ID, user.Email, true); err != nil { if err := user_model.ActivateUserEmail(ctx, user.ID, user.Email, true); err != nil {
log.Error("Unable to activate email for user: %-v with email: %s: %v", user, user.Email, err) log.Error("Unable to activate email for user: %-v with email: %s: %v", user, user.Email, err)
ctx.ServerError("ActivateUserEmail", err) ctx.ServerError("ActivateUserEmail", err)
return return
@ -767,8 +767,8 @@ func ActivateEmail(ctx *context.Context) {
emailStr := ctx.FormString("email") emailStr := ctx.FormString("email")
// Verify code. // Verify code.
if email := user_model.VerifyActiveEmailCode(code, emailStr); email != nil { if email := user_model.VerifyActiveEmailCode(ctx, code, emailStr); email != nil {
if err := user_model.ActivateEmail(email); err != nil { if err := user_model.ActivateEmail(ctx, email); err != nil {
ctx.ServerError("ActivateEmail", err) ctx.ServerError("ActivateEmail", err)
} }

View File

@ -142,7 +142,7 @@ func LinkAccountPostSignIn(ctx *context.Context) {
return return
} }
u, _, err := auth_service.UserSignIn(signInForm.UserName, signInForm.Password) u, _, err := auth_service.UserSignIn(ctx, signInForm.UserName, signInForm.Password)
if err != nil { if err != nil {
handleSignInError(ctx, signInForm.UserName, &signInForm, tplLinkAccount, "UserLinkAccount", err) handleSignInError(ctx, signInForm.UserName, &signInForm, tplLinkAccount, "UserLinkAccount", err)
return return

View File

@ -859,7 +859,7 @@ func SignInOAuth(ctx *context.Context) {
} }
// try to do a direct callback flow, so we don't authenticate the user again but use the valid accesstoken to get the user // try to do a direct callback flow, so we don't authenticate the user again but use the valid accesstoken to get the user
user, gothUser, err := oAuth2UserLoginCallback(authSource, ctx.Req, ctx.Resp) user, gothUser, err := oAuth2UserLoginCallback(ctx, authSource, ctx.Req, ctx.Resp)
if err == nil && user != nil { if err == nil && user != nil {
// we got the user without going through the whole OAuth2 authentication flow again // we got the user without going through the whole OAuth2 authentication flow again
handleOAuth2SignIn(ctx, authSource, user, gothUser) handleOAuth2SignIn(ctx, authSource, user, gothUser)
@ -909,7 +909,7 @@ func SignInOAuthCallback(ctx *context.Context) {
return return
} }
u, gothUser, err := oAuth2UserLoginCallback(authSource, ctx.Req, ctx.Resp) u, gothUser, err := oAuth2UserLoginCallback(ctx, authSource, ctx.Req, ctx.Resp)
if err != nil { if err != nil {
if user_model.IsErrUserProhibitLogin(err) { if user_model.IsErrUserProhibitLogin(err) {
uplerr := err.(user_model.ErrUserProhibitLogin) uplerr := err.(user_model.ErrUserProhibitLogin)
@ -1208,7 +1208,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
// OAuth2UserLoginCallback attempts to handle the callback from the OAuth2 provider and if successful // OAuth2UserLoginCallback attempts to handle the callback from the OAuth2 provider and if successful
// login the user // login the user
func oAuth2UserLoginCallback(authSource *auth.Source, request *http.Request, response http.ResponseWriter) (*user_model.User, goth.User, error) { func oAuth2UserLoginCallback(ctx *context.Context, authSource *auth.Source, request *http.Request, response http.ResponseWriter) (*user_model.User, goth.User, error) {
oauth2Source := authSource.Cfg.(*oauth2.Source) oauth2Source := authSource.Cfg.(*oauth2.Source)
// Make sure that the response is not an error response. // Make sure that the response is not an error response.
@ -1260,7 +1260,7 @@ func oAuth2UserLoginCallback(authSource *auth.Source, request *http.Request, res
LoginSource: authSource.ID, LoginSource: authSource.ID,
} }
hasUser, err := user_model.GetUser(user) hasUser, err := user_model.GetUser(ctx, user)
if err != nil { if err != nil {
return nil, goth.User{}, err return nil, goth.User{}, err
} }

View File

@ -157,7 +157,7 @@ func signInOpenIDVerify(ctx *context.Context) {
/* Now we should seek for the user and log him in, or prompt /* Now we should seek for the user and log him in, or prompt
* to register if not found */ * to register if not found */
u, err := user_model.GetUserByOpenID(id) u, err := user_model.GetUserByOpenID(ctx, id)
if err != nil { if err != nil {
if !user_model.IsErrUserNotExist(err) { if !user_model.IsErrUserNotExist(err) {
ctx.RenderWithErr(err.Error(), tplSignInOpenID, &forms.SignInOpenIDForm{ ctx.RenderWithErr(err.Error(), tplSignInOpenID, &forms.SignInOpenIDForm{
@ -280,7 +280,7 @@ func ConnectOpenIDPost(ctx *context.Context) {
ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp
ctx.Data["OpenID"] = oid ctx.Data["OpenID"] = oid
u, _, err := auth.UserSignIn(form.UserName, form.Password) u, _, err := auth.UserSignIn(ctx, form.UserName, form.Password)
if err != nil { if err != nil {
handleSignInError(ctx, form.UserName, &form, tplConnectOID, "ConnectOpenIDPost", err) handleSignInError(ctx, form.UserName, &form, tplConnectOID, "ConnectOpenIDPost", err)
return return

View File

@ -114,7 +114,7 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto
} }
// Fail early, don't frustrate the user // Fail early, don't frustrate the user
u := user_model.VerifyUserActiveCode(code) u := user_model.VerifyUserActiveCode(ctx, code)
if u == nil { if u == nil {
ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", fmt.Sprintf("%s/user/forgot_password", setting.AppSubURL)), true) ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", fmt.Sprintf("%s/user/forgot_password", setting.AppSubURL)), true)
return nil, nil return nil, nil

View File

@ -87,7 +87,7 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
opts.Keyword = ctx.FormTrim("q") opts.Keyword = ctx.FormTrim("q")
opts.OrderBy = orderBy opts.OrderBy = orderBy
if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
users, count, err = user_model.SearchUsers(opts) users, count, err = user_model.SearchUsers(ctx, opts)
if err != nil { if err != nil {
ctx.ServerError("SearchUsers", err) ctx.ServerError("SearchUsers", err)
return return
@ -108,7 +108,7 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
ctx.Data["Keyword"] = opts.Keyword ctx.Data["Keyword"] = opts.Keyword
ctx.Data["Total"] = count ctx.Data["Total"] = count
ctx.Data["Users"] = users ctx.Data["Users"] = users
ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus() ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus(ctx)
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled

View File

@ -69,7 +69,7 @@ func Home(ctx *context.Context) {
func HomeSitemap(ctx *context.Context) { func HomeSitemap(ctx *context.Context) {
m := sitemap.NewSitemapIndex() m := sitemap.NewSitemapIndex()
if !setting.Service.Explore.DisableUsersPage { if !setting.Service.Explore.DisableUsersPage {
_, cnt, err := user_model.SearchUsers(&user_model.SearchUserOptions{ _, cnt, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Type: user_model.UserTypeIndividual, Type: user_model.UserTypeIndividual,
ListOptions: db.ListOptions{PageSize: 1}, ListOptions: db.ListOptions{PageSize: 1},
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,

View File

@ -123,7 +123,7 @@ func Home(ctx *context.Context) {
PublicOnly: ctx.Org.PublicMemberOnly, PublicOnly: ctx.Org.PublicMemberOnly,
ListOptions: db.ListOptions{Page: 1, PageSize: 25}, ListOptions: db.ListOptions{Page: 1, PageSize: 25},
} }
members, _, err := organization.FindOrgMembers(opts) members, _, err := organization.FindOrgMembers(ctx, opts)
if err != nil { if err != nil {
ctx.ServerError("FindOrgMembers", err) ctx.ServerError("FindOrgMembers", err)
return return

View File

@ -62,7 +62,7 @@ func Members(ctx *context.Context) {
pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5) pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5)
opts.ListOptions.Page = page opts.ListOptions.Page = page
opts.ListOptions.PageSize = setting.UI.MembersPagingNum opts.ListOptions.PageSize = setting.UI.MembersPagingNum
members, membersIsPublic, err := organization.FindOrgMembers(opts) members, membersIsPublic, err := organization.FindOrgMembers(ctx, opts)
if err != nil { if err != nil {
ctx.ServerError("GetMembers", err) ctx.ServerError("GetMembers", err)
return return
@ -71,7 +71,7 @@ func Members(ctx *context.Context) {
ctx.Data["Members"] = members ctx.Data["Members"] = members
ctx.Data["MembersIsPublicMember"] = membersIsPublic ctx.Data["MembersIsPublicMember"] = membersIsPublic
ctx.Data["MembersIsUserOrgOwner"] = organization.IsUserOrgOwner(members, org.ID) ctx.Data["MembersIsUserOrgOwner"] = organization.IsUserOrgOwner(members, org.ID)
ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus() ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus(ctx)
ctx.HTML(http.StatusOK, tplMembers) ctx.HTML(http.StatusOK, tplMembers)
} }

View File

@ -78,9 +78,9 @@ func TeamsAction(ctx *context.Context) {
ctx.Error(http.StatusNotFound) ctx.Error(http.StatusNotFound)
return return
} }
err = models.AddTeamMember(ctx.Org.Team, ctx.Doer.ID) err = models.AddTeamMember(ctx, ctx.Org.Team, ctx.Doer.ID)
case "leave": case "leave":
err = models.RemoveTeamMember(ctx.Org.Team, ctx.Doer.ID) err = models.RemoveTeamMember(ctx, ctx.Org.Team, ctx.Doer.ID)
if err != nil { if err != nil {
if org_model.IsErrLastOrgOwner(err) { if org_model.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner")) ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
@ -107,7 +107,7 @@ func TeamsAction(ctx *context.Context) {
return return
} }
err = models.RemoveTeamMember(ctx.Org.Team, uid) err = models.RemoveTeamMember(ctx, ctx.Org.Team, uid)
if err != nil { if err != nil {
if org_model.IsErrLastOrgOwner(err) { if org_model.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner")) ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
@ -162,7 +162,7 @@ func TeamsAction(ctx *context.Context) {
if ctx.Org.Team.IsMember(u.ID) { if ctx.Org.Team.IsMember(u.ID) {
ctx.Flash.Error(ctx.Tr("org.teams.add_duplicate_users")) ctx.Flash.Error(ctx.Tr("org.teams.add_duplicate_users"))
} else { } else {
err = models.AddTeamMember(ctx.Org.Team, u.ID) err = models.AddTeamMember(ctx, ctx.Org.Team, u.ID)
} }
page = "team" page = "team"
@ -251,9 +251,9 @@ func TeamsRepoAction(ctx *context.Context) {
case "remove": case "remove":
err = repo_service.RemoveRepositoryFromTeam(ctx, ctx.Org.Team, ctx.FormInt64("repoid")) err = repo_service.RemoveRepositoryFromTeam(ctx, ctx.Org.Team, ctx.FormInt64("repoid"))
case "addall": case "addall":
err = models.AddAllRepositories(ctx.Org.Team) err = models.AddAllRepositories(ctx, ctx.Org.Team)
case "removeall": case "removeall":
err = models.RemoveAllRepositories(ctx.Org.Team) err = models.RemoveAllRepositories(ctx, ctx.Org.Team)
} }
if err != nil { if err != nil {
@ -352,7 +352,7 @@ func NewTeamPost(ctx *context.Context) {
return return
} }
if err := models.NewTeam(t); err != nil { if err := models.NewTeam(ctx, t); err != nil {
ctx.Data["Err_TeamName"] = true ctx.Data["Err_TeamName"] = true
switch { switch {
case org_model.IsErrTeamAlreadyExist(err): case org_model.IsErrTeamAlreadyExist(err):
@ -526,7 +526,7 @@ func EditTeamPost(ctx *context.Context) {
return return
} }
if err := models.UpdateTeam(t, isAuthChanged, isIncludeAllChanged); err != nil { if err := models.UpdateTeam(ctx, t, isAuthChanged, isIncludeAllChanged); err != nil {
ctx.Data["Err_TeamName"] = true ctx.Data["Err_TeamName"] = true
switch { switch {
case org_model.IsErrTeamAlreadyExist(err): case org_model.IsErrTeamAlreadyExist(err):
@ -541,7 +541,7 @@ func EditTeamPost(ctx *context.Context) {
// DeleteTeam response for the delete team request // DeleteTeam response for the delete team request
func DeleteTeam(ctx *context.Context) { func DeleteTeam(ctx *context.Context) {
if err := models.DeleteTeam(ctx.Org.Team); err != nil { if err := models.DeleteTeam(ctx, ctx.Org.Team); err != nil {
ctx.Flash.Error("DeleteTeam: " + err.Error()) ctx.Flash.Error("DeleteTeam: " + err.Error())
} else { } else {
ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success")) ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success"))
@ -583,7 +583,7 @@ func TeamInvitePost(ctx *context.Context) {
return return
} }
if err := models.AddTeamMember(team, ctx.Doer.ID); err != nil { if err := models.AddTeamMember(ctx, team, ctx.Doer.ID); err != nil {
ctx.ServerError("AddTeamMember", err) ctx.ServerError("AddTeamMember", err)
return return
} }

View File

@ -41,7 +41,7 @@ func Branches(ctx *context.Context) {
ctx.Data["IsWriter"] = ctx.Repo.CanWrite(unit.TypeCode) ctx.Data["IsWriter"] = ctx.Repo.CanWrite(unit.TypeCode)
ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror
ctx.Data["CanPull"] = ctx.Repo.CanWrite(unit.TypeCode) || ctx.Data["CanPull"] = ctx.Repo.CanWrite(unit.TypeCode) ||
(ctx.IsSigned && repo_model.HasForkedRepo(ctx.Doer.ID, ctx.Repo.Repository.ID)) (ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID))
ctx.Data["PageIsViewCode"] = true ctx.Data["PageIsViewCode"] = true
ctx.Data["PageIsBranches"] = true ctx.Data["PageIsBranches"] = true

View File

@ -357,7 +357,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
// "OwnForkRepo" // "OwnForkRepo"
var ownForkRepo *repo_model.Repository var ownForkRepo *repo_model.Repository
if ctx.Doer != nil && baseRepo.OwnerID != ctx.Doer.ID { if ctx.Doer != nil && baseRepo.OwnerID != ctx.Doer.ID {
repo := repo_model.GetForkedRepo(ctx.Doer.ID, baseRepo.ID) repo := repo_model.GetForkedRepo(ctx, ctx.Doer.ID, baseRepo.ID)
if repo != nil { if repo != nil {
ownForkRepo = repo ownForkRepo = repo
ctx.Data["OwnForkRepo"] = ownForkRepo ctx.Data["OwnForkRepo"] = ownForkRepo
@ -381,13 +381,13 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
// 5. If the headOwner has a fork of the baseRepo - use that // 5. If the headOwner has a fork of the baseRepo - use that
if !has { if !has {
ci.HeadRepo = repo_model.GetForkedRepo(ci.HeadUser.ID, baseRepo.ID) ci.HeadRepo = repo_model.GetForkedRepo(ctx, ci.HeadUser.ID, baseRepo.ID)
has = ci.HeadRepo != nil has = ci.HeadRepo != nil
} }
// 6. If the baseRepo is a fork and the headUser has a fork of that use that // 6. If the baseRepo is a fork and the headUser has a fork of that use that
if !has && baseRepo.IsFork { if !has && baseRepo.IsFork {
ci.HeadRepo = repo_model.GetForkedRepo(ci.HeadUser.ID, baseRepo.ForkID) ci.HeadRepo = repo_model.GetForkedRepo(ctx, ci.HeadUser.ID, baseRepo.ForkID)
has = ci.HeadRepo != nil has = ci.HeadRepo != nil
} }
@ -804,7 +804,7 @@ func CompareDiff(ctx *context.Context) {
ctx.Data["IsRepoToolbarCommits"] = true ctx.Data["IsRepoToolbarCommits"] = true
ctx.Data["IsDiffCompare"] = true ctx.Data["IsDiffCompare"] = true
templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates) _, templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates)
if len(templateErrs) > 0 { if len(templateErrs) > 0 {
ctx.Flash.Warning(renderErrorOfTemplates(ctx, templateErrs), true) ctx.Flash.Warning(renderErrorOfTemplates(ctx, templateErrs), true)

View File

@ -130,7 +130,7 @@ func MustAllowPulls(ctx *context.Context) {
} }
// User can send pull request if owns a forked repository. // User can send pull request if owns a forked repository.
if ctx.IsSigned && repo_model.HasForkedRepo(ctx.Doer.ID, ctx.Repo.Repository.ID) { if ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) {
ctx.Repo.PullRequest.Allowed = true ctx.Repo.PullRequest.Allowed = true
ctx.Repo.PullRequest.HeadInfoSubURL = url.PathEscape(ctx.Doer.Name) + ":" + util.PathEscapeSegments(ctx.Repo.BranchName) ctx.Repo.PullRequest.HeadInfoSubURL = url.PathEscape(ctx.Doer.Name) + ":" + util.PathEscapeSegments(ctx.Repo.BranchName)
} }
@ -830,10 +830,11 @@ func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull
return labels return labels
} }
func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles []string) map[string]error { // Tries to load and set an issue template. The first return value indicates if a template was loaded.
func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles []string) (bool, map[string]error) {
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
if err != nil { if err != nil {
return nil return false, nil
} }
templateCandidates := make([]string, 0, 1+len(possibleFiles)) templateCandidates := make([]string, 0, 1+len(possibleFiles))
@ -896,20 +897,15 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
ctx.Data["label_ids"] = strings.Join(labelIDs, ",") ctx.Data["label_ids"] = strings.Join(labelIDs, ",")
ctx.Data["Reference"] = template.Ref ctx.Data["Reference"] = template.Ref
ctx.Data["RefEndName"] = git.RefName(template.Ref).ShortName() ctx.Data["RefEndName"] = git.RefName(template.Ref).ShortName()
return templateErrs return true, templateErrs
} }
return templateErrs return false, templateErrs
} }
// NewIssue render creating issue page // NewIssue render creating issue page
func NewIssue(ctx *context.Context) { func NewIssue(ctx *context.Context) {
issueConfig, _ := issue_service.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo) issueConfig, _ := issue_service.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
hasTemplates := issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo) hasTemplates := issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo)
if !issueConfig.BlankIssuesEnabled && hasTemplates {
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if blank issues are disabled, just redirect to the "issues/choose" page with these parameters.
ctx.Redirect(fmt.Sprintf("%s/issues/new/choose?%s", ctx.Repo.Repository.Link(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
return
}
ctx.Data["Title"] = ctx.Tr("repo.issues.new") ctx.Data["Title"] = ctx.Tr("repo.issues.new")
ctx.Data["PageIsIssueList"] = true ctx.Data["PageIsIssueList"] = true
@ -963,7 +959,8 @@ func NewIssue(ctx *context.Context) {
ctx.Data["Tags"] = tags ctx.Data["Tags"] = tags
_, templateErrs := issue_service.GetTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo) _, templateErrs := issue_service.GetTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
if errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates); len(errs) > 0 { templateLoaded, errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
if len(errs) > 0 {
for k, v := range errs { for k, v := range errs {
templateErrs[k] = v templateErrs[k] = v
} }
@ -978,6 +975,12 @@ func NewIssue(ctx *context.Context) {
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWrite(unit.TypeIssues) ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWrite(unit.TypeIssues)
if !issueConfig.BlankIssuesEnabled && hasTemplates && !templateLoaded {
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if blank issues are disabled, just redirect to the "issues/choose" page with these parameters.
ctx.Redirect(fmt.Sprintf("%s/issues/new/choose?%s", ctx.Repo.Repository.Link(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
return
}
ctx.HTML(http.StatusOK, tplIssueNew) ctx.HTML(http.StatusOK, tplIssueNew)
} }

View File

@ -56,7 +56,7 @@ func SetDiffViewStyle(ctx *context.Context) {
} }
ctx.Data["IsSplitStyle"] = style == "split" ctx.Data["IsSplitStyle"] = style == "split"
if err := user_model.UpdateUserDiffViewStyle(ctx.Doer, style); err != nil { if err := user_model.UpdateUserDiffViewStyle(ctx, ctx.Doer, style); err != nil {
ctx.ServerError("ErrUpdateDiffViewStyle", err) ctx.ServerError("ErrUpdateDiffViewStyle", err)
} }
} }

View File

@ -128,18 +128,18 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
ctx.Data["repo_name"] = forkRepo.Name ctx.Data["repo_name"] = forkRepo.Name
ctx.Data["description"] = forkRepo.Description ctx.Data["description"] = forkRepo.Description
ctx.Data["IsPrivate"] = forkRepo.IsPrivate || forkRepo.Owner.Visibility == structs.VisibleTypePrivate ctx.Data["IsPrivate"] = forkRepo.IsPrivate || forkRepo.Owner.Visibility == structs.VisibleTypePrivate
canForkToUser := forkRepo.OwnerID != ctx.Doer.ID && !repo_model.HasForkedRepo(ctx.Doer.ID, forkRepo.ID) canForkToUser := forkRepo.OwnerID != ctx.Doer.ID && !repo_model.HasForkedRepo(ctx, ctx.Doer.ID, forkRepo.ID)
ctx.Data["ForkRepo"] = forkRepo ctx.Data["ForkRepo"] = forkRepo
ownedOrgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx.Doer.ID) ownedOrgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx, ctx.Doer.ID)
if err != nil { if err != nil {
ctx.ServerError("GetOrgsCanCreateRepoByUserID", err) ctx.ServerError("GetOrgsCanCreateRepoByUserID", err)
return nil return nil
} }
var orgs []*organization.Organization var orgs []*organization.Organization
for _, org := range ownedOrgs { for _, org := range ownedOrgs {
if forkRepo.OwnerID != org.ID && !repo_model.HasForkedRepo(org.ID, forkRepo.ID) { if forkRepo.OwnerID != org.ID && !repo_model.HasForkedRepo(ctx, org.ID, forkRepo.ID) {
orgs = append(orgs, org) orgs = append(orgs, org)
} }
} }
@ -233,7 +233,7 @@ func ForkPost(ctx *context.Context) {
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form)
return return
} }
repo := repo_model.GetForkedRepo(ctxUser.ID, traverseParentRepo.ID) repo := repo_model.GetForkedRepo(ctx, ctxUser.ID, traverseParentRepo.ID)
if repo != nil { if repo != nil {
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name)) ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name))
return return

View File

@ -80,7 +80,7 @@ func CommitInfoCache(ctx *context.Context) {
} }
func checkContextUser(ctx *context.Context, uid int64) *user_model.User { func checkContextUser(ctx *context.Context, uid int64) *user_model.User {
orgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx.Doer.ID) orgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx, ctx.Doer.ID)
if err != nil { if err != nil {
ctx.ServerError("GetOrgsCanCreateRepoByUserID", err) ctx.ServerError("GetOrgsCanCreateRepoByUserID", err)
return nil return nil

View File

@ -46,7 +46,7 @@ func SetDefaultBranchPost(ctx *context.Context) {
return return
} }
} }
if err := repo_model.UpdateDefaultBranch(repo); err != nil { if err := repo_model.UpdateDefaultBranch(ctx, repo); err != nil {
ctx.ServerError("SetDefaultBranch", err) ctx.ServerError("SetDefaultBranch", err)
return return
} }

View File

@ -1091,7 +1091,7 @@ func Forks(ctx *context.Context) {
pager := context.NewPagination(ctx.Repo.Repository.NumForks, setting.ItemsPerPage, page, 5) pager := context.NewPagination(ctx.Repo.Repository.NumForks, setting.ItemsPerPage, page, 5)
ctx.Data["Page"] = pager ctx.Data["Page"] = pager
forks, err := repo_model.GetForks(ctx.Repo.Repository, db.ListOptions{ forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, db.ListOptions{
Page: pager.Paginater.Current(), Page: pager.Paginater.Current(),
PageSize: setting.ItemsPerPage, PageSize: setting.ItemsPerPage,
}) })

View File

@ -19,7 +19,7 @@ func Search(ctx *context.Context) {
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
} }
users, maxResults, err := user_model.SearchUsers(&user_model.SearchUserOptions{ users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer, Actor: ctx.Doer,
Keyword: ctx.FormTrim("q"), Keyword: ctx.FormTrim("q"),
UID: ctx.FormInt64("uid"), UID: ctx.FormInt64("uid"),

View File

@ -93,7 +93,7 @@ func EmailPost(ctx *context.Context) {
// Make emailaddress primary. // Make emailaddress primary.
if ctx.FormString("_method") == "PRIMARY" { if ctx.FormString("_method") == "PRIMARY" {
if err := user_model.MakeEmailPrimary(&user_model.EmailAddress{ID: ctx.FormInt64("id")}); err != nil { if err := user_model.MakeEmailPrimary(ctx, &user_model.EmailAddress{ID: ctx.FormInt64("id")}); err != nil {
ctx.ServerError("MakeEmailPrimary", err) ctx.ServerError("MakeEmailPrimary", err)
return return
} }
@ -112,7 +112,7 @@ func EmailPost(ctx *context.Context) {
} }
id := ctx.FormInt64("id") id := ctx.FormInt64("id")
email, err := user_model.GetEmailAddressByID(ctx.Doer.ID, id) email, err := user_model.GetEmailAddressByID(ctx, ctx.Doer.ID, id)
if err != nil { if err != nil {
log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.Doer.ID, id, err) log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.Doer.ID, id, err)
ctx.Redirect(setting.AppSubURL + "/user/settings/account") ctx.Redirect(setting.AppSubURL + "/user/settings/account")
@ -161,7 +161,7 @@ func EmailPost(ctx *context.Context) {
ctx.ServerError("SetEmailPreference", errors.New("option unrecognized")) ctx.ServerError("SetEmailPreference", errors.New("option unrecognized"))
return return
} }
if err := user_model.SetEmailNotifications(ctx.Doer, preference); err != nil { if err := user_model.SetEmailNotifications(ctx, ctx.Doer, preference); err != nil {
log.Error("Set Email Notifications failed: %v", err) log.Error("Set Email Notifications failed: %v", err)
ctx.ServerError("SetEmailNotifications", err) ctx.ServerError("SetEmailNotifications", err)
return return
@ -220,7 +220,7 @@ func EmailPost(ctx *context.Context) {
// DeleteEmail response for delete user's email // DeleteEmail response for delete user's email
func DeleteEmail(ctx *context.Context) { func DeleteEmail(ctx *context.Context) {
if err := user_model.DeleteEmailAddress(&user_model.EmailAddress{ID: ctx.FormInt64("id"), UID: ctx.Doer.ID}); err != nil { if err := user_model.DeleteEmailAddress(ctx, &user_model.EmailAddress{ID: ctx.FormInt64("id"), UID: ctx.Doer.ID}); err != nil {
ctx.ServerError("DeleteEmail", err) ctx.ServerError("DeleteEmail", err)
return return
} }
@ -235,7 +235,7 @@ func DeleteAccount(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsSettingsAccount"] = true ctx.Data["PageIsSettingsAccount"] = true
if _, _, err := auth.UserSignIn(ctx.Doer.Name, ctx.FormString("password")); err != nil { if _, _, err := auth.UserSignIn(ctx, ctx.Doer.Name, ctx.FormString("password")); err != nil {
if user_model.IsErrUserNotExist(err) { if user_model.IsErrUserNotExist(err) {
loadAccountData(ctx) loadAccountData(ctx)
@ -267,7 +267,7 @@ func DeleteAccount(ctx *context.Context) {
} }
func loadAccountData(ctx *context.Context) { func loadAccountData(ctx *context.Context) {
emlist, err := user_model.GetEmailAddresses(ctx.Doer.ID) emlist, err := user_model.GetEmailAddresses(ctx, ctx.Doer.ID)
if err != nil { if err != nil {
ctx.ServerError("GetEmailAddresses", err) ctx.ServerError("GetEmailAddresses", err)
return return

View File

@ -51,7 +51,7 @@ func KeysPost(ctx *context.Context) {
} }
switch form.Type { switch form.Type {
case "principal": case "principal":
content, err := asymkey_model.CheckPrincipalKeyString(ctx.Doer, form.Content) content, err := asymkey_model.CheckPrincipalKeyString(ctx, ctx.Doer, form.Content)
if err != nil { if err != nil {
if db.IsErrSSHDisabled(err) { if db.IsErrSSHDisabled(err) {
ctx.Flash.Info(ctx.Tr("settings.ssh_disabled")) ctx.Flash.Info(ctx.Tr("settings.ssh_disabled"))

View File

@ -114,7 +114,7 @@ func ProfilePost(ctx *context.Context) {
ctx.Doer.Description = form.Description ctx.Doer.Description = form.Description
ctx.Doer.KeepActivityPrivate = form.KeepActivityPrivate ctx.Doer.KeepActivityPrivate = form.KeepActivityPrivate
ctx.Doer.Visibility = form.Visibility ctx.Doer.Visibility = form.Visibility
if err := user_model.UpdateUserSetting(ctx.Doer); err != nil { if err := user_model.UpdateUserSetting(ctx, ctx.Doer); err != nil {
if _, ok := err.(user_model.ErrEmailAlreadyUsed); ok { if _, ok := err.(user_model.ErrEmailAlreadyUsed); ok {
ctx.Flash.Error(ctx.Tr("form.email_been_used")) ctx.Flash.Error(ctx.Tr("form.email_been_used"))
ctx.Redirect(setting.AppSubURL + "/user/settings") ctx.Redirect(setting.AppSubURL + "/user/settings")
@ -379,7 +379,7 @@ func UpdateUIThemePost(ctx *context.Context) {
return return
} }
if err := user_model.UpdateUserTheme(ctx.Doer, form.Theme); err != nil { if err := user_model.UpdateUserTheme(ctx, ctx.Doer, form.Theme); err != nil {
ctx.Flash.Error(ctx.Tr("settings.theme_update_error")) ctx.Flash.Error(ctx.Tr("settings.theme_update_error"))
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
return return
@ -405,7 +405,7 @@ func UpdateUserLang(ctx *context.Context) {
ctx.Doer.Language = form.Language ctx.Doer.Language = form.Language
} }
if err := user_model.UpdateUserSetting(ctx.Doer); err != nil { if err := user_model.UpdateUserSetting(ctx, ctx.Doer); err != nil {
ctx.ServerError("UpdateUserSetting", err) ctx.ServerError("UpdateUserSetting", err)
return return
} }

View File

@ -123,7 +123,7 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore
} }
log.Trace("Basic Authorization: Attempting SignIn for %s", uname) log.Trace("Basic Authorization: Attempting SignIn for %s", uname)
u, source, err := UserSignIn(uname, passwd) u, source, err := UserSignIn(req.Context(), uname, passwd)
if err != nil { if err != nil {
if !user_model.IsErrUserNotExist(err) { if !user_model.IsErrUserNotExist(err) {
log.Error("UserSignIn: %v", err) log.Error("UserSignIn: %v", err)

View File

@ -33,7 +33,7 @@ type Method interface {
// PasswordAuthenticator represents a source of authentication // PasswordAuthenticator represents a source of authentication
type PasswordAuthenticator interface { type PasswordAuthenticator interface {
Authenticate(user *user_model.User, login, password string) (*user_model.User, error) Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error)
} }
// LocalTwoFASkipper represents a source of authentication that can skip local 2fa // LocalTwoFASkipper represents a source of authentication that can skip local 2fa

View File

@ -164,7 +164,7 @@ func (r *ReverseProxy) newUser(req *http.Request) *user_model.User {
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,
} }
if err := user_model.CreateUser(user, &overwriteDefault); err != nil { if err := user_model.CreateUser(req.Context(), user, &overwriteDefault); err != nil {
// FIXME: should I create a system notice? // FIXME: should I create a system notice?
log.Error("CreateUser: %v", err) log.Error("CreateUser: %v", err)
return nil return nil

View File

@ -4,6 +4,7 @@
package auth package auth
import ( import (
"context"
"strings" "strings"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/auth"
@ -20,14 +21,14 @@ import (
) )
// UserSignIn validates user name and password. // UserSignIn validates user name and password.
func UserSignIn(username, password string) (*user_model.User, *auth.Source, error) { func UserSignIn(ctx context.Context, username, password string) (*user_model.User, *auth.Source, error) {
var user *user_model.User var user *user_model.User
isEmail := false isEmail := false
if strings.Contains(username, "@") { if strings.Contains(username, "@") {
isEmail = true isEmail = true
emailAddress := user_model.EmailAddress{LowerEmail: strings.ToLower(strings.TrimSpace(username))} emailAddress := user_model.EmailAddress{LowerEmail: strings.ToLower(strings.TrimSpace(username))}
// check same email // check same email
has, err := db.GetEngine(db.DefaultContext).Get(&emailAddress) has, err := db.GetEngine(ctx).Get(&emailAddress)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -49,7 +50,7 @@ func UserSignIn(username, password string) (*user_model.User, *auth.Source, erro
} }
if user != nil { if user != nil {
hasUser, err := user_model.GetUser(user) hasUser, err := user_model.GetUser(ctx, user)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -69,7 +70,7 @@ func UserSignIn(username, password string) (*user_model.User, *auth.Source, erro
return nil, nil, smtp.ErrUnsupportedLoginType return nil, nil, smtp.ErrUnsupportedLoginType
} }
user, err := authenticator.Authenticate(user, user.LoginName, password) user, err := authenticator.Authenticate(ctx, user, user.LoginName, password)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -100,7 +101,7 @@ func UserSignIn(username, password string) (*user_model.User, *auth.Source, erro
continue continue
} }
authUser, err := authenticator.Authenticate(nil, username, password) authUser, err := authenticator.Authenticate(ctx, nil, username, password)
if err == nil { if err == nil {
if !authUser.ProhibitLogin { if !authUser.ProhibitLogin {

View File

@ -4,9 +4,9 @@
package db package db
import ( import (
"context"
"fmt" "fmt"
"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/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -43,7 +43,7 @@ func (err ErrUserPasswordInvalid) Unwrap() error {
} }
// Authenticate authenticates the provided user against the DB // Authenticate authenticates the provided user against the DB
func Authenticate(user *user_model.User, login, password string) (*user_model.User, error) { func Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error) {
if user == nil { if user == nil {
return nil, user_model.ErrUserNotExist{Name: login} return nil, user_model.ErrUserNotExist{Name: login}
} }
@ -61,7 +61,7 @@ func Authenticate(user *user_model.User, login, password string) (*user_model.Us
if err := user.SetPassword(password); err != nil { if err := user.SetPassword(password); err != nil {
return nil, err return nil, err
} }
if err := user_model.UpdateUserCols(db.DefaultContext, user, "passwd", "passwd_hash_algo", "salt"); err != nil { if err := user_model.UpdateUserCols(ctx, user, "passwd", "passwd_hash_algo", "salt"); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -4,6 +4,8 @@
package db package db
import ( import (
"context"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
) )
@ -23,8 +25,8 @@ func (source *Source) ToDB() ([]byte, error) {
// Authenticate queries if login/password is valid against the PAM, // Authenticate queries if login/password is valid against the PAM,
// and create a local user if success when enabled. // and create a local user if success when enabled.
func (source *Source) Authenticate(user *user_model.User, login, password string) (*user_model.User, error) { func (source *Source) Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error) {
return Authenticate(user, login, password) return Authenticate(ctx, user, login, password)
} }
func init() { func init() {

View File

@ -4,12 +4,12 @@
package ldap package ldap
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
asymkey_model "code.gitea.io/gitea/models/asymkey" asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
auth_module "code.gitea.io/gitea/modules/auth" auth_module "code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -19,7 +19,7 @@ import (
// Authenticate queries if login/password is valid against the LDAP directory pool, // Authenticate queries if login/password is valid against the LDAP directory pool,
// and create a local user if success when enabled. // and create a local user if success when enabled.
func (source *Source) Authenticate(user *user_model.User, userName, password string) (*user_model.User, error) { func (source *Source) Authenticate(ctx context.Context, user *user_model.User, userName, password string) (*user_model.User, error) {
loginName := userName loginName := userName
if user != nil { if user != nil {
loginName = user.LoginName loginName = user.LoginName
@ -33,11 +33,11 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
isAttributeSSHPublicKeySet := len(strings.TrimSpace(source.AttributeSSHPublicKey)) > 0 isAttributeSSHPublicKeySet := len(strings.TrimSpace(source.AttributeSSHPublicKey)) > 0
// Update User admin flag if exist // Update User admin flag if exist
if isExist, err := user_model.IsUserExist(db.DefaultContext, 0, sr.Username); err != nil { if isExist, err := user_model.IsUserExist(ctx, 0, sr.Username); err != nil {
return nil, err return nil, err
} else if isExist { } else if isExist {
if user == nil { if user == nil {
user, err = user_model.GetUserByName(db.DefaultContext, sr.Username) user, err = user_model.GetUserByName(ctx, sr.Username)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -55,7 +55,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
cols = append(cols, "is_restricted") cols = append(cols, "is_restricted")
} }
if len(cols) > 0 { if len(cols) > 0 {
err = user_model.UpdateUserCols(db.DefaultContext, user, cols...) err = user_model.UpdateUserCols(ctx, user, cols...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -94,7 +94,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,
} }
err := user_model.CreateUser(user, overwriteDefault) err := user_model.CreateUser(ctx, user, overwriteDefault)
if err != nil { if err != nil {
return user, err return user, err
} }
@ -116,7 +116,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
if err != nil { if err != nil {
return user, err return user, err
} }
if err := source_service.SyncGroupsToTeams(db.DefaultContext, user, sr.Groups, groupTeamMapping, source.GroupTeamMapRemoval); err != nil { if err := source_service.SyncGroupsToTeams(ctx, user, sr.Groups, groupTeamMapping, source.GroupTeamMapRemoval); err != nil {
return user, err return user, err
} }
} }

View File

@ -28,7 +28,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
var sshKeysNeedUpdate bool var sshKeysNeedUpdate bool
// Find all users with this login type - FIXME: Should this be an iterator? // Find all users with this login type - FIXME: Should this be an iterator?
users, err := user_model.GetUsersBySource(source.authSource) users, err := user_model.GetUsersBySource(ctx, source.authSource)
if err != nil { if err != nil {
log.Error("SyncExternalUsers: %v", err) log.Error("SyncExternalUsers: %v", err)
return err return err
@ -128,7 +128,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,
} }
err = user_model.CreateUser(usr, overwriteDefault) err = user_model.CreateUser(ctx, usr, overwriteDefault)
if err != nil { if err != nil {
log.Error("SyncExternalUsers[%s]: Error creating user %s: %v", source.authSource.Name, su.Username, err) log.Error("SyncExternalUsers[%s]: Error creating user %s: %v", source.authSource.Name, su.Username, err)
} }

View File

@ -4,13 +4,15 @@
package oauth2 package oauth2
import ( import (
"context"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/services/auth/source/db" "code.gitea.io/gitea/services/auth/source/db"
) )
// Authenticate falls back to the db authenticator // Authenticate falls back to the db authenticator
func (source *Source) Authenticate(user *user_model.User, login, password string) (*user_model.User, error) { func (source *Source) Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error) {
return db.Authenticate(user, login, password) return db.Authenticate(ctx, user, login, password)
} }
// NB: Oauth2 does not implement LocalTwoFASkipper for password authentication // NB: Oauth2 does not implement LocalTwoFASkipper for password authentication

View File

@ -4,6 +4,7 @@
package pam package pam
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
@ -18,7 +19,7 @@ import (
// Authenticate queries if login/password is valid against the PAM, // Authenticate queries if login/password is valid against the PAM,
// and create a local user if success when enabled. // and create a local user if success when enabled.
func (source *Source) Authenticate(user *user_model.User, userName, password string) (*user_model.User, error) { func (source *Source) Authenticate(ctx context.Context, user *user_model.User, userName, password string) (*user_model.User, error) {
pamLogin, err := pam.Auth(source.ServiceName, userName, password) pamLogin, err := pam.Auth(source.ServiceName, userName, password)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "Authentication failure") { if strings.Contains(err.Error(), "Authentication failure") {
@ -62,7 +63,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,
} }
if err := user_model.CreateUser(user, overwriteDefault); err != nil { if err := user_model.CreateUser(ctx, user, overwriteDefault); err != nil {
return user, err return user, err
} }

View File

@ -4,6 +4,7 @@
package smtp package smtp
import ( import (
"context"
"errors" "errors"
"net/smtp" "net/smtp"
"net/textproto" "net/textproto"
@ -16,7 +17,7 @@ import (
// Authenticate queries if the provided login/password is authenticates against the SMTP server // Authenticate queries if the provided login/password is authenticates against the SMTP server
// Users will be autoregistered as required // Users will be autoregistered as required
func (source *Source) Authenticate(user *user_model.User, userName, password string) (*user_model.User, error) { func (source *Source) Authenticate(ctx context.Context, user *user_model.User, userName, password string) (*user_model.User, error) {
// Verify allowed domains. // Verify allowed domains.
if len(source.AllowedDomains) > 0 { if len(source.AllowedDomains) > 0 {
idx := strings.Index(userName, "@") idx := strings.Index(userName, "@")
@ -77,7 +78,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
IsActive: util.OptionalBoolTrue, IsActive: util.OptionalBoolTrue,
} }
if err := user_model.CreateUser(user, overwriteDefault); err != nil { if err := user_model.CreateUser(ctx, user, overwriteDefault); err != nil {
return user, err return user, err
} }

View File

@ -100,12 +100,12 @@ func syncGroupsToTeamsCached(ctx context.Context, user *user_model.User, orgTeam
} }
if action == syncAdd && !isMember { if action == syncAdd && !isMember {
if err := models.AddTeamMember(team, user.ID); err != nil { if err := models.AddTeamMember(ctx, team, user.ID); err != nil {
log.Error("group sync: Could not add user to team: %v", err) log.Error("group sync: Could not add user to team: %v", err)
return err return err
} }
} else if action == syncRemove && isMember { } else if action == syncRemove && isMember {
if err := models.RemoveTeamMember(team, user.ID); err != nil { if err := models.RemoveTeamMember(ctx, team, user.ID); err != nil {
log.Error("group sync: Could not remove user from team: %v", err) log.Error("group sync: Could not remove user from team: %v", err)
return err return err
} }

View File

@ -4,6 +4,7 @@
package auth package auth
import ( import (
"context"
"errors" "errors"
"net/http" "net/http"
"strings" "strings"
@ -113,7 +114,7 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore,
log.Error("User '%s' not found", username) log.Error("User '%s' not found", username)
return nil, nil return nil, nil
} }
user, err = s.newUser(username, cfg) user, err = s.newUser(req.Context(), username, cfg)
if err != nil { if err != nil {
log.Error("CreateUser: %v", err) log.Error("CreateUser: %v", err)
return nil, err return nil, err
@ -161,7 +162,7 @@ func (s *SSPI) shouldAuthenticate(req *http.Request) (shouldAuth bool) {
// newUser creates a new user object for the purpose of automatic registration // newUser creates a new user object for the purpose of automatic registration
// and populates its name and email with the information present in request headers. // and populates its name and email with the information present in request headers.
func (s *SSPI) newUser(username string, cfg *sspi.Source) (*user_model.User, error) { func (s *SSPI) newUser(ctx context.Context, username string, cfg *sspi.Source) (*user_model.User, error) {
email := gouuid.New().String() + "@localhost.localdomain" email := gouuid.New().String() + "@localhost.localdomain"
user := &user_model.User{ user := &user_model.User{
Name: username, Name: username,
@ -177,7 +178,7 @@ func (s *SSPI) newUser(username string, cfg *sspi.Source) (*user_model.User, err
KeepEmailPrivate: util.OptionalBoolTrue, KeepEmailPrivate: util.OptionalBoolTrue,
EmailNotificationsPreference: &emailNotificationPreference, EmailNotificationsPreference: &emailNotificationPreference,
} }
if err := user_model.CreateUser(user, overwriteDefault); err != nil { if err := user_model.CreateUser(ctx, user, overwriteDefault); err != nil {
return nil, err return nil, err
} }

View File

@ -107,16 +107,16 @@ func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName strin
} }
// ToBranchProtection convert a ProtectedBranch to api.BranchProtection // ToBranchProtection convert a ProtectedBranch to api.BranchProtection
func ToBranchProtection(bp *git_model.ProtectedBranch) *api.BranchProtection { func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch) *api.BranchProtection {
pushWhitelistUsernames, err := user_model.GetUserNamesByIDs(bp.WhitelistUserIDs) pushWhitelistUsernames, err := user_model.GetUserNamesByIDs(ctx, bp.WhitelistUserIDs)
if err != nil { if err != nil {
log.Error("GetUserNamesByIDs (WhitelistUserIDs): %v", err) log.Error("GetUserNamesByIDs (WhitelistUserIDs): %v", err)
} }
mergeWhitelistUsernames, err := user_model.GetUserNamesByIDs(bp.MergeWhitelistUserIDs) mergeWhitelistUsernames, err := user_model.GetUserNamesByIDs(ctx, bp.MergeWhitelistUserIDs)
if err != nil { if err != nil {
log.Error("GetUserNamesByIDs (MergeWhitelistUserIDs): %v", err) log.Error("GetUserNamesByIDs (MergeWhitelistUserIDs): %v", err)
} }
approvalsWhitelistUsernames, err := user_model.GetUserNamesByIDs(bp.ApprovalsWhitelistUserIDs) approvalsWhitelistUsernames, err := user_model.GetUserNamesByIDs(ctx, bp.ApprovalsWhitelistUserIDs)
if err != nil { if err != nil {
log.Error("GetUserNamesByIDs (ApprovalsWhitelistUserIDs): %v", err) log.Error("GetUserNamesByIDs (ApprovalsWhitelistUserIDs): %v", err)
} }

View File

@ -101,7 +101,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
} }
for i, team := range teams { for i, team := range teams {
if i > 0 { // first team is Owner. if i > 0 { // first team is Owner.
assert.NoError(t, models.NewTeam(team), "%s: NewTeam", team.Name) assert.NoError(t, models.NewTeam(db.DefaultContext, team), "%s: NewTeam", team.Name)
} }
testTeamRepositories(team.ID, teamRepos[i]) testTeamRepositories(team.ID, teamRepos[i])
} }
@ -111,7 +111,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
teams[4].IncludesAllRepositories = true teams[4].IncludesAllRepositories = true
teamRepos[4] = repoIds teamRepos[4] = repoIds
for i, team := range teams { for i, team := range teams {
assert.NoError(t, models.UpdateTeam(team, false, true), "%s: UpdateTeam", team.Name) assert.NoError(t, models.UpdateTeam(db.DefaultContext, team, false, true), "%s: UpdateTeam", team.Name)
testTeamRepositories(team.ID, teamRepos[i]) testTeamRepositories(team.ID, teamRepos[i])
} }

View File

@ -92,7 +92,7 @@ func TestCreateUser(t *testing.T) {
MustChangePassword: false, MustChangePassword: false,
} }
assert.NoError(t, user_model.CreateUser(user)) assert.NoError(t, user_model.CreateUser(db.DefaultContext, user))
assert.NoError(t, DeleteUser(db.DefaultContext, user, false)) assert.NoError(t, DeleteUser(db.DefaultContext, user, false))
} }
@ -177,7 +177,7 @@ func TestCreateUser_Issue5882(t *testing.T) {
for _, v := range tt { for _, v := range tt {
setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation
assert.NoError(t, user_model.CreateUser(v.user)) assert.NoError(t, user_model.CreateUser(db.DefaultContext, v.user))
u, err := user_model.GetUserByEmail(db.DefaultContext, v.user.Email) u, err := user_model.GetUserByEmail(db.DefaultContext, v.user.Email)
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -37,6 +37,9 @@
{{if .Visibility.IsPrivate}} {{if .Visibility.IsPrivate}}
<span class="text gold">{{svg "octicon-lock"}}</span> <span class="text gold">{{svg "octicon-lock"}}</span>
{{end}} {{end}}
{{if eq .Type 3}}{{/* Reserved organization */}}
<span class="ui mini label">{{$.locale.Tr "admin.users.reserved"}}</span>
{{end}}
</td> </td>
<td>{{.NumTeams}}</td> <td>{{.NumTeams}}</td>
<td>{{.NumMembers}}</td> <td>{{.NumMembers}}</td>

View File

@ -84,7 +84,13 @@
<td> <td>
<a href="{{$.Link}}/{{.ID}}">{{.Name}}</a> <a href="{{$.Link}}/{{.ID}}">{{.Name}}</a>
{{if .IsAdmin}} {{if .IsAdmin}}
<span class="ui basic label">{{$.locale.Tr "admin.users.admin"}}</span> <span class="ui mini label">{{$.locale.Tr "admin.users.admin"}}</span>
{{else if eq 2 .Type}}{{/* Reserved user */}}
<span class="ui mini label">{{$.locale.Tr "admin.users.reserved"}}</span>
{{else if eq 4 .Type}}{{/* Bot "user" */}}
<span class="ui mini label">{{$.locale.Tr "admin.users.bot"}}</span>
{{else if eq 5 .Type}}{{/* Remote user */}}
<span class="ui mini label">{{$.locale.Tr "admin.users.remote"}}</span>
{{end}} {{end}}
</td> </td>
<td class="gt-ellipsis gt-max-width-12rem">{{.Email}}</td> <td class="gt-ellipsis gt-max-width-12rem">{{.Email}}</td>

View File

@ -428,7 +428,7 @@ func TestLDAPGroupTeamSyncAddMember(t *testing.T) {
isMember, err := organization.IsTeamMember(db.DefaultContext, usersOrgs[0].ID, team.ID, user.ID) isMember, err := organization.IsTeamMember(db.DefaultContext, usersOrgs[0].ID, team.ID, user.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, isMember, "Membership should be added to the right team") assert.True(t, isMember, "Membership should be added to the right team")
err = models.RemoveTeamMember(team, user.ID) err = models.RemoveTeamMember(db.DefaultContext, team, user.ID)
assert.NoError(t, err) assert.NoError(t, err)
err = models.RemoveOrgUser(usersOrgs[0].ID, user.ID) err = models.RemoveOrgUser(usersOrgs[0].ID, user.ID)
assert.NoError(t, err) assert.NoError(t, err)
@ -460,7 +460,7 @@ func TestLDAPGroupTeamSyncRemoveMember(t *testing.T) {
}) })
err = organization.AddOrgUser(org.ID, user.ID) err = organization.AddOrgUser(org.ID, user.ID)
assert.NoError(t, err) assert.NoError(t, err)
err = models.AddTeamMember(team, user.ID) err = models.AddTeamMember(db.DefaultContext, team, user.ID)
assert.NoError(t, err) assert.NoError(t, err)
isMember, err := organization.IsOrganizationMember(db.DefaultContext, org.ID, user.ID) isMember, err := organization.IsOrganizationMember(db.DefaultContext, org.ID, user.ID)
assert.NoError(t, err) assert.NoError(t, err)