diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/access.go | 6 | ||||
-rw-r--r-- | models/action.go | 60 | ||||
-rw-r--r-- | models/fix.go | 6 | ||||
-rw-r--r-- | models/issue.go | 9 | ||||
-rw-r--r-- | models/models.go | 13 | ||||
-rw-r--r-- | models/publickey.go | 14 | ||||
-rw-r--r-- | models/repo.go | 65 | ||||
-rw-r--r-- | models/update.go | 29 | ||||
-rw-r--r-- | models/user.go | 49 |
9 files changed, 160 insertions, 91 deletions
diff --git a/models/access.go b/models/access.go index 970f4a941f..749a2604d5 100644 --- a/models/access.go +++ b/models/access.go @@ -42,6 +42,12 @@ func UpdateAccess(access *Access) error { return err } +// DeleteAccess deletes access record. +func DeleteAccess(access *Access) error { + _, err := orm.Delete(access) + 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 { diff --git a/models/action.go b/models/action.go index a9a41a9f4d..8d8713b8a6 100644 --- a/models/action.go +++ b/models/action.go @@ -10,6 +10,7 @@ import ( "time" "github.com/gogits/git" + qlog "github.com/qiniu/log" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" @@ -31,17 +32,19 @@ const ( // Action represents user operation type and other information to repository., // it implemented interface base.Actioner so that can be used in template render. type Action struct { - Id int64 - UserId int64 // Receiver user id. - OpType int // Operations: CREATE DELETE STAR ... - ActUserId int64 // Action user id. - ActUserName string // Action user name. - ActEmail string - RepoId int64 - RepoName string - RefName string - Content string `xorm:"TEXT"` - Created time.Time `xorm:"created"` + Id int64 + UserId int64 // Receiver user id. + OpType int // Operations: CREATE DELETE STAR ... + ActUserId int64 // Action user id. + ActUserName string // Action user name. + ActEmail string + RepoId int64 + RepoUserName string + RepoName string + RefName string + IsPrivate bool `xorm:"NOT NULL DEFAULT false"` + Content string `xorm:"TEXT"` + Created time.Time `xorm:"created"` } func (a Action) GetOpType() int { @@ -69,8 +72,8 @@ func (a Action) GetContent() string { } // CommitRepoAction adds new action for committing repository. -func CommitRepoAction(userId int64, userName, actEmail string, - repoId int64, repoName string, refName string, commit *base.PushCommits) error { +func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, + repoId int64, repoUserName, repoName string, refName string, commit *base.PushCommits) error { // log.Trace("action.CommitRepoAction(start): %d/%s", userId, repoName) opType := OP_COMMIT_REPO @@ -84,36 +87,38 @@ func CommitRepoAction(userId int64, userName, actEmail string, bs, err := json.Marshal(commit) if err != nil { - log.Error("action.CommitRepoAction(json): %d/%s", userId, repoName) - return err - } - - if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail, - OpType: opType, Content: string(bs), RepoId: repoId, RepoName: repoName, RefName: refName}); err != nil { - log.Error("action.CommitRepoAction(notify watchers): %d/%s", userId, repoName) + qlog.Error("action.CommitRepoAction(json): %d/%s", repoUserId, repoName) return err } // Change repository bare status and update last updated time. - repo, err := GetRepositoryByName(userId, repoName) + repo, err := GetRepositoryByName(repoUserId, repoName) if err != nil { - log.Error("action.CommitRepoAction(GetRepositoryByName): %d/%s", userId, repoName) + qlog.Error("action.CommitRepoAction(GetRepositoryByName): %d/%s", repoUserId, repoName) return err } repo.IsBare = false if err = UpdateRepository(repo); err != nil { - log.Error("action.CommitRepoAction(UpdateRepository): %d/%s", userId, repoName) + qlog.Error("action.CommitRepoAction(UpdateRepository): %d/%s", repoUserId, repoName) + return err + } + + if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail, + OpType: opType, Content: string(bs), RepoId: repoId, RepoUserName: repoUserName, + RepoName: repoName, RefName: refName, + IsPrivate: repo.IsPrivate}); err != nil { + qlog.Error("action.CommitRepoAction(notify watchers): %d/%s", userId, repoName) return err } - log.Trace("action.CommitRepoAction(end): %d/%s", userId, repoName) + qlog.Info("action.CommitRepoAction(end): %d/%s", repoUserId, repoName) return nil } // NewRepoAction adds new action for creating repository. func NewRepoAction(user *User, repo *Repository) (err error) { if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email, - OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name}); err != nil { + OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name, IsPrivate: repo.IsPrivate}); err != nil { log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name) return err } @@ -125,7 +130,8 @@ func NewRepoAction(user *User, repo *Repository) (err error) { // TransferRepoAction adds new action for transfering repository. func TransferRepoAction(user, newUser *User, repo *Repository) (err error) { if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email, - OpType: OP_TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name}); err != nil { + OpType: OP_TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name, + IsPrivate: repo.IsPrivate}); err != nil { log.Error("action.TransferRepoAction(notify watchers): %d/%s", user.Id, repo.Name) return err } @@ -139,7 +145,7 @@ func GetFeeds(userid, offset int64, isProfile bool) ([]Action, error) { actions := make([]Action, 0, 20) sess := orm.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid) if isProfile { - sess.And("act_user_id=?", userid) + sess.Where("is_private=?", false).And("act_user_id=?", userid) } else { sess.And("act_user_id!=?", userid) } diff --git a/models/fix.go b/models/fix.go new file mode 100644 index 0000000000..9fc141bd26 --- /dev/null +++ b/models/fix.go @@ -0,0 +1,6 @@ +package models + +func Fix() error { + _, err := orm.Exec("alter table repository drop column num_releases") + return err +} diff --git a/models/issue.go b/models/issue.go index f14030df5e..6a32312eed 100644 --- a/models/issue.go +++ b/models/issue.go @@ -70,12 +70,7 @@ func CreateIssue(userId, repoId, milestoneId, assigneeId int64, issueCount int, return nil, err } - if err = sess.Commit(); err != nil { - sess.Rollback() - return nil, err - } - - return issue, nil + return issue, sess.Commit() } // GetIssueById returns issue object by given id. @@ -196,7 +191,7 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, c defer sess.Close() sess.Begin() - if _, err := orm.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId, + if _, err := sess.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId, CommitId: commitId, Line: line, Content: content}); err != nil { sess.Rollback() return err diff --git a/models/models.go b/models/models.go index 3bce764963..b565f22ab1 100644 --- a/models/models.go +++ b/models/models.go @@ -58,10 +58,10 @@ func NewTestEngine(x *xorm.Engine) (err error) { case "postgres": var host, port = "127.0.0.1", "5432" fields := strings.Split(DbCfg.Host, ":") - if len(fields) > 0 { + if len(fields) > 0 && len(strings.TrimSpace(fields[0])) > 0 { host = fields[0] } - if len(fields) > 1 { + if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 { port = fields[1] } cnnstr := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s", @@ -91,10 +91,10 @@ func SetEngine() (err error) { case "postgres": var host, port = "127.0.0.1", "5432" fields := strings.Split(DbCfg.Host, ":") - if len(fields) > 0 { + if len(fields) > 0 && len(strings.TrimSpace(fields[0])) > 0 { host = fields[0] } - if len(fields) > 1 { + if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 { port = fields[1] } orm, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s", @@ -160,3 +160,8 @@ func GetStatistic() (stats Statistic) { stats.Counter.Release, _ = orm.Count(new(Release)) return } + +// DumpDatabase dumps all data from database to file system. +func DumpDatabase(filePath string) error { + return orm.DumpAllToFile(filePath) +} diff --git a/models/publickey.go b/models/publickey.go index ed47ff209d..b80412812b 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -77,12 +77,12 @@ func init() { // PublicKey represents a SSH key of user. type PublicKey struct { Id int64 - OwnerId int64 `xorm:"unique(s) index not null"` - Name string `xorm:"unique(s) not null"` + 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"` - Updated time.Time `xorm:"updated"` + Content string `xorm:"TEXT NOT NULL"` + Created time.Time `xorm:"CREATED"` + Updated time.Time `xorm:"UPDATED"` } // GenAuthorizedKey returns formatted public key string. @@ -107,9 +107,9 @@ func AddPublicKey(key *PublicKey) (err error) { if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil { return err } - stdout, _, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath) + stdout, stderr, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath) if err != nil { - return err + return errors.New("ssh-keygen -l -f: " + stderr) } else if len(stdout) < 2 { return errors.New("Not enough output for calculating fingerprint") } diff --git a/models/repo.go b/models/repo.go index 2011ed7de1..e8baadf6b0 100644 --- a/models/repo.go +++ b/models/repo.go @@ -159,9 +159,7 @@ func MirrorUpdate() { repoPath := filepath.Join(base.RepoRootPath, m.RepoName+".git") _, stderr, err := com.ExecCmdDir(repoPath, "git", "remote", "update") if err != nil { - return err - } else if strings.Contains(stderr, "fatal:") { - return errors.New(stderr) + return errors.New("git remote update: " + stderr) } else if err = git.UnpackRefs(repoPath); err != nil { return err } @@ -177,9 +175,7 @@ func MirrorUpdate() { func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) error { _, stderr, err := com.ExecCmd("git", "clone", "--mirror", url, repoPath) if err != nil { - return err - } else if strings.Contains(stderr, "fatal:") { - return errors.New(stderr) + return errors.New("git clone --mirror: " + stderr) } if _, err = orm.InsertOne(&Mirror{ @@ -219,23 +215,17 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url // Clone from local repository. _, stderr, err := com.ExecCmd("git", "clone", repoPath, tmpDir) if err != nil { - return repo, err - } else if strings.Contains(stderr, "fatal:") { return repo, errors.New("git clone: " + stderr) } // Pull data from source. _, stderr, err = com.ExecCmdDir(tmpDir, "git", "pull", url) if err != nil { - return repo, err - } else if strings.Contains(stderr, "fatal:") { return repo, errors.New("git pull: " + stderr) } // Push data to local repository. if _, stderr, err = com.ExecCmdDir(tmpDir, "git", "push", "origin", "master"); err != nil { - return repo, err - } else if strings.Contains(stderr, "fatal:") { return repo, errors.New("git push: " + stderr) } @@ -256,14 +246,17 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir } repo := &Repository{ - OwnerId: user.Id, - Name: name, - LowerName: strings.ToLower(name), - Description: desc, - IsPrivate: private, - IsBare: lang == "" && license == "" && !initReadme, - DefaultBranch: "master", + OwnerId: user.Id, + Name: name, + LowerName: strings.ToLower(name), + Description: desc, + IsPrivate: private, + IsBare: lang == "" && license == "" && !initReadme, + } + if !repo.IsBare { + repo.DefaultBranch = "master" } + repoPath := RepoPath(user.Name, repo.Name) sess := orm.NewSession() @@ -320,16 +313,14 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir return nil, err } - if !repo.IsPrivate { - if err = NewRepoAction(user, repo); err != nil { - log.Error("repo.CreateRepository(NewRepoAction): %v", err) - } - } - if err = WatchRepo(user.Id, repo.Id, true); err != nil { log.Error("repo.CreateRepository(WatchRepo): %v", err) } + if err = NewRepoAction(user, repo); err != nil { + log.Error("repo.CreateRepository(NewRepoAction): %v", err) + } + // No need for init for mirror. if mirror { return repo, nil @@ -388,10 +379,11 @@ func createHookUpdate(hookPath, content string) error { } // SetRepoEnvs sets environment variables for command update. -func SetRepoEnvs(userId int64, userName, repoName string) { +func SetRepoEnvs(userId int64, userName, repoName, repoUserName string) { os.Setenv("userId", base.ToStr(userId)) os.Setenv("userName", userName) os.Setenv("repoName", repoName) + os.Setenv("repoUserName", repoUserName) } // InitRepository initializes README and .gitignore if needed. @@ -403,10 +395,11 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep return err } + rp := strings.NewReplacer("\\", "/", " ", "\\ ") // hook/post-update if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"), fmt.Sprintf("#!/usr/bin/env %s\n%s update $1 $2 $3\n", base.ScriptType, - strings.Replace(appPath, "\\", "/", -1))); err != nil { + rp.Replace(appPath))); err != nil { return err } @@ -428,8 +421,6 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep _, stderr, err := com.ExecCmd("git", "clone", repoPath, tmpDir) if err != nil { - return err - } else if strings.Contains(stderr, "fatal:") { return errors.New("git clone: " + stderr) } @@ -469,7 +460,7 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep return nil } - SetRepoEnvs(user.Id, user.Name, repo.Name) + SetRepoEnvs(user.Id, user.Name, repo.Name, user.Name) // Apply changes and commit. return initRepoCommit(tmpDir, user.NewGitSig()) @@ -725,6 +716,20 @@ func GetRepositoryCount(user *User) (int64, error) { return orm.Count(&Repository{OwnerId: user.Id}) } +// GetCollaborators returns a list of user name of repository's collaborators. +func GetCollaborators(repoName string) ([]string, error) { + accesses := make([]*Access, 0, 10) + if err := orm.Find(&accesses, &Access{RepoName: strings.ToLower(repoName)}); err != nil { + return nil, err + } + + names := make([]string, len(accesses)) + for i := range accesses { + names[i] = accesses[i].UserName + } + return names, nil +} + // Watch is connection request for receiving repository notifycation. type Watch struct { Id int64 diff --git a/models/update.go b/models/update.go index 2f59547b72..3ae5510a84 100644 --- a/models/update.go +++ b/models/update.go @@ -1,3 +1,7 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + package models import ( @@ -5,24 +9,32 @@ import ( "os/exec" "strings" + qlog "github.com/qiniu/log" + "github.com/gogits/git" + "github.com/gogits/gogs/modules/base" - qlog "github.com/qiniu/log" ) -func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId int64) { +func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) { isNew := strings.HasPrefix(oldCommitId, "0000000") if isNew && strings.HasPrefix(newCommitId, "0000000") { qlog.Fatal("old rev and new rev both 000000") } - f := RepoPath(userName, repoName) + f := RepoPath(repoUserName, repoName) gitUpdate := exec.Command("git", "update-server-info") gitUpdate.Dir = f gitUpdate.Run() + isDel := strings.HasPrefix(newCommitId, "0000000") + if isDel { + qlog.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId) + return + } + repo, err := git.OpenRepository(f) if err != nil { qlog.Fatalf("runUpdate.Open repoId: %v", err) @@ -53,7 +65,12 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId qlog.Fatalf("runUpdate.Commit repoId: %v", err) } - repos, err := GetRepositoryByName(userId, repoName) + ru, err := GetUserByName(repoUserName) + if err != nil { + qlog.Fatalf("runUpdate.GetUserByName: %v", err) + } + + repos, err := GetRepositoryByName(ru.Id, repoName) if err != nil { qlog.Fatalf("runUpdate.GetRepositoryByName userId: %v", err) } @@ -77,8 +94,8 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId } //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) - if err = CommitRepoAction(userId, userName, actEmail, - repos.Id, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil { + if err = CommitRepoAction(userId, ru.Id, userName, actEmail, + repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil { qlog.Fatalf("runUpdate.models.CommitRepoAction: %v", err) } } diff --git a/models/user.go b/models/user.go index 3372d75497..a4b753f8e1 100644 --- a/models/user.go +++ b/models/user.go @@ -40,6 +40,7 @@ type User struct { Id int64 LowerName string `xorm:"unique not null"` Name string `xorm:"unique not null"` + FullName string Email string `xorm:"unique not null"` Passwd string `xorm:"not null"` LoginType int @@ -68,7 +69,9 @@ func (user *User) HomeLink() string { // AvatarLink returns the user gravatar link. func (user *User) AvatarLink() string { - if base.Service.EnableCacheAvatar { + if base.DisableGravatar { + return "/img/avatar_default.jpg" + } else if base.Service.EnableCacheAvatar { return "/avatar/" + user.Avatar } return "//1.gravatar.com/avatar/" + user.Avatar @@ -224,9 +227,9 @@ func ChangeUserName(user *User, newUserName string) (err error) { 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 = UpdateAccessWithSession(sess, &accesses[i]); err != nil { - return err - } + } + if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil { + return err } } @@ -242,6 +245,7 @@ func ChangeUserName(user *User, newUserName string) (err error) { } for j := range accesses { + accesses[j].UserName = newUserName accesses[j].RepoName = newUserName + "/" + repos[i].LowerName if err = UpdateAccessWithSession(sess, &accesses[j]); err != nil { return err @@ -404,22 +408,47 @@ func GetUserByEmail(email string) (*User, error) { return user, nil } +// SearchUserByName returns given number of users whose name contains keyword. +func SearchUserByName(key string, limit int) (us []*User, err error) { + // Prevent SQL inject. + key = strings.TrimSpace(key) + if len(key) == 0 { + return us, nil + } + + key = strings.Split(key, " ")[0] + if len(key) == 0 { + return us, nil + } + key = strings.ToLower(key) + + us = make([]*User, 0, limit) + err = orm.Limit(limit).Where("lower_name like '%" + key + "%'").Find(&us) + return us, err +} + // 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) +func LoginUserPlain(uname, passwd string) (*User, error) { + var u *User + if strings.Contains(uname, "@") { + u = &User{Email: uname} + } else { + u = &User{LowerName: strings.ToLower(uname)} + } + + has, err := orm.Get(u) if err != nil { return nil, err } else if !has { return nil, ErrUserNotExist } - newUser := &User{Passwd: passwd, Salt: user.Salt} + newUser := &User{Passwd: passwd, Salt: u.Salt} newUser.EncodePasswd() - if user.Passwd != newUser.Passwd { + if u.Passwd != newUser.Passwd { return nil, ErrUserNotExist } - return &user, nil + return u, nil } // Follow is connection request for receiving user notifycation. |