This commit is contained in:
@@ -21,24 +21,24 @@ import (
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
_ "image/jpeg" // Needed for jpeg support
|
||||
"gitea.dev/models/auth"
|
||||
"gitea.dev/models/db"
|
||||
"gitea.dev/modules/auth/openid"
|
||||
"gitea.dev/modules/auth/password/hash"
|
||||
"gitea.dev/modules/base"
|
||||
"gitea.dev/modules/container"
|
||||
"gitea.dev/modules/git"
|
||||
"gitea.dev/modules/htmlutil"
|
||||
"gitea.dev/modules/httplib"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/optional"
|
||||
"gitea.dev/modules/setting"
|
||||
"gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/timeutil"
|
||||
"gitea.dev/modules/util"
|
||||
"gitea.dev/modules/validation"
|
||||
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/auth/openid"
|
||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/htmlutil"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
_ "image/jpeg" // Needed for jpeg support
|
||||
|
||||
"golang.org/x/text/runes"
|
||||
"golang.org/x/text/transform"
|
||||
@@ -244,12 +244,15 @@ func (u *User) IsOAuth2() bool {
|
||||
return u.LoginType == auth.OAuth2
|
||||
}
|
||||
|
||||
// MaxCreationLimit returns the number of repositories a user is allowed to create
|
||||
// MaxCreationLimit returns the number of repositories a user or an organization is allowed to create
|
||||
func (u *User) MaxCreationLimit() int {
|
||||
if u.MaxRepoCreation <= -1 {
|
||||
return setting.Repository.MaxCreationLimit
|
||||
if u.MaxRepoCreation > -1 {
|
||||
return u.MaxRepoCreation
|
||||
}
|
||||
return u.MaxRepoCreation
|
||||
if u.IsOrganization() {
|
||||
return setting.Repository.OrgMaxCreationLimit
|
||||
}
|
||||
return setting.Repository.UserMaxCreationLimit
|
||||
}
|
||||
|
||||
// CanCreateRepoIn checks whether the doer(u) can create a repository in the owner
|
||||
@@ -264,13 +267,11 @@ func (u *User) CanCreateRepoIn(owner *User) bool {
|
||||
return true
|
||||
}
|
||||
const noLimit = -1
|
||||
if owner.MaxRepoCreation == noLimit {
|
||||
if setting.Repository.MaxCreationLimit == noLimit {
|
||||
return true
|
||||
}
|
||||
return owner.NumRepos < setting.Repository.MaxCreationLimit
|
||||
limit := owner.MaxCreationLimit()
|
||||
if limit == noLimit {
|
||||
return true
|
||||
}
|
||||
return owner.NumRepos < owner.MaxRepoCreation
|
||||
return owner.NumRepos < limit
|
||||
}
|
||||
|
||||
// CanCreateOrganization returns true if user can create organisation.
|
||||
@@ -339,7 +340,7 @@ func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListO
|
||||
And(isUserVisibleToViewerCond(viewer))
|
||||
|
||||
if listOptions.Page > 0 {
|
||||
sess = db.SetSessionPagination(sess, &listOptions)
|
||||
db.SetSessionPagination(sess, &listOptions)
|
||||
|
||||
users := make([]*User, 0, listOptions.PageSize)
|
||||
count, err := sess.FindAndCount(&users)
|
||||
@@ -361,7 +362,7 @@ func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListO
|
||||
And(isUserVisibleToViewerCond(viewer))
|
||||
|
||||
if listOptions.Page > 0 {
|
||||
sess = db.SetSessionPagination(sess, &listOptions)
|
||||
db.SetSessionPagination(sess, &listOptions)
|
||||
|
||||
users := make([]*User, 0, listOptions.PageSize)
|
||||
count, err := sess.FindAndCount(&users)
|
||||
@@ -532,10 +533,7 @@ const SaltByteLength = 16
|
||||
|
||||
// GetUserSalt returns a random user salt token.
|
||||
func GetUserSalt() (string, error) {
|
||||
rBytes, err := util.CryptoRandomBytes(SaltByteLength)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
rBytes := util.CryptoRandomBytes(SaltByteLength)
|
||||
// Returns a 32-byte long string.
|
||||
return hex.EncodeToString(rBytes), nil
|
||||
}
|
||||
@@ -625,6 +623,7 @@ var (
|
||||
"sitemap.xml", // search engine sitemap
|
||||
"ssh_info", // agit info
|
||||
"swagger.v1.json",
|
||||
"openapi3.v1.json",
|
||||
|
||||
"ghost", // reserved name for deleted users (id: -1)
|
||||
"gitea-actions", // gitea builtin user (id: -2)
|
||||
@@ -1149,14 +1148,7 @@ func GetUsersBySource(ctx context.Context, s *auth.Source) ([]*User, error) {
|
||||
return users, err
|
||||
}
|
||||
|
||||
// UserCommit represents a commit with validation of user.
|
||||
type UserCommit struct { //revive:disable-line:exported
|
||||
User *User
|
||||
*git.Commit
|
||||
}
|
||||
|
||||
// ValidateCommitWithEmail check if author's e-mail of commit is corresponding to a user.
|
||||
func ValidateCommitWithEmail(ctx context.Context, c *git.Commit) *User {
|
||||
func GetUserByGitAuthor(ctx context.Context, c *git.Commit) *User {
|
||||
if c.Author == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -1167,33 +1159,6 @@ func ValidateCommitWithEmail(ctx context.Context, c *git.Commit) *User {
|
||||
return u
|
||||
}
|
||||
|
||||
// ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
|
||||
func ValidateCommitsWithEmails(ctx context.Context, oldCommits []*git.Commit) ([]*UserCommit, error) {
|
||||
var (
|
||||
newCommits = make([]*UserCommit, 0, len(oldCommits))
|
||||
emailSet = make(container.Set[string])
|
||||
)
|
||||
for _, c := range oldCommits {
|
||||
if c.Author != nil {
|
||||
emailSet.Add(c.Author.Email)
|
||||
}
|
||||
}
|
||||
|
||||
emailUserMap, err := GetUsersByEmails(ctx, emailSet.Values())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, c := range oldCommits {
|
||||
user := emailUserMap.GetByEmail(c.Author.Email) // FIXME: why ValidateCommitsWithEmails uses "Author", but ParseCommitsWithSignature uses "Committer"?
|
||||
newCommits = append(newCommits, &UserCommit{
|
||||
User: user,
|
||||
Commit: c,
|
||||
})
|
||||
}
|
||||
return newCommits, nil
|
||||
}
|
||||
|
||||
type EmailUserMap struct {
|
||||
m map[string]*User
|
||||
}
|
||||
@@ -1204,7 +1169,7 @@ func (eum *EmailUserMap) GetByEmail(email string) *User {
|
||||
|
||||
func GetUsersByEmails(ctx context.Context, emails []string) (*EmailUserMap, error) {
|
||||
if len(emails) == 0 {
|
||||
return nil, nil //nolint:nilnil // return nil when there are no emails to look up
|
||||
return &EmailUserMap{}, nil
|
||||
}
|
||||
|
||||
needCheckEmails := make(container.Set[string])
|
||||
@@ -1311,8 +1276,7 @@ func GetUserByEmail(ctx context.Context, email string) (*User, error) {
|
||||
|
||||
email = strings.ToLower(email)
|
||||
// Otherwise, check in alternative list for activated email addresses
|
||||
emailAddress := &EmailAddress{LowerEmail: email, IsActivated: true}
|
||||
has, err := db.GetEngine(ctx).Get(emailAddress)
|
||||
emailAddress, has, err := db.Get[EmailAddress](ctx, builder.Eq{"lower_email": email, "is_activated": true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1332,13 +1296,29 @@ func GetUserByEmail(ctx context.Context, email string) (*User, error) {
|
||||
return nil, ErrUserNotExist{Name: email}
|
||||
}
|
||||
|
||||
func GetIndividualUser(ctx context.Context, user *User) (bool, error) {
|
||||
// FIXME: the design is wrong, empty User fields won't apply, this function should be removed in the future
|
||||
has, err := db.GetEngine(ctx).Get(user)
|
||||
func GetIndividualUserByPrimaryEmail(ctx context.Context, email string) (*User, error) {
|
||||
email = strings.ToLower(strings.TrimSpace(email))
|
||||
if len(email) == 0 {
|
||||
return nil, ErrUserNotExist{Name: email}
|
||||
}
|
||||
|
||||
user, has, err := db.Get[User](ctx, builder.Eq{"email": email, "type": UserTypeIndividual})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !has {
|
||||
return nil, ErrUserNotExist{Name: email}
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func GetIndividualUserByLoginSource(ctx context.Context, loginType auth.Type, loginSource int64, loginName string) (*User, bool, error) {
|
||||
user, has, err := db.Get[User](ctx, builder.Eq{"login_type": loginType, "login_source": loginSource, "login_name": loginName})
|
||||
if has && user.Type != UserTypeIndividual {
|
||||
has = false
|
||||
user = nil
|
||||
}
|
||||
return has, err
|
||||
return user, has, err
|
||||
}
|
||||
|
||||
// GetUserByOpenID returns the user object by given OpenID if exists.
|
||||
@@ -1472,16 +1452,6 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// CountWrongUserType count OrgUser who have wrong type
|
||||
func CountWrongUserType(ctx context.Context) (int64, error) {
|
||||
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
|
||||
func FixWrongUserType(ctx context.Context) (int64, error) {
|
||||
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 {
|
||||
if setting.UI.DefaultShowFullName {
|
||||
return "full_name, name"
|
||||
|
||||
Reference in New Issue
Block a user