aboutsummaryrefslogtreecommitdiff
path: root/internal/db
diff options
context:
space:
mode:
authorJoe Chen <jc@unknwon.io>2022-10-22 14:41:40 +0800
committerGitHub <noreply@github.com>2022-10-22 14:41:40 +0800
commitc502dc6ed888a4cf2c8b36176585f4166536ab6d (patch)
tree71e3f758069dc2435eecb88ae786b2efaaa972f9 /internal/db
parent260e990be75885e1a560df449dacdeecafeffdcf (diff)
refactor(db): move some methods from `user.go` to `users.go` (#7195)
Diffstat (limited to 'internal/db')
-rw-r--r--internal/db/issue_mail.go13
-rw-r--r--internal/db/org.go2
-rw-r--r--internal/db/repo.go8
-rw-r--r--internal/db/user.go153
-rw-r--r--internal/db/user_mail.go2
-rw-r--r--internal/db/users.go169
-rw-r--r--internal/db/users_test.go2
7 files changed, 169 insertions, 180 deletions
diff --git a/internal/db/issue_mail.go b/internal/db/issue_mail.go
index c9b5471a..91d89a41 100644
--- a/internal/db/issue_mail.go
+++ b/internal/db/issue_mail.go
@@ -13,6 +13,7 @@ import (
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/email"
"gogs.io/gogs/internal/markup"
+ "gogs.io/gogs/internal/userutil"
)
func (issue *Issue) MailSubject() string {
@@ -36,12 +37,14 @@ func (this mailerUser) Email() string {
return this.user.Email
}
-func (this mailerUser) GenerateActivateCode() string {
- return this.user.GenerateActivateCode()
-}
-
func (this mailerUser) GenerateEmailActivateCode(email string) string {
- return this.user.GenerateEmailActivateCode(email)
+ return userutil.GenerateActivateCode(
+ this.user.ID,
+ email,
+ this.user.Name,
+ this.user.Passwd,
+ this.user.Rands,
+ )
}
func NewMailerUser(u *User) email.User {
diff --git a/internal/db/org.go b/internal/db/org.go
index cf984f14..c5c55f44 100644
--- a/internal/db/org.go
+++ b/internal/db/org.go
@@ -177,7 +177,7 @@ func GetOrgByName(name string) (*User, error) {
}
u := &User{
LowerName: strings.ToLower(name),
- Type: UserOrganization,
+ Type: UserTypeOrganization,
}
has, err := x.Get(u)
if err != nil {
diff --git a/internal/db/repo.go b/internal/db/repo.go
index 94f50dfe..97228015 100644
--- a/internal/db/repo.go
+++ b/internal/db/repo.go
@@ -1157,8 +1157,8 @@ func (err ErrReachLimitOfRepo) Error() string {
// CreateRepository creates a repository for given user or organization.
func CreateRepository(doer, owner *User, opts CreateRepoOptionsLegacy) (_ *Repository, err error) {
- if !owner.CanCreateRepo() {
- return nil, ErrReachLimitOfRepo{Limit: owner.RepoCreationNum()}
+ if !owner.canCreateRepo() {
+ return nil, ErrReachLimitOfRepo{Limit: owner.maxNumRepos()}
}
repo := &Repository{
@@ -2467,8 +2467,8 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool, error) {
// ForkRepository creates a fork of target repository under another user domain.
func ForkRepository(doer, owner *User, baseRepo *Repository, name, desc string) (_ *Repository, err error) {
- if !owner.CanCreateRepo() {
- return nil, ErrReachLimitOfRepo{Limit: owner.RepoCreationNum()}
+ if !owner.canCreateRepo() {
+ return nil, ErrReachLimitOfRepo{Limit: owner.maxNumRepos()}
}
repo := &Repository{
diff --git a/internal/db/user.go b/internal/db/user.go
index 08b7e09e..33b69af1 100644
--- a/internal/db/user.go
+++ b/internal/db/user.go
@@ -27,7 +27,6 @@ import (
"xorm.io/xorm"
"github.com/gogs/git-module"
- api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/avatar"
"gogs.io/gogs/internal/conf"
@@ -37,77 +36,13 @@ import (
"gogs.io/gogs/internal/tool"
)
-// USER_AVATAR_URL_PREFIX is used to identify a URL is to access user avatar.
-const USER_AVATAR_URL_PREFIX = "avatars"
-
-type UserType int
-
-const (
- UserIndividual UserType = iota // Historic reason to make it starts at 0.
- UserOrganization
-)
-
-// User represents the object of individual and member of organization.
-type User struct {
- ID int64 `gorm:"primaryKey"`
- LowerName string `xorm:"UNIQUE NOT NULL" gorm:"unique;not null"`
- Name string `xorm:"UNIQUE NOT NULL" gorm:"not null"`
- FullName string
- // Email is the primary email address (to be used for communication)
- Email string `xorm:"NOT NULL" gorm:"not null"`
- Passwd string `xorm:"NOT NULL" gorm:"not null"`
- LoginSource int64 `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
- LoginName string
- Type UserType
- OwnedOrgs []*User `xorm:"-" gorm:"-" json:"-"`
- Orgs []*User `xorm:"-" gorm:"-" json:"-"`
- Repos []*Repository `xorm:"-" gorm:"-" json:"-"`
- Location string
- Website string
- Rands string `xorm:"VARCHAR(10)" gorm:"type:VARCHAR(10)"`
- Salt string `xorm:"VARCHAR(10)" gorm:"type:VARCHAR(10)"`
-
- Created time.Time `xorm:"-" gorm:"-" json:"-"`
- CreatedUnix int64
- Updated time.Time `xorm:"-" gorm:"-" json:"-"`
- UpdatedUnix int64
-
- // Remember visibility choice for convenience, true for private
- LastRepoVisibility bool
- // Maximum repository creation limit, -1 means use global default
- MaxRepoCreation int `xorm:"NOT NULL DEFAULT -1" gorm:"not null;default:-1"`
-
- // Permissions
- IsActive bool // Activate primary email
- IsAdmin bool
- AllowGitHook bool
- AllowImportLocal bool // Allow migrate repository by local path
- ProhibitLogin bool
-
- // Avatar
- Avatar string `xorm:"VARCHAR(2048) NOT NULL" gorm:"type:VARCHAR(2048);not null"`
- AvatarEmail string `xorm:"NOT NULL" gorm:"not null"`
- UseCustomAvatar bool
-
- // Counters
- NumFollowers int
- NumFollowing int `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
- NumStars int
- NumRepos int
-
- // For organization
- Description string
- NumTeams int
- NumMembers int
- Teams []*Team `xorm:"-" gorm:"-" json:"-"`
- Members []*User `xorm:"-" gorm:"-" json:"-"`
-}
-
+// TODO(unknwon): Delete me once refactoring is done.
func (u *User) BeforeInsert() {
u.CreatedUnix = time.Now().Unix()
u.UpdatedUnix = u.CreatedUnix
}
+// TODO(unknwon): Refactoring together with methods that do updates.
func (u *User) BeforeUpdate() {
if u.MaxRepoCreation < -1 {
u.MaxRepoCreation = -1
@@ -115,6 +50,7 @@ func (u *User) BeforeUpdate() {
u.UpdatedUnix = time.Now().Unix()
}
+// TODO(unknwon): Delete me once refactoring is done.
func (u *User) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
@@ -124,81 +60,6 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) {
}
}
-func (u *User) APIFormat() *api.User {
- return &api.User{
- ID: u.ID,
- UserName: u.Name,
- Login: u.Name,
- FullName: u.FullName,
- Email: u.Email,
- AvatarUrl: u.AvatarLink(),
- }
-}
-
-func (u *User) RepoCreationNum() int {
- if u.MaxRepoCreation <= -1 {
- return conf.Repository.MaxCreationLimit
- }
- return u.MaxRepoCreation
-}
-
-func (u *User) CanCreateRepo() bool {
- if u.MaxRepoCreation <= -1 {
- if conf.Repository.MaxCreationLimit <= -1 {
- return true
- }
- return u.NumRepos < conf.Repository.MaxCreationLimit
- }
- return u.NumRepos < u.MaxRepoCreation
-}
-
-func (u *User) CanCreateOrganization() bool {
- return !conf.Admin.DisableRegularOrgCreation || u.IsAdmin
-}
-
-// CanEditGitHook returns true if user can edit Git hooks.
-func (u *User) CanEditGitHook() bool {
- return u.IsAdmin || u.AllowGitHook
-}
-
-// CanImportLocal returns true if user can migrate repository by local path.
-func (u *User) CanImportLocal() bool {
- return conf.Repository.EnableLocalPathMigration && (u.IsAdmin || u.AllowImportLocal)
-}
-
-// DashboardLink returns the user dashboard page link.
-func (u *User) DashboardLink() string {
- if u.IsOrganization() {
- return conf.Server.Subpath + "/org/" + u.Name + "/dashboard/"
- }
- return conf.Server.Subpath + "/"
-}
-
-// HomeLink returns the user or organization home page link.
-func (u *User) HomeLink() string {
- return conf.Server.Subpath + "/" + u.Name
-}
-
-func (u *User) HTMLURL() string {
- return conf.Server.ExternalURL + u.Name
-}
-
-// GenerateEmailActivateCode generates an activate code based on user information and given e-mail.
-func (u *User) GenerateEmailActivateCode(email string) string {
- code := tool.CreateTimeLimitCode(
- com.ToStr(u.ID)+email+u.LowerName+u.Passwd+u.Rands,
- conf.Auth.ActivateCodeLives, nil)
-
- // Add tail hex username
- code += hex.EncodeToString([]byte(u.LowerName))
- return code
-}
-
-// GenerateActivateCode generates an activate code based on user information.
-func (u *User) GenerateActivateCode() string {
- return u.GenerateEmailActivateCode(u.Email)
-}
-
// CustomAvatarPath returns user custom avatar file path.
func (u *User) CustomAvatarPath() string {
return filepath.Join(conf.Picture.AvatarUploadPath, com.ToStr(u.ID))
@@ -246,7 +107,7 @@ func (u *User) RelAvatarLink() string {
if !com.IsExist(u.CustomAvatarPath()) {
return defaultImgUrl
}
- return fmt.Sprintf("%s/%s/%d", conf.Server.Subpath, USER_AVATAR_URL_PREFIX, u.ID)
+ return fmt.Sprintf("%s/%s/%d", conf.Server.Subpath, conf.UsersAvatarURLPath, u.ID)
case conf.Picture.DisableGravatar:
if !com.IsExist(u.CustomAvatarPath()) {
if err := u.GenerateRandomAvatar(); err != nil {
@@ -254,7 +115,7 @@ func (u *User) RelAvatarLink() string {
}
}
- return fmt.Sprintf("%s/%s/%d", conf.Server.Subpath, USER_AVATAR_URL_PREFIX, u.ID)
+ return fmt.Sprintf("%s/%s/%d", conf.Server.Subpath, conf.UsersAvatarURLPath, u.ID)
}
return tool.AvatarLink(u.AvatarEmail)
}
@@ -374,7 +235,7 @@ func (u *User) IsWriterOfRepo(repo *Repository) bool {
// IsOrganization returns true if user is actually a organization.
func (u *User) IsOrganization() bool {
- return u.Type == UserOrganization
+ return u.Type == UserTypeOrganization
}
// IsUserOrgOwner returns true if user is in the owner team of given organization.
@@ -434,7 +295,7 @@ func (u *User) GetOrganizations(showPrivate bool) error {
}
u.Orgs = make([]*User, 0, len(orgIDs))
- if err = x.Where("type = ?", UserOrganization).In("id", orgIDs).Find(&u.Orgs); err != nil {
+ if err = x.Where("type = ?", UserTypeOrganization).In("id", orgIDs).Find(&u.Orgs); err != nil {
return err
}
return nil
diff --git a/internal/db/user_mail.go b/internal/db/user_mail.go
index fc6356fe..ea6c1a73 100644
--- a/internal/db/user_mail.go
+++ b/internal/db/user_mail.go
@@ -69,7 +69,7 @@ func isEmailUsed(e Engine, email string) (bool, error) {
}
// We need to check primary email of users as well.
- return e.Where("type=?", UserIndividual).And("email=?", email).Get(new(User))
+ return e.Where("type=?", UserTypeIndividual).And("email=?", email).Get(new(User))
}
// IsEmailUsed returns true if the email has been used.
diff --git a/internal/db/users.go b/internal/db/users.go
index d52cfc4c..94bc25f5 100644
--- a/internal/db/users.go
+++ b/internal/db/users.go
@@ -11,10 +11,12 @@ import (
"time"
"github.com/go-macaron/binding"
+ api "github.com/gogs/go-gogs-client"
"github.com/pkg/errors"
"gorm.io/gorm"
"gogs.io/gogs/internal/auth"
+ "gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/cryptoutil"
"gogs.io/gogs/internal/errutil"
)
@@ -54,27 +56,6 @@ type UsersStore interface {
var Users UsersStore
-// BeforeCreate implements the GORM create hook.
-func (u *User) BeforeCreate(tx *gorm.DB) error {
- if u.CreatedUnix == 0 {
- u.CreatedUnix = tx.NowFunc().Unix()
- u.UpdatedUnix = u.CreatedUnix
- }
- return nil
-}
-
-// AfterFind implements the GORM query hook.
-func (u *User) AfterFind(_ *gorm.DB) error {
- u.Created = time.Unix(u.CreatedUnix, 0).Local()
- u.Updated = time.Unix(u.UpdatedUnix, 0).Local()
- return nil
-}
-
-// IsLocal returns true if user is created as local account.
-func (u *User) IsLocal() bool {
- return u.LoginSource <= 0
-}
-
var _ UsersStore = (*users)(nil)
type users struct {
@@ -303,7 +284,7 @@ func (db *users) GetByEmail(ctx context.Context, email string) (*User, error) {
// First try to find the user by primary email
user := new(User)
err := db.WithContext(ctx).
- Where("email = ? AND type = ? AND is_active = ?", email, UserIndividual, true).
+ Where("email = ? AND type = ? AND is_active = ?", email, UserTypeIndividual, true).
First(user).
Error
if err == nil {
@@ -357,3 +338,147 @@ func (db *users) HasForkedRepository(ctx context.Context, userID, repoID int64)
db.WithContext(ctx).Model(new(Repository)).Where("owner_id = ? AND fork_id = ?", userID, repoID).Count(&count)
return count > 0
}
+
+// UserType indicates the type of the user account.
+type UserType int
+
+const (
+ UserTypeIndividual UserType = iota // NOTE: Historic reason to make it starts at 0.
+ UserTypeOrganization
+)
+
+// User represents the object of an individual or an organization.
+type User struct {
+ ID int64 `gorm:"primaryKey"`
+ LowerName string `xorm:"UNIQUE NOT NULL" gorm:"unique;not null"`
+ Name string `xorm:"UNIQUE NOT NULL" gorm:"not null"`
+ FullName string
+ // Email is the primary email address (to be used for communication)
+ Email string `xorm:"NOT NULL" gorm:"not null"`
+ Passwd string `xorm:"NOT NULL" gorm:"not null"`
+ LoginSource int64 `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
+ LoginName string
+ Type UserType
+ OwnedOrgs []*User `xorm:"-" gorm:"-" json:"-"`
+ Orgs []*User `xorm:"-" gorm:"-" json:"-"`
+ Repos []*Repository `xorm:"-" gorm:"-" json:"-"`
+ Location string
+ Website string
+ Rands string `xorm:"VARCHAR(10)" gorm:"type:VARCHAR(10)"`
+ Salt string `xorm:"VARCHAR(10)" gorm:"type:VARCHAR(10)"`
+
+ Created time.Time `xorm:"-" gorm:"-" json:"-"`
+ CreatedUnix int64
+ Updated time.Time `xorm:"-" gorm:"-" json:"-"`
+ UpdatedUnix int64
+
+ // Remember visibility choice for convenience, true for private
+ LastRepoVisibility bool
+ // Maximum repository creation limit, -1 means use global default
+ MaxRepoCreation int `xorm:"NOT NULL DEFAULT -1" gorm:"not null;default:-1"`
+
+ // Permissions
+ IsActive bool // Activate primary email
+ IsAdmin bool
+ AllowGitHook bool
+ AllowImportLocal bool // Allow migrate repository by local path
+ ProhibitLogin bool
+
+ // Avatar
+ Avatar string `xorm:"VARCHAR(2048) NOT NULL" gorm:"type:VARCHAR(2048);not null"`
+ AvatarEmail string `xorm:"NOT NULL" gorm:"not null"`
+ UseCustomAvatar bool
+
+ // Counters
+ NumFollowers int
+ NumFollowing int `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
+ NumStars int
+ NumRepos int
+
+ // For organization
+ Description string
+ NumTeams int
+ NumMembers int
+ Teams []*Team `xorm:"-" gorm:"-" json:"-"`
+ Members []*User `xorm:"-" gorm:"-" json:"-"`
+}
+
+// BeforeCreate implements the GORM create hook.
+func (u *User) BeforeCreate(tx *gorm.DB) error {
+ if u.CreatedUnix == 0 {
+ u.CreatedUnix = tx.NowFunc().Unix()
+ u.UpdatedUnix = u.CreatedUnix
+ }
+ return nil
+}
+
+// AfterFind implements the GORM query hook.
+func (u *User) AfterFind(_ *gorm.DB) error {
+ u.Created = time.Unix(u.CreatedUnix, 0).Local()
+ u.Updated = time.Unix(u.UpdatedUnix, 0).Local()
+ return nil
+}
+
+// IsLocal returns true if user is created as local account.
+func (u *User) IsLocal() bool {
+ return u.LoginSource <= 0
+}
+
+// APIFormat returns the API format of a user.
+func (u *User) APIFormat() *api.User {
+ return &api.User{
+ ID: u.ID,
+ UserName: u.Name,
+ Login: u.Name,
+ FullName: u.FullName,
+ Email: u.Email,
+ AvatarUrl: u.AvatarLink(),
+ }
+}
+
+// maxNumRepos returns the maximum number of repositories that the user can have
+// direct ownership.
+func (u *User) maxNumRepos() int {
+ if u.MaxRepoCreation <= -1 {
+ return conf.Repository.MaxCreationLimit
+ }
+ return u.MaxRepoCreation
+}
+
+// canCreateRepo returns true if the user can create a repository.
+func (u *User) canCreateRepo() bool {
+ return u.maxNumRepos() <= -1 || u.NumRepos < u.maxNumRepos()
+}
+
+// CanCreateOrganization returns true if user can create organizations.
+func (u *User) CanCreateOrganization() bool {
+ return !conf.Admin.DisableRegularOrgCreation || u.IsAdmin
+}
+
+// CanEditGitHook returns true if user can edit Git hooks.
+func (u *User) CanEditGitHook() bool {
+ return u.IsAdmin || u.AllowGitHook
+}
+
+// CanImportLocal returns true if user can migrate repositories by local path.
+func (u *User) CanImportLocal() bool {
+ return conf.Repository.EnableLocalPathMigration && (u.IsAdmin || u.AllowImportLocal)
+}
+
+// HomeURLPath returns the URL path to the user or organization home page.
+//
+// TODO(unknwon): This is also used in templates, which should be fixed by
+// having a dedicated type `template.User` and move this to the "userutil"
+// package.
+func (u *User) HomeURLPath() string {
+ return conf.Server.Subpath + "/" + u.Name
+}
+
+// HTMLURL returns the HTML URL to the user or organization home page.
+//
+// TODO(unknwon): This is also used in templates, which should be fixed by
+// having a dedicated type `template.User` and move this to the "userutil"
+// package.
+func (u *User) HTMLURL() string {
+ return conf.Server.ExternalURL + u.Name
+}
diff --git a/internal/db/users_test.go b/internal/db/users_test.go
index 68c1bfdc..67be21dd 100644
--- a/internal/db/users_test.go
+++ b/internal/db/users_test.go
@@ -198,7 +198,7 @@ func usersGetByEmail(t *testing.T, db *users) {
org, err := db.Create(ctx, "gogs", "gogs@exmaple.com", CreateUserOptions{})
require.NoError(t, err)
- err = db.Model(&User{}).Where("id", org.ID).UpdateColumn("type", UserOrganization).Error
+ err = db.Model(&User{}).Where("id", org.ID).UpdateColumn("type", UserTypeOrganization).Error
require.NoError(t, err)
_, err = db.GetByEmail(ctx, org.Email)