|
|
|
@ -5,17 +5,21 @@
|
|
|
|
|
package models |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"bytes" |
|
|
|
|
"container/list" |
|
|
|
|
"crypto/sha256" |
|
|
|
|
"encoding/hex" |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"image" |
|
|
|
|
"image/jpeg" |
|
|
|
|
"os" |
|
|
|
|
"path/filepath" |
|
|
|
|
"strings" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/Unknwon/com" |
|
|
|
|
"github.com/nfnt/resize" |
|
|
|
|
|
|
|
|
|
"github.com/gogits/gogs/modules/base" |
|
|
|
|
"github.com/gogits/gogs/modules/git" |
|
|
|
@ -57,22 +61,29 @@ type User struct {
|
|
|
|
|
Type UserType |
|
|
|
|
Orgs []*User `xorm:"-"` |
|
|
|
|
Repos []*Repository `xorm:"-"` |
|
|
|
|
NumFollowers int |
|
|
|
|
NumFollowings int |
|
|
|
|
NumStars int |
|
|
|
|
NumRepos int |
|
|
|
|
Avatar string `xorm:"VARCHAR(2048) NOT NULL"` |
|
|
|
|
AvatarEmail string `xorm:"NOT NULL"` |
|
|
|
|
Location string |
|
|
|
|
Website string |
|
|
|
|
IsActive bool |
|
|
|
|
IsAdmin bool |
|
|
|
|
AllowGitHook bool |
|
|
|
|
Rands string `xorm:"VARCHAR(10)"` |
|
|
|
|
Salt string `xorm:"VARCHAR(10)"` |
|
|
|
|
Created time.Time `xorm:"CREATED"` |
|
|
|
|
Updated time.Time `xorm:"UPDATED"` |
|
|
|
|
|
|
|
|
|
// Permissions.
|
|
|
|
|
IsActive bool |
|
|
|
|
IsAdmin bool |
|
|
|
|
AllowGitHook bool |
|
|
|
|
|
|
|
|
|
// Avatar.
|
|
|
|
|
Avatar string `xorm:"VARCHAR(2048) NOT NULL"` |
|
|
|
|
AvatarEmail string `xorm:"NOT NULL"` |
|
|
|
|
UseCustomAvatar bool |
|
|
|
|
|
|
|
|
|
// Counters.
|
|
|
|
|
NumFollowers int |
|
|
|
|
NumFollowings int |
|
|
|
|
NumStars int |
|
|
|
|
NumRepos int |
|
|
|
|
|
|
|
|
|
// For organization.
|
|
|
|
|
Description string |
|
|
|
|
NumTeams int |
|
|
|
@ -96,9 +107,12 @@ func (u *User) HomeLink() string {
|
|
|
|
|
|
|
|
|
|
// AvatarLink returns user gravatar link.
|
|
|
|
|
func (u *User) AvatarLink() string { |
|
|
|
|
if setting.DisableGravatar { |
|
|
|
|
switch { |
|
|
|
|
case u.UseCustomAvatar: |
|
|
|
|
return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id) |
|
|
|
|
case setting.DisableGravatar: |
|
|
|
|
return setting.AppSubUrl + "/img/avatar_default.jpg" |
|
|
|
|
} else if setting.Service.EnableCacheAvatar { |
|
|
|
|
case setting.Service.EnableCacheAvatar: |
|
|
|
|
return setting.AppSubUrl + "/avatar/" + u.Avatar |
|
|
|
|
} |
|
|
|
|
return setting.GravatarSource + u.Avatar |
|
|
|
@ -126,6 +140,43 @@ func (u *User) ValidtePassword(passwd string) bool {
|
|
|
|
|
return u.Passwd == newUser.Passwd |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// UploadAvatar saves custom avatar for user.
|
|
|
|
|
// FIXME: splite uploads to different subdirs in case we have massive users.
|
|
|
|
|
func (u *User) UploadAvatar(data []byte) error { |
|
|
|
|
savePath := filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id)) |
|
|
|
|
u.UseCustomAvatar = true |
|
|
|
|
|
|
|
|
|
img, _, err := image.Decode(bytes.NewReader(data)) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
m := resize.Resize(200, 200, img, resize.NearestNeighbor) |
|
|
|
|
|
|
|
|
|
sess := x.NewSession() |
|
|
|
|
defer sess.Close() |
|
|
|
|
if err = sess.Begin(); err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err = sess.Id(u.Id).AllCols().Update(u); err != nil { |
|
|
|
|
sess.Rollback() |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fw, err := os.Create(savePath) |
|
|
|
|
if err != nil { |
|
|
|
|
sess.Rollback() |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
defer fw.Close() |
|
|
|
|
if err = jpeg.Encode(fw, m, nil); err != nil { |
|
|
|
|
sess.Rollback() |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return sess.Commit() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsOrganization returns true if user is actually a organization.
|
|
|
|
|
func (u *User) IsOrganization() bool { |
|
|
|
|
return u.Type == ORGANIZATION |
|
|
|
@ -517,40 +568,37 @@ func GetUserIdsByNames(names []string) []int64 {
|
|
|
|
|
|
|
|
|
|
// UserCommit represtns a commit with validation of user.
|
|
|
|
|
type UserCommit struct { |
|
|
|
|
UserName string |
|
|
|
|
User *User |
|
|
|
|
*git.Commit |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ValidateCommitWithEmail chceck if author's e-mail of commit is corresponsind to a user.
|
|
|
|
|
func ValidateCommitWithEmail(c *git.Commit) (uname string) { |
|
|
|
|
func ValidateCommitWithEmail(c *git.Commit) *User { |
|
|
|
|
u, err := GetUserByEmail(c.Author.Email) |
|
|
|
|
if err == nil { |
|
|
|
|
uname = u.Name |
|
|
|
|
if err != nil { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
return uname |
|
|
|
|
return u |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
|
|
|
|
|
func ValidateCommitsWithEmails(oldCommits *list.List) *list.List { |
|
|
|
|
emails := map[string]string{} |
|
|
|
|
emails := map[string]*User{} |
|
|
|
|
newCommits := list.New() |
|
|
|
|
e := oldCommits.Front() |
|
|
|
|
for e != nil { |
|
|
|
|
c := e.Value.(*git.Commit) |
|
|
|
|
|
|
|
|
|
uname := "" |
|
|
|
|
var u *User |
|
|
|
|
if v, ok := emails[c.Author.Email]; !ok { |
|
|
|
|
u, err := GetUserByEmail(c.Author.Email) |
|
|
|
|
if err == nil { |
|
|
|
|
uname = u.Name |
|
|
|
|
} |
|
|
|
|
emails[c.Author.Email] = uname |
|
|
|
|
u, _ = GetUserByEmail(c.Author.Email) |
|
|
|
|
emails[c.Author.Email] = u |
|
|
|
|
} else { |
|
|
|
|
uname = v |
|
|
|
|
u = v |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
newCommits.PushBack(UserCommit{ |
|
|
|
|
UserName: uname, |
|
|
|
|
User: u, |
|
|
|
|
Commit: c, |
|
|
|
|
}) |
|
|
|
|
e = e.Next() |
|
|
|
|