summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorevolvedlight <steve@evolvedlight.co.uk>2014-10-13 20:30:31 +0100
committerevolvedlight <steve@evolvedlight.co.uk>2014-10-13 20:30:31 +0100
commit8d2a6fc484b540819e211d52b8d54e97269f0918 (patch)
treee5bfe7d3937bb2d18ba2fb50ea72514bd5bb4e13 /models
parent29ac3980ffdb5faa525d77fddc109c9023ebe257 (diff)
parent89bd994c836ecc9b6ceb80849f470521e1b15917 (diff)
downloadgitea-8d2a6fc484b540819e211d52b8d54e97269f0918.tar.gz
gitea-8d2a6fc484b540819e211d52b8d54e97269f0918.zip
Merge remote-tracking branch 'upstream/dev'
Conflicts: models/repo.go
Diffstat (limited to 'models')
-rw-r--r--models/action.go18
-rw-r--r--models/admin.go64
-rw-r--r--models/models.go10
-rw-r--r--models/org.go17
-rw-r--r--models/publickey.go20
-rw-r--r--models/repo.go28
-rw-r--r--models/update.go9
-rw-r--r--models/user.go2
-rw-r--r--models/webhook.go16
9 files changed, 133 insertions, 51 deletions
diff --git a/models/action.go b/models/action.go
index 4203ead38e..ef111e67a4 100644
--- a/models/action.go
+++ b/models/action.go
@@ -181,13 +181,19 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
commit = &base.PushCommits{}
}
- refName := git.RefEndName(refFullName)
+ repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
+ // if not the first commit, set the compareUrl
+ if !strings.HasPrefix(oldCommitId, "0000000") {
+ commit.CompareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId)
+ }
bs, err := json.Marshal(commit)
if err != nil {
return errors.New("action.CommitRepoAction(json): " + err.Error())
}
+ refName := git.RefEndName(refFullName)
+
// Change repository bare status and update last updated time.
repo, err := GetRepositoryByName(repoUserId, repoName)
if err != nil {
@@ -211,7 +217,6 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
return errors.New("action.CommitRepoAction(NotifyWatchers): " + err.Error())
}
- //qlog.Info("action.CommitRepoAction(end): %d/%s", repoUserId, repoName)
// New push event hook.
if err := repo.GetOwner(); err != nil {
@@ -237,13 +242,6 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
return nil
}
- repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
- compareUrl := ""
- // if not the first commit, set the compareUrl
- if !strings.HasPrefix(oldCommitId, "0000000") {
- compareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId)
- }
-
pusher_email, pusher_name := "", ""
pusher, err := GetUserByName(userName)
if err == nil {
@@ -293,7 +291,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
},
Before: oldCommitId,
After: newCommitId,
- CompareUrl: compareUrl,
+ CompareUrl: commit.CompareUrl,
}
for _, w := range ws {
diff --git a/models/admin.go b/models/admin.go
new file mode 100644
index 0000000000..493cc7afc8
--- /dev/null
+++ b/models/admin.go
@@ -0,0 +1,64 @@
+// 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 (
+ "time"
+
+ "github.com/Unknwon/com"
+)
+
+type NoticeType int
+
+const (
+ NOTICE_REPOSITORY NoticeType = iota + 1
+)
+
+// Notice represents a system notice for admin.
+type Notice struct {
+ Id int64
+ Type NoticeType
+ Description string `xorm:"TEXT"`
+ Created time.Time `xorm:"CREATED"`
+}
+
+// TrStr returns a translation format string.
+func (n *Notice) TrStr() string {
+ return "admin.notices.type_" + com.ToStr(n.Type)
+}
+
+// CreateNotice creates new system notice.
+func CreateNotice(tp NoticeType, desc string) error {
+ n := &Notice{
+ Type: tp,
+ Description: desc,
+ }
+ _, err := x.Insert(n)
+ return err
+}
+
+// CreateRepositoryNotice creates new system notice with type NOTICE_REPOSITORY.
+func CreateRepositoryNotice(desc string) error {
+ return CreateNotice(NOTICE_REPOSITORY, desc)
+}
+
+// CountNotices returns number of notices.
+func CountNotices() int64 {
+ count, _ := x.Count(new(Notice))
+ return count
+}
+
+// GetNotices returns given number of notices with offset.
+func GetNotices(num, offset int) ([]*Notice, error) {
+ notices := make([]*Notice, 0, num)
+ err := x.Limit(num, offset).Desc("id").Find(&notices)
+ return notices, err
+}
+
+// DeleteNotice deletes a system notice by given ID.
+func DeleteNotice(id int64) error {
+ _, err := x.Id(id).Delete(new(Notice))
+ return err
+}
diff --git a/models/models.go b/models/models.go
index 60959c60e9..4dcc447b34 100644
--- a/models/models.go
+++ b/models/models.go
@@ -31,12 +31,12 @@ var (
)
func init() {
- tables = append(tables, new(User), new(PublicKey),
+ tables = append(tables, new(User), new(PublicKey), new(Follow), new(Oauth2),
new(Repository), new(Watch), new(Star), new(Action), new(Access),
- new(Issue), new(Comment), new(Oauth2), new(Follow),
- new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
- new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
- new(UpdateTask), new(Attachment))
+ new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
+ new(Mirror), new(Release), new(LoginSource), new(Webhook),
+ new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
+ new(Notice))
}
func LoadModelsConfig() {
diff --git a/models/org.go b/models/org.go
index 31db8e3643..3232bf2ac1 100644
--- a/models/org.go
+++ b/models/org.go
@@ -845,20 +845,9 @@ func IsTeamMember(orgId, teamId, uid int64) bool {
// GetTeamMembers returns all members in given team of organization.
func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
- tus := make([]*TeamUser, 0, 10)
- err := x.Where("org_id=?", orgId).And("team_id=?", teamId).Find(&tus)
- if err != nil {
- return nil, err
- }
-
- us := make([]*User, len(tus))
- for i, tu := range tus {
- us[i], err = GetUserById(tu.Uid)
- if err != nil {
- return nil, err
- }
- }
- return us, nil
+ us := make([]*User, 0, 10)
+ err := x.Sql("SELECT * FROM `user` JOIN `team_user` ON `team_user`.`team_id` = ? AND `team_user`.`uid` = `user`.`id`", teamId).Find(&us)
+ return us, err
}
// GetUserTeams returns all teams that user belongs to in given origanization.
diff --git a/models/publickey.go b/models/publickey.go
index 8bb924e853..762d7333fa 100644
--- a/models/publickey.go
+++ b/models/publickey.go
@@ -33,6 +33,7 @@ const (
var (
ErrKeyAlreadyExist = errors.New("Public key already exist")
ErrKeyNotExist = errors.New("Public key does not exist")
+ ErrKeyUnableVerify = errors.New("Unable to verify public key")
)
var sshOpLocker = sync.Mutex{}
@@ -108,7 +109,7 @@ var (
// CheckPublicKeyString checks if the given public key string is recognized by SSH.
func CheckPublicKeyString(content string) (bool, error) {
if strings.ContainsAny(content, "\n\r") {
- return false, errors.New("Only a single line with a single key please")
+ return false, errors.New("only a single line with a single key please")
}
// write the key to a fileā€¦
@@ -126,7 +127,7 @@ func CheckPublicKeyString(content string) (bool, error) {
if err != nil {
return false, errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
- return false, errors.New("ssh-keygen returned not enough output to evaluate the key")
+ return false, errors.New("ssh-keygen returned not enough output to evaluate the key: " + stdout)
}
// The ssh-keygen in Windows does not print key type, so no need go further.
@@ -134,21 +135,22 @@ func CheckPublicKeyString(content string) (bool, error) {
return true, nil
}
+ fmt.Println(stdout)
sshKeygenOutput := strings.Split(stdout, " ")
if len(sshKeygenOutput) < 4 {
- return false, errors.New("Not enough fields returned by ssh-keygen -l -f")
+ return false, ErrKeyUnableVerify
}
// Check if key type and key size match.
- keySize, err := com.StrTo(sshKeygenOutput[0]).Int()
- if err != nil {
- return false, errors.New("Cannot get key size of the given key")
+ keySize := com.StrTo(sshKeygenOutput[0]).MustInt()
+ if keySize == 0 {
+ return false, errors.New("cannot get key size of the given key")
}
keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])
if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 {
- return false, errors.New("Sorry, unrecognized public key type")
+ return false, errors.New("sorry, unrecognized public key type")
} else if keySize < minimumKeySize {
- return false, fmt.Errorf("The minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
+ return false, fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
}
return true, nil
@@ -204,7 +206,7 @@ func AddPublicKey(key *PublicKey) (err error) {
if err != nil {
return errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
- return errors.New("Not enough output for calculating fingerprint")
+ return errors.New("not enough output for calculating fingerprint: " + stdout)
}
key.Fingerprint = strings.Split(stdout, " ")[1]
diff --git a/models/repo.go b/models/repo.go
index 0ca8b305ea..d156621c83 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -23,6 +23,7 @@ import (
"github.com/Unknwon/cae/zip"
"github.com/Unknwon/com"
+ "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
@@ -48,7 +49,7 @@ var (
)
var (
- DescriptionPattern = regexp.MustCompile(`https?://\S+`)
+ DescPattern = regexp.MustCompile(`https?://\S+`)
)
func LoadRepoConfig() {
@@ -165,7 +166,9 @@ type Repository struct {
}
func (repo *Repository) GetOwner() (err error) {
- repo.Owner, err = GetUserById(repo.OwnerId)
+ if repo.Owner == nil {
+ repo.Owner, err = GetUserById(repo.OwnerId)
+ }
return err
}
@@ -182,6 +185,14 @@ func (repo *Repository) IsOwnedBy(u *User) bool {
return repo.OwnerId == u.Id
}
+func (repo *Repository) HasAccess(uname string) bool {
+ if err := repo.GetOwner(); err != nil {
+ return false
+ }
+ has, _ := HasAccess(uname, path.Join(repo.Owner.Name, repo.Name), READABLE)
+ return has
+}
+
// DescriptionHtml does special handles to description and return HTML string.
func (repo *Repository) DescriptionHtml() template.HTML {
sanitize := func(s string) string {
@@ -189,7 +200,7 @@ func (repo *Repository) DescriptionHtml() template.HTML {
ss := html.EscapeString(s)
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss)
}
- return template.HTML(DescriptionPattern.ReplaceAllStringFunc(repo.Description, sanitize))
+ return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize))
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
@@ -660,7 +671,7 @@ func RepoPath(userName, repoName string) string {
func TransferOwnership(u *User, newOwner string, repo *Repository) error {
newUser, err := GetUserByName(newOwner)
if err != nil {
- return err
+ return fmt.Errorf("fail to get new owner(%s): %v", newOwner, err)
}
// Check if new owner has repository with same name.
@@ -948,9 +959,14 @@ func DeleteRepository(uid, repoId int64, userName string) error {
sess.Rollback()
return err
}
+
+ // Remove repository files.
if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil {
- sess.Rollback()
- return err
+ desc := fmt.Sprintf("Fail to delete repository files(%s/%s): %v", userName, repo.Name, err)
+ log.Warn(desc)
+ if err = CreateRepositoryNotice(desc); err != nil {
+ log.Error(4, "Fail to add notice: %v", err)
+ }
}
return sess.Commit()
}
diff --git a/models/update.go b/models/update.go
index d939a90874..33b7733e18 100644
--- a/models/update.go
+++ b/models/update.go
@@ -106,7 +106,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
repos.Id, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil {
- log.GitLogger.Fatal(4, "runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
+ log.GitLogger.Fatal(4, "CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
}
return err
}
@@ -116,8 +116,8 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err)
}
+ // Push new branch.
var l *list.List
- // if a new branch
if isNew {
l, err = newCommit.CommitsBefore()
if err != nil {
@@ -134,7 +134,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
return fmt.Errorf("runUpdate.Commit repoId: %v", err)
}
- // if commits push
+ // Push commits.
commits := make([]*base.PushCommit, 0)
var actEmail string
for e := l.Front(); e != nil; e = e.Next() {
@@ -153,9 +153,8 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
}
}
- //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()})
if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
- repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}, oldCommitId, newCommitId); err != nil {
+ repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitId, newCommitId); err != nil {
return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
}
return nil
diff --git a/models/user.go b/models/user.go
index ee8f8586d5..dc9b052ca8 100644
--- a/models/user.go
+++ b/models/user.go
@@ -488,7 +488,7 @@ func GetUserByName(name string) (*User, error) {
return user, nil
}
-// GetUserEmailsByNames returns a slice of e-mails corresponds to names.
+// GetUserEmailsByNames returns a list of e-mails corresponds to names.
func GetUserEmailsByNames(names []string) []string {
mails := make([]string, 0, len(names))
for _, name := range names {
diff --git a/models/webhook.go b/models/webhook.go
index 9508c98a5e..ac0c240977 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -235,8 +235,22 @@ func UpdateHookTask(t *HookTask) error {
return err
}
+var (
+ // Prevent duplicate deliveries.
+ // This happens with massive hook tasks cannot finish delivering
+ // before next shooting starts.
+ isShooting = false
+)
+
// DeliverHooks checks and delivers undelivered hooks.
+// FIXME: maybe can use goroutine to shoot a number of them at same time?
func DeliverHooks() {
+ if isShooting {
+ return
+ }
+ isShooting = true
+ defer func() { isShooting = false }()
+
tasks := make([]*HookTask, 0, 10)
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask),
@@ -255,7 +269,7 @@ func DeliverHooks() {
t.IsDelivered = true
- // TODO: record response.
+ // FIXME: record response.
switch t.Type {
case GOGS:
{