|
|
|
@ -52,7 +52,7 @@ var (
|
|
|
|
|
|
|
|
|
|
// User represents the object of individual and member of organization.
|
|
|
|
|
type User struct {
|
|
|
|
|
Id int64
|
|
|
|
|
ID int64 `xorm:"pk autoincr"`
|
|
|
|
|
LowerName string `xorm:"UNIQUE NOT NULL"`
|
|
|
|
|
Name string `xorm:"UNIQUE NOT NULL"`
|
|
|
|
|
FullName string
|
|
|
|
@ -137,7 +137,7 @@ func (u *User) IsLocal() bool {
|
|
|
|
|
|
|
|
|
|
// HasForkedRepo checks if user has already forked a repository with given ID.
|
|
|
|
|
func (u *User) HasForkedRepo(repoID int64) bool {
|
|
|
|
|
_, has := HasForkedRepo(u.Id, repoID)
|
|
|
|
|
_, has := HasForkedRepo(u.ID, repoID)
|
|
|
|
|
return has
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -184,7 +184,7 @@ func (u *User) HomeLink() string {
|
|
|
|
|
// GenerateEmailActivateCode generates an activate code based on user information and given e-mail.
|
|
|
|
|
func (u *User) GenerateEmailActivateCode(email string) string {
|
|
|
|
|
code := base.CreateTimeLimitCode(
|
|
|
|
|
com.ToStr(u.Id)+email+u.LowerName+u.Passwd+u.Rands,
|
|
|
|
|
com.ToStr(u.ID)+email+u.LowerName+u.Passwd+u.Rands,
|
|
|
|
|
setting.Service.ActiveCodeLives, nil)
|
|
|
|
|
|
|
|
|
|
// Add tail hex username
|
|
|
|
@ -199,7 +199,7 @@ func (u *User) GenerateActivateCode() string {
|
|
|
|
|
|
|
|
|
|
// CustomAvatarPath returns user custom avatar file path.
|
|
|
|
|
func (u *User) CustomAvatarPath() string {
|
|
|
|
|
return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
|
|
|
|
|
return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.ID))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GenerateRandomAvatar generates a random avatar for user.
|
|
|
|
@ -226,13 +226,13 @@ func (u *User) GenerateRandomAvatar() error {
|
|
|
|
|
return fmt.Errorf("Encode: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.Info("New random avatar created: %d", u.Id)
|
|
|
|
|
log.Info("New random avatar created: %d", u.ID)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (u *User) RelAvatarLink() string {
|
|
|
|
|
defaultImgUrl := "/img/avatar_default.png"
|
|
|
|
|
if u.Id == -1 {
|
|
|
|
|
if u.ID == -1 {
|
|
|
|
|
return defaultImgUrl
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -241,7 +241,7 @@ func (u *User) RelAvatarLink() string {
|
|
|
|
|
if !com.IsExist(u.CustomAvatarPath()) {
|
|
|
|
|
return defaultImgUrl
|
|
|
|
|
}
|
|
|
|
|
return "/avatars/" + com.ToStr(u.Id)
|
|
|
|
|
return "/avatars/" + com.ToStr(u.ID)
|
|
|
|
|
case setting.DisableGravatar, setting.OfflineMode:
|
|
|
|
|
if !com.IsExist(u.CustomAvatarPath()) {
|
|
|
|
|
if err := u.GenerateRandomAvatar(); err != nil {
|
|
|
|
@ -249,7 +249,7 @@ func (u *User) RelAvatarLink() string {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "/avatars/" + com.ToStr(u.Id)
|
|
|
|
|
return "/avatars/" + com.ToStr(u.ID)
|
|
|
|
|
}
|
|
|
|
|
return setting.GravatarSource + u.Avatar
|
|
|
|
|
}
|
|
|
|
@ -266,7 +266,7 @@ func (u *User) AvatarLink() string {
|
|
|
|
|
// User.GetFollwoers returns range of user's followers.
|
|
|
|
|
func (u *User) GetFollowers(page int) ([]*User, error) {
|
|
|
|
|
users := make([]*User, 0, ItemsPerPage)
|
|
|
|
|
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("follow.follow_id=?", u.Id)
|
|
|
|
|
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("follow.follow_id=?", u.ID)
|
|
|
|
|
if setting.UsePostgreSQL {
|
|
|
|
|
sess = sess.Join("LEFT", "follow", `"user".id=follow.user_id`)
|
|
|
|
|
} else {
|
|
|
|
@ -276,13 +276,13 @@ func (u *User) GetFollowers(page int) ([]*User, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (u *User) IsFollowing(followID int64) bool {
|
|
|
|
|
return IsFollowing(u.Id, followID)
|
|
|
|
|
return IsFollowing(u.ID, followID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetFollowing returns range of user's following.
|
|
|
|
|
func (u *User) GetFollowing(page int) ([]*User, error) {
|
|
|
|
|
users := make([]*User, 0, ItemsPerPage)
|
|
|
|
|
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("follow.user_id=?", u.Id)
|
|
|
|
|
sess := x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).Where("follow.user_id=?", u.ID)
|
|
|
|
|
if setting.UsePostgreSQL {
|
|
|
|
|
sess = sess.Join("LEFT", "follow", `"user".id=follow.follow_id`)
|
|
|
|
|
} else {
|
|
|
|
@ -350,7 +350,7 @@ func (u *User) UploadAvatar(data []byte) error {
|
|
|
|
|
|
|
|
|
|
// DeleteAvatar deletes the user's custom avatar.
|
|
|
|
|
func (u *User) DeleteAvatar() error {
|
|
|
|
|
log.Trace("DeleteAvatar[%d]: %s", u.Id, u.CustomAvatarPath())
|
|
|
|
|
log.Trace("DeleteAvatar[%d]: %s", u.ID, u.CustomAvatarPath())
|
|
|
|
|
os.Remove(u.CustomAvatarPath())
|
|
|
|
|
|
|
|
|
|
u.UseCustomAvatar = false
|
|
|
|
@ -385,16 +385,16 @@ func (u *User) IsOrganization() bool {
|
|
|
|
|
|
|
|
|
|
// IsUserOrgOwner returns true if user is in the owner team of given organization.
|
|
|
|
|
func (u *User) IsUserOrgOwner(orgId int64) bool {
|
|
|
|
|
return IsOrganizationOwner(orgId, u.Id)
|
|
|
|
|
return IsOrganizationOwner(orgId, u.ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsPublicMember returns true if user public his/her membership in give organization.
|
|
|
|
|
func (u *User) IsPublicMember(orgId int64) bool {
|
|
|
|
|
return IsPublicMembership(orgId, u.Id)
|
|
|
|
|
return IsPublicMembership(orgId, u.ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (u *User) getOrganizationCount(e Engine) (int64, error) {
|
|
|
|
|
return e.Where("uid=?", u.Id).Count(new(OrgUser))
|
|
|
|
|
return e.Where("uid=?", u.ID).Count(new(OrgUser))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOrganizationCount returns count of membership of organization of user.
|
|
|
|
@ -404,19 +404,19 @@ func (u *User) GetOrganizationCount() (int64, error) {
|
|
|
|
|
|
|
|
|
|
// GetRepositories returns all repositories that user owns, including private repositories.
|
|
|
|
|
func (u *User) GetRepositories() (err error) {
|
|
|
|
|
u.Repos, err = GetRepositories(u.Id, true)
|
|
|
|
|
u.Repos, err = GetRepositories(u.ID, true)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOwnedOrganizations returns all organizations that user owns.
|
|
|
|
|
func (u *User) GetOwnedOrganizations() (err error) {
|
|
|
|
|
u.OwnedOrgs, err = GetOwnedOrgsByUserID(u.Id)
|
|
|
|
|
u.OwnedOrgs, err = GetOwnedOrgsByUserID(u.ID)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOrganizations returns all organizations that user belongs to.
|
|
|
|
|
func (u *User) GetOrganizations(all bool) error {
|
|
|
|
|
ous, err := GetOrgUsersByUserID(u.Id, all)
|
|
|
|
|
ous, err := GetOrgUsersByUserID(u.ID, all)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@ -463,7 +463,7 @@ func GetUserSalt() string {
|
|
|
|
|
// NewFakeUser creates and returns a fake user for someone has deleted his/her account.
|
|
|
|
|
func NewFakeUser() *User {
|
|
|
|
|
return &User{
|
|
|
|
|
Id: -1,
|
|
|
|
|
ID: -1,
|
|
|
|
|
Name: "Someone",
|
|
|
|
|
LowerName: "someone",
|
|
|
|
|
}
|
|
|
|
@ -588,7 +588,7 @@ func VerifyUserActiveCode(code string) (user *User) {
|
|
|
|
|
if user = getVerifyUser(code); user != nil {
|
|
|
|
|
// time limit code
|
|
|
|
|
prefix := code[:base.TimeLimitCodeLength]
|
|
|
|
|
data := com.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
|
|
|
|
|
data := com.ToStr(user.ID) + user.Email + user.LowerName + user.Passwd + user.Rands
|
|
|
|
|
|
|
|
|
|
if base.VerifyTimeLimitCode(data, minutes, prefix) {
|
|
|
|
|
return user
|
|
|
|
@ -604,7 +604,7 @@ func VerifyActiveEmailCode(code, email string) *EmailAddress {
|
|
|
|
|
if user := getVerifyUser(code); user != nil {
|
|
|
|
|
// time limit code
|
|
|
|
|
prefix := code[:base.TimeLimitCodeLength]
|
|
|
|
|
data := com.ToStr(user.Id) + email + user.LowerName + user.Passwd + user.Rands
|
|
|
|
|
data := com.ToStr(user.ID) + email + user.LowerName + user.Passwd + user.Rands
|
|
|
|
|
|
|
|
|
|
if base.VerifyTimeLimitCode(data, minutes, prefix) {
|
|
|
|
|
emailAddress := &EmailAddress{Email: email}
|
|
|
|
@ -634,7 +634,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Delete all local copies of repository wiki that user owns.
|
|
|
|
|
if err = x.Where("owner_id=?", u.Id).Iterate(new(Repository), func(idx int, bean interface{}) error {
|
|
|
|
|
if err = x.Where("owner_id=?", u.ID).Iterate(new(Repository), func(idx int, bean interface{}) error {
|
|
|
|
|
repo := bean.(*Repository)
|
|
|
|
|
RemoveAllWithNotice("Delete repository wiki local copy", repo.LocalWikiPath())
|
|
|
|
|
return nil
|
|
|
|
@ -649,7 +649,7 @@ func updateUser(e Engine, u *User) error {
|
|
|
|
|
// Organization does not need email
|
|
|
|
|
if !u.IsOrganization() {
|
|
|
|
|
u.Email = strings.ToLower(u.Email)
|
|
|
|
|
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
|
|
|
|
|
has, err := e.Where("id!=?", u.ID).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if has {
|
|
|
|
@ -668,7 +668,7 @@ func updateUser(e Engine, u *User) error {
|
|
|
|
|
u.Description = base.TruncateString(u.Description, 255)
|
|
|
|
|
|
|
|
|
|
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
|
|
|
|
|
_, err := e.Id(u.Id).AllCols().Update(u)
|
|
|
|
|
_, err := e.Id(u.ID).AllCols().Update(u)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -697,7 +697,7 @@ func deleteUser(e *xorm.Session, u *User) error {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("GetRepositoryCount: %v", err)
|
|
|
|
|
} else if count > 0 {
|
|
|
|
|
return ErrUserOwnRepos{UID: u.Id}
|
|
|
|
|
return ErrUserOwnRepos{UID: u.ID}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check membership of organization.
|
|
|
|
@ -705,12 +705,12 @@ func deleteUser(e *xorm.Session, u *User) error {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("GetOrganizationCount: %v", err)
|
|
|
|
|
} else if count > 0 {
|
|
|
|
|
return ErrUserHasOrgs{UID: u.Id}
|
|
|
|
|
return ErrUserHasOrgs{UID: u.ID}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***** START: Watch *****
|
|
|
|
|
watches := make([]*Watch, 0, 10)
|
|
|
|
|
if err = e.Find(&watches, &Watch{UserID: u.Id}); err != nil {
|
|
|
|
|
if err = e.Find(&watches, &Watch{UserID: u.ID}); err != nil {
|
|
|
|
|
return fmt.Errorf("get all watches: %v", err)
|
|
|
|
|
}
|
|
|
|
|
for i := range watches {
|
|
|
|
@ -722,7 +722,7 @@ func deleteUser(e *xorm.Session, u *User) error {
|
|
|
|
|
|
|
|
|
|
// ***** START: Star *****
|
|
|
|
|
stars := make([]*Star, 0, 10)
|
|
|
|
|
if err = e.Find(&stars, &Star{UID: u.Id}); err != nil {
|
|
|
|
|
if err = e.Find(&stars, &Star{UID: u.ID}); err != nil {
|
|
|
|
|
return fmt.Errorf("get all stars: %v", err)
|
|
|
|
|
}
|
|
|
|
|
for i := range stars {
|
|
|
|
@ -734,7 +734,7 @@ func deleteUser(e *xorm.Session, u *User) error {
|
|
|
|
|
|
|
|
|
|
// ***** START: Follow *****
|
|
|
|
|
followers := make([]*Follow, 0, 10)
|
|
|
|
|
if err = e.Find(&followers, &Follow{UserID: u.Id}); err != nil {
|
|
|
|
|
if err = e.Find(&followers, &Follow{UserID: u.ID}); err != nil {
|
|
|
|
|
return fmt.Errorf("get all followers: %v", err)
|
|
|
|
|
}
|
|
|
|
|
for i := range followers {
|
|
|
|
@ -745,22 +745,22 @@ func deleteUser(e *xorm.Session, u *User) error {
|
|
|
|
|
// ***** END: Follow *****
|
|
|
|
|
|
|
|
|
|
if err = deleteBeans(e,
|
|
|
|
|
&AccessToken{UID: u.Id},
|
|
|
|
|
&Collaboration{UserID: u.Id},
|
|
|
|
|
&Access{UserID: u.Id},
|
|
|
|
|
&Watch{UserID: u.Id},
|
|
|
|
|
&Star{UID: u.Id},
|
|
|
|
|
&Follow{FollowID: u.Id},
|
|
|
|
|
&Action{UserID: u.Id},
|
|
|
|
|
&IssueUser{UID: u.Id},
|
|
|
|
|
&EmailAddress{UID: u.Id},
|
|
|
|
|
&AccessToken{UID: u.ID},
|
|
|
|
|
&Collaboration{UserID: u.ID},
|
|
|
|
|
&Access{UserID: u.ID},
|
|
|
|
|
&Watch{UserID: u.ID},
|
|
|
|
|
&Star{UID: u.ID},
|
|
|
|
|
&Follow{FollowID: u.ID},
|
|
|
|
|
&Action{UserID: u.ID},
|
|
|
|
|
&IssueUser{UID: u.ID},
|
|
|
|
|
&EmailAddress{UID: u.ID},
|
|
|
|
|
); err != nil {
|
|
|
|
|
return fmt.Errorf("deleteBeans: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***** START: PublicKey *****
|
|
|
|
|
keys := make([]*PublicKey, 0, 10)
|
|
|
|
|
if err = e.Find(&keys, &PublicKey{OwnerID: u.Id}); err != nil {
|
|
|
|
|
if err = e.Find(&keys, &PublicKey{OwnerID: u.ID}); err != nil {
|
|
|
|
|
return fmt.Errorf("get all public keys: %v", err)
|
|
|
|
|
}
|
|
|
|
|
for _, key := range keys {
|
|
|
|
@ -771,11 +771,11 @@ func deleteUser(e *xorm.Session, u *User) error {
|
|
|
|
|
// ***** END: PublicKey *****
|
|
|
|
|
|
|
|
|
|
// Clear assignee.
|
|
|
|
|
if _, err = e.Exec("UPDATE `issue` SET assignee_id=0 WHERE assignee_id=?", u.Id); err != nil {
|
|
|
|
|
if _, err = e.Exec("UPDATE `issue` SET assignee_id=0 WHERE assignee_id=?", u.ID); err != nil {
|
|
|
|
|
return fmt.Errorf("clear assignee: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err = e.Id(u.Id).Delete(new(User)); err != nil {
|
|
|
|
|
if _, err = e.Id(u.ID).Delete(new(User)); err != nil {
|
|
|
|
|
return fmt.Errorf("Delete: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -861,7 +861,7 @@ func GetUserByID(id int64) (*User, error) {
|
|
|
|
|
|
|
|
|
|
// GetAssigneeByID returns the user with write access of repository by given ID.
|
|
|
|
|
func GetAssigneeByID(repo *Repository, userID int64) (*User, error) {
|
|
|
|
|
has, err := HasAccess(&User{Id: userID}, repo, ACCESS_MODE_WRITE)
|
|
|
|
|
has, err := HasAccess(&User{ID: userID}, repo, ACCESS_MODE_WRITE)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
} else if !has {
|
|
|
|
@ -906,7 +906,7 @@ func GetUserIDsByNames(names []string) []int64 {
|
|
|
|
|
if err != nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
ids = append(ids, u.Id)
|
|
|
|
|
ids = append(ids, u.ID)
|
|
|
|
|
}
|
|
|
|
|
return ids
|
|
|
|
|
}
|
|
|
|
|