diff options
author | 无闻 <joe2010xtmf@163.com> | 2014-04-07 15:47:26 -0400 |
---|---|---|
committer | 无闻 <joe2010xtmf@163.com> | 2014-04-07 15:47:26 -0400 |
commit | 2577940c30f6a6d15390974ab36f8c3d1e00f9f4 (patch) | |
tree | c5f8fac19903327e78d5ac4f0fa2f8004a10974d /models | |
parent | ef6b9784962d3152d3ec46833303bad72915af57 (diff) | |
parent | 22feddf804c7fbf3418cbbc8e7302da271da4e5a (diff) |
Merge pull request #68 from gogits/dev
Dev
Diffstat (limited to 'models')
-rw-r--r-- | models/access.go | 11 | ||||
-rw-r--r-- | models/models.go | 19 | ||||
-rw-r--r-- | models/oauth2.go | 33 | ||||
-rw-r--r-- | models/publickey.go | 4 | ||||
-rw-r--r-- | models/repo.go | 57 | ||||
-rw-r--r-- | models/user.go | 75 |
6 files changed, 156 insertions, 43 deletions
diff --git a/models/access.go b/models/access.go index 83261575..2c090015 100644 --- a/models/access.go +++ b/models/access.go @@ -7,6 +7,8 @@ package models import ( "strings" "time" + + "github.com/lunny/xorm" ) // Access types. @@ -40,6 +42,15 @@ func UpdateAccess(access *Access) error { return err } +// UpdateAccess updates access information with session for rolling back. +func UpdateAccessWithSession(sess *xorm.Session, access *Access) error { + if _, err := sess.Id(access.Id).Update(access); err != nil { + sess.Rollback() + return err + } + return nil +} + // HasAccess returns true if someone can read or write to given repository. func HasAccess(userName, repoName string, mode int) (bool, error) { return orm.Get(&Access{ diff --git a/models/models.go b/models/models.go index 0ad86337..ee96207d 100644 --- a/models/models.go +++ b/models/models.go @@ -18,7 +18,9 @@ import ( ) var ( - orm *xorm.Engine + orm *xorm.Engine + tables []interface{} + HasEngine bool DbCfg struct { @@ -28,6 +30,11 @@ var ( UseSQLite3 bool ) +func init() { + tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), + new(Action), new(Access), new(Issue), new(Comment), new(Oauth2)) +} + func LoadModelsConfig() { DbCfg.Type = base.Cfg.MustValue("database", "DB_TYPE") if DbCfg.Type == "sqlite3" { @@ -58,9 +65,7 @@ func NewTestEngine(x *xorm.Engine) (err error) { if err != nil { return fmt.Errorf("models.init(fail to conntect database): %v", err) } - - return x.Sync(new(User), new(PublicKey), new(Repository), new(Watch), - new(Action), new(Access), new(Issue), new(Comment)) + return x.Sync(tables...) } func SetEngine() (err error) { @@ -102,9 +107,9 @@ func SetEngine() (err error) { func NewEngine() (err error) { if err = SetEngine(); err != nil { return err - } else if err = orm.Sync(new(User), new(PublicKey), new(Repository), new(Watch), - new(Action), new(Access), new(Issue), new(Comment)); err != nil { - return fmt.Errorf("sync database struct error: %v", err) + } + if err = orm.Sync(tables...); err != nil { + return fmt.Errorf("sync database struct error: %v\n", err) } return nil } diff --git a/models/oauth2.go b/models/oauth2.go index 70dcd510..a17d4e30 100644 --- a/models/oauth2.go +++ b/models/oauth2.go @@ -1,6 +1,6 @@ package models -import "time" +import "fmt" // OT: Oauth2 Type const ( @@ -10,9 +10,30 @@ const ( ) type Oauth2 struct { - Uid int64 `xorm:"pk"` // userId - Type int `xorm:"pk unique(oauth)"` // twitter,github,google... - Identity string `xorm:"pk unique(oauth)"` // id.. - Token string `xorm:"VARCHAR(200) not null"` - RefreshTime time.Time `xorm:"created"` + Uid int64 `xorm:"pk"` // userId + Type int `xorm:"pk unique(oauth)"` // twitter,github,google... + Identity string `xorm:"pk unique(oauth)"` // id.. + Token string `xorm:"VARCHAR(200) not null"` + //RefreshTime time.Time `xorm:"created"` +} + +func AddOauth2(oa *Oauth2) (err error) { + if _, err = orm.Insert(oa); err != nil { + return err + } + return nil +} + +func GetOauth2User(identity string) (u *User, err error) { + oa := &Oauth2{} + oa.Identity = identity + exists, err := orm.Get(oa) + if err != nil { + return + } + if !exists { + err = fmt.Errorf("not exists oauth2: %s", identity) + return + } + return GetUserById(oa.Uid) } diff --git a/models/publickey.go b/models/publickey.go index 42d2523b..ed47ff20 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -77,8 +77,8 @@ func init() { // PublicKey represents a SSH key of user. type PublicKey struct { Id int64 - OwnerId int64 `xorm:" index not null"` - Name string `xorm:" not null"` //UNIQUE(s) + OwnerId int64 `xorm:"unique(s) index not null"` + Name string `xorm:"unique(s) not null"` Fingerprint string Content string `xorm:"TEXT not null"` Created time.Time `xorm:"created"` diff --git a/models/repo.go b/models/repo.go index e8ebce92..bb5c3637 100644 --- a/models/repo.go +++ b/models/repo.go @@ -138,11 +138,8 @@ func CreateRepository(user *User, repoName, desc, repoLang, license string, priv IsPrivate: private, IsBare: repoLang == "" && license == "" && !initReadme, } - repoPath := RepoPath(user.Name, repoName) - if err = initRepository(repoPath, user, repo, initReadme, repoLang, license); err != nil { - return nil, err - } + sess := orm.NewSession() defer sess.Close() sess.Begin() @@ -207,6 +204,10 @@ func CreateRepository(user *User, repoName, desc, repoLang, license string, priv log.Error("repo.CreateRepository(WatchRepo): %v", err) } + if err = initRepository(repoPath, user, repo, initReadme, repoLang, license); err != nil { + return nil, err + } + return repo, nil } @@ -332,6 +333,11 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep return nil } + // for update use + os.Setenv("userName", user.Name) + os.Setenv("userId", base.ToStr(user.Id)) + os.Setenv("repoName", repo.Name) + // Apply changes and commit. return initRepoCommit(tmpDir, user.NewGitSig()) } @@ -381,45 +387,62 @@ func TransferOwnership(user *User, newOwner string, repo *Repository) (err error if err = orm.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repo.LowerName}); err != nil { return err } + + sess := orm.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return err + } + for i := range accesses { accesses[i].RepoName = newUser.LowerName + "/" + repo.LowerName if accesses[i].UserName == user.LowerName { accesses[i].UserName = newUser.LowerName } - if err = UpdateAccess(&accesses[i]); err != nil { + if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil { return err } } // Update repository. repo.OwnerId = newUser.Id - if _, err := orm.Id(repo.Id).Update(repo); err != nil { + if _, err := sess.Id(repo.Id).Update(repo); err != nil { + sess.Rollback() return err } // Update user repository number. rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?" - if _, err = orm.Exec(rawSql, newUser.Id); err != nil { + if _, err = sess.Exec(rawSql, newUser.Id); err != nil { + sess.Rollback() return err } rawSql = "UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?" - if _, err = orm.Exec(rawSql, user.Id); err != nil { + if _, err = sess.Exec(rawSql, user.Id); err != nil { + sess.Rollback() return err } // Add watch of new owner to repository. if !IsWatching(newUser.Id, repo.Id) { if err = WatchRepo(newUser.Id, repo.Id, true); err != nil { + sess.Rollback() return err } } if err = TransferRepoAction(user, newUser, repo); err != nil { + sess.Rollback() return err } // Change repository directory name. - return os.Rename(RepoPath(user.Name, repo.Name), RepoPath(newUser.Name, repo.Name)) + if err = os.Rename(RepoPath(user.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil { + sess.Rollback() + return err + } + + return sess.Commit() } // ChangeRepositoryName changes all corresponding setting from old repository name to new one. @@ -429,15 +452,27 @@ func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) if err = orm.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil { return err } + + sess := orm.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return err + } + for i := range accesses { accesses[i].RepoName = userName + "/" + newRepoName - if err = UpdateAccess(&accesses[i]); err != nil { + if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil { return err } } // Change repository directory name. - return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName)) + if err = os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName)); err != nil { + sess.Rollback() + return err + } + + return sess.Commit() } func UpdateRepository(repo *Repository) error { diff --git a/models/user.go b/models/user.go index 2641a15f..0fcf7243 100644 --- a/models/user.go +++ b/models/user.go @@ -5,6 +5,7 @@ package models import ( + "crypto/sha256" "encoding/hex" "errors" "fmt" @@ -13,8 +14,6 @@ import ( "strings" "time" - "github.com/dchest/scrypt" - "github.com/gogits/git" "github.com/gogits/gogs/modules/base" @@ -62,6 +61,7 @@ type User struct { IsActive bool IsAdmin bool Rands string `xorm:"VARCHAR(10)"` + Salt string `xorm:"VARCHAR(10)"` Created time.Time `xorm:"created"` Updated time.Time `xorm:"updated"` } @@ -89,10 +89,9 @@ func (user *User) NewGitSig() *git.Signature { } // EncodePasswd encodes password to safe format. -func (user *User) EncodePasswd() error { - newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(base.SecretKey), 16384, 8, 1, 64) +func (user *User) EncodePasswd() { + newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New) user.Passwd = fmt.Sprintf("%x", newPasswd) - return err } // Member represents user is member of organization. @@ -148,9 +147,9 @@ func RegisterUser(user *User) (*User, error) { user.Avatar = base.EncodeMd5(user.Email) user.AvatarEmail = user.Email user.Rands = GetUserSalt() - if err = user.EncodePasswd(); err != nil { - return nil, err - } else if _, err = orm.Insert(user); err != nil { + user.Salt = GetUserSalt() + user.EncodePasswd() + if _, err = orm.Insert(user); err != nil { return nil, err } else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil { if _, err := orm.Id(user.Id).Delete(&User{}); err != nil { @@ -218,11 +217,18 @@ func ChangeUserName(user *User, newUserName string) (err error) { if err = orm.Find(&accesses, &Access{UserName: user.LowerName}); err != nil { return err } + + sess := orm.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return err + } + for i := range accesses { accesses[i].UserName = newUserName if strings.HasPrefix(accesses[i].RepoName, user.LowerName+"/") { accesses[i].RepoName = strings.Replace(accesses[i].RepoName, user.LowerName, newUserName, 1) - if err = UpdateAccess(&accesses[i]); err != nil { + if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil { return err } } @@ -241,14 +247,19 @@ func ChangeUserName(user *User, newUserName string) (err error) { for j := range accesses { accesses[j].RepoName = newUserName + "/" + repos[i].LowerName - if err = UpdateAccess(&accesses[j]); err != nil { + if err = UpdateAccessWithSession(sess, &accesses[j]); err != nil { return err } } } // Change user directory name. - return os.Rename(UserPath(user.LowerName), UserPath(newUserName)) + if err = os.Rename(UserPath(user.LowerName), UserPath(newUserName)); err != nil { + sess.Rollback() + return err + } + + return sess.Commit() } // UpdateUser updates user's information. @@ -355,20 +366,50 @@ func GetUserByName(name string) (*User, error) { return user, nil } -// LoginUserPlain validates user by raw user name and password. -func LoginUserPlain(name, passwd string) (*User, error) { - user := User{LowerName: strings.ToLower(name), Passwd: passwd} - if err := user.EncodePasswd(); err != nil { +// GetUserEmailsByNames returns a slice of e-mails corresponds to names. +func GetUserEmailsByNames(names []string) []string { + mails := make([]string, 0, len(names)) + for _, name := range names { + u, err := GetUserByName(name) + if err != nil { + continue + } + mails = append(mails, u.Email) + } + return mails +} + +// GetUserByEmail returns the user object by given e-mail if exists. +func GetUserByEmail(email string) (*User, error) { + if len(email) == 0 { + return nil, ErrUserNotExist + } + user := &User{Email: strings.ToLower(email)} + has, err := orm.Get(user) + if err != nil { return nil, err + } else if !has { + return nil, ErrUserNotExist } + return user, nil +} +// LoginUserPlain validates user by raw user name and password. +func LoginUserPlain(name, passwd string) (*User, error) { + user := User{LowerName: strings.ToLower(name)} has, err := orm.Get(&user) if err != nil { return nil, err } else if !has { - err = ErrUserNotExist + return nil, ErrUserNotExist + } + + newUser := &User{Passwd: passwd, Salt: user.Salt} + newUser.EncodePasswd() + if user.Passwd != newUser.Passwd { + return nil, ErrUserNotExist } - return &user, err + return &user, nil } // Follow is connection request for receiving user notifycation. |