summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/access.go9
-rw-r--r--models/action.go95
-rw-r--r--models/git_diff.go8
-rw-r--r--models/issue.go47
-rw-r--r--models/migrations/migrations.go152
-rw-r--r--models/models.go22
-rw-r--r--models/org.go55
-rw-r--r--models/publickey.go4
-rw-r--r--models/repo.go176
-rw-r--r--models/user.go3
-rw-r--r--models/webhook.go14
11 files changed, 355 insertions, 230 deletions
diff --git a/models/access.go b/models/access.go
index 916711f786..174aca987f 100644
--- a/models/access.go
+++ b/models/access.go
@@ -4,10 +4,6 @@
package models
-//import (
-// "github.com/go-xorm/xorm"
-//)
-
type AccessMode int
const (
@@ -81,9 +77,10 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
if err != nil {
return nil, err
}
- err = repo.GetOwner()
- if err != nil {
+ if err = repo.GetOwner(); err != nil {
return nil, err
+ } else if repo.OwnerId == u.Id {
+ continue
}
repos[repo] = access.Mode
}
diff --git a/models/action.go b/models/action.go
index 318a5f6ad4..5cba2f515a 100644
--- a/models/action.go
+++ b/models/action.go
@@ -41,14 +41,21 @@ var (
var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
- IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
- IssueCloseKeywordsPat *regexp.Regexp
- IssueReferenceKeywordsPat *regexp.Regexp
+ IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
+ IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
+
+ IssueCloseKeywordsPat, IssueReopenKeywordsPat *regexp.Regexp
+ IssueReferenceKeywordsPat *regexp.Regexp
)
+func assembleKeywordsPattern(words []string) string {
+ return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|"))
+}
+
func init() {
- IssueCloseKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueCloseKeywords, "|")))
- IssueReferenceKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:) \S+`))
+ IssueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueCloseKeywords))
+ IssueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueReopenKeywords))
+ IssueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
}
// Action represents user operation type and other information to repository.,
@@ -91,7 +98,7 @@ func (a Action) GetRepoName() string {
}
func (a Action) GetRepoLink() string {
- return path.Join(a.RepoUserName, a.RepoName)
+ return path.Join(setting.AppSubUrl, a.RepoUserName, a.RepoName)
}
func (a Action) GetBranch() string {
@@ -112,13 +119,11 @@ func (a Action) GetIssueInfos() []string {
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits {
- references := IssueReferenceKeywordsPat.FindAllString(c.Message, -1)
-
- for _, ref := range references {
+ for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
- return !unicode.IsDigit(c)
- })
+ return !unicode.IsDigit(c)
+ })
if len(ref) == 0 {
continue
@@ -128,33 +133,29 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false {
- // We don't support User#ID syntax yet
+ // FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
-
if err != nil {
return err
}
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
-
- if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
+ if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
return err
}
}
- closes := IssueCloseKeywordsPat.FindAllString(c.Message, -1)
-
- for _, ref := range closes {
+ for _, ref := range IssueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
- return !unicode.IsDigit(c)
- })
+ return !unicode.IsDigit(c)
+ })
if len(ref) == 0 {
continue
@@ -171,7 +172,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
issue, err := GetIssueByRef(ref)
-
if err != nil {
return err
}
@@ -180,7 +180,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if issue.IsClosed {
continue
}
-
issue.IsClosed = true
if err = UpdateIssue(issue); err != nil {
@@ -194,14 +193,60 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// If commit happened in the referenced repository, it means the issue can be closed.
- if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, CLOSE, "", nil); err != nil {
+ if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil {
return err
}
}
}
-
- }
+ for _, ref := range IssueReopenKeywordsPat.FindAllString(c.Message, -1) {
+ ref := ref[strings.IndexByte(ref, byte(' '))+1:]
+ ref = strings.TrimRightFunc(ref, func(c rune) bool {
+ return !unicode.IsDigit(c)
+ })
+
+ if len(ref) == 0 {
+ continue
+ }
+
+ // Add repo name if missing
+ if ref[0] == '#' {
+ ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
+ } else if strings.Contains(ref, "/") == false {
+ // We don't support User#ID syntax yet
+ // return ErrNotImplemented
+
+ continue
+ }
+
+ issue, err := GetIssueByRef(ref)
+ if err != nil {
+ return err
+ }
+
+ if issue.RepoId == repoId {
+ if !issue.IsClosed {
+ continue
+ }
+ issue.IsClosed = false
+
+ if err = UpdateIssue(issue); err != nil {
+ return err
+ } else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
+ return err
+ }
+
+ if err = ChangeMilestoneIssueStats(issue); err != nil {
+ return err
+ }
+
+ // If commit happened in the referenced repository, it means the issue can be closed.
+ if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil {
+ return err
+ }
+ }
+ }
+ }
return nil
}
diff --git a/models/git_diff.go b/models/git_diff.go
index 7e91626f1d..9d34ed6271 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -60,6 +60,8 @@ type DiffFile struct {
Index int
Addition, Deletion int
Type int
+ IsCreated bool
+ IsDeleted bool
IsBin bool
Sections []*DiffSection
}
@@ -181,10 +183,16 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
switch {
case strings.HasPrefix(scanner.Text(), "new file"):
curFile.Type = DIFF_FILE_ADD
+ curFile.IsDeleted = false
+ curFile.IsCreated = true
case strings.HasPrefix(scanner.Text(), "deleted"):
curFile.Type = DIFF_FILE_DEL
+ curFile.IsCreated = false
+ curFile.IsDeleted = true
case strings.HasPrefix(scanner.Text(), "index"):
curFile.Type = DIFF_FILE_CHANGE
+ curFile.IsCreated = false
+ curFile.IsDeleted = false
}
if curFile.Type > 0 {
break
diff --git a/models/issue.go b/models/issue.go
index 8d0525d7c5..3cd71d8aa4 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -282,30 +282,33 @@ type IssueUser struct {
}
// NewIssueUserPairs adds new issue-user pairs for new issue of repository.
-func NewIssueUserPairs(repo *Repository, iid, oid, pid, aid int64) (err error) {
- iu := &IssueUser{IssueId: iid, RepoId: repo.Id}
-
- us, err := repo.GetCollaborators()
+func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID int64) (err error) {
+ users, err := repo.GetCollaborators()
if err != nil {
return err
}
+ iu := &IssueUser{
+ IssueId: issueID,
+ RepoId: repo.Id,
+ }
+
isNeedAddPoster := true
- for _, u := range us {
+ for _, u := range users {
iu.Uid = u.Id
- iu.IsPoster = iu.Uid == pid
+ iu.IsPoster = iu.Uid == posterID
if isNeedAddPoster && iu.IsPoster {
isNeedAddPoster = false
}
- iu.IsAssigned = iu.Uid == aid
+ iu.IsAssigned = iu.Uid == assigneeID
if _, err = x.Insert(iu); err != nil {
return err
}
}
if isNeedAddPoster {
- iu.Uid = pid
+ iu.Uid = posterID
iu.IsPoster = true
- iu.IsAssigned = iu.Uid == aid
+ iu.IsAssigned = iu.Uid == assigneeID
if _, err = x.Insert(iu); err != nil {
return err
}
@@ -859,22 +862,16 @@ type CommentType int
const (
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
- COMMENT CommentType = iota
-
- // Reopen action
- REOPEN
-
- // Close action
- CLOSE
-
- // Reference from another issue
- ISSUE
+ COMMENT_TYPE_COMMENT CommentType = iota
+ COMMENT_TYPE_REOPEN
+ COMMENT_TYPE_CLOSE
+ // References.
+ COMMENT_TYPE_ISSUE
// Reference from some commit (not part of a pull request)
- COMMIT
-
+ COMMENT_TYPE_COMMIT
// Reference from some pull request
- PULL
+ COMMENT_TYPE_PULL
)
// Comment represents a comment in commit and issue page.
@@ -908,7 +905,7 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
// Check comment type.
switch cmtType {
- case COMMENT:
+ case COMMENT_TYPE_COMMENT:
rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, issueId); err != nil {
sess.Rollback()
@@ -929,13 +926,13 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
return nil, err
}
}
- case REOPEN:
+ case COMMENT_TYPE_REOPEN:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
return nil, err
}
- case CLOSE:
+ case COMMENT_TYPE_CLOSE:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 37986b68bd..1510bafdb6 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -1,15 +1,44 @@
+// Copyright 2015 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 migrations
import (
- "errors"
- "strconv"
+ "fmt"
"strings"
"time"
+ "github.com/Unknwon/com"
"github.com/go-xorm/xorm"
+
+ "github.com/gogits/gogs/modules/log"
+ "github.com/gogits/gogs/modules/setting"
)
-type migration func(*xorm.Engine) error
+const _MIN_DB_VER = 0
+
+type Migration interface {
+ Description() string
+ Migrate(*xorm.Engine) error
+}
+
+type migration struct {
+ description string
+ migrate func(*xorm.Engine) error
+}
+
+func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
+ return &migration{desc, fn}
+}
+
+func (m *migration) Description() string {
+ return m.description
+}
+
+func (m *migration) Migrate(x *xorm.Engine) error {
+ return m.migrate(x)
+}
// The version table. Should have only one row with id==1
type Version struct {
@@ -18,23 +47,26 @@ type Version struct {
}
// This is a sequence of migrations. Add new migrations to the bottom of the list.
-// If you want to "retire" a migration, replace it with "expiredMigration"
-var migrations = []migration{
- accessToCollaboration,
- accessRefactor,
+// If you want to "retire" a migration, remove it from the top of the list and
+// update _MIN_VER_DB accordingly
+var migrations = []Migration{
+ NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1
+ NewMigration("refactor access table to use id's", accessRefactor), // V1 -> V2
}
// Migrate database to current version
func Migrate(x *xorm.Engine) error {
if err := x.Sync(new(Version)); err != nil {
- return err
+ return fmt.Errorf("sync: %v", err)
}
currentVersion := &Version{Id: 1}
has, err := x.Get(currentVersion)
if err != nil {
- return err
+ return fmt.Errorf("get: %v", err)
} else if !has {
+ // If the user table does not exist it is a fresh installation and we
+ // can skip all migrations
needsMigration, err := x.IsTableExist("user")
if err != nil {
return err
@@ -44,22 +76,24 @@ func Migrate(x *xorm.Engine) error {
if err != nil {
return err
}
+ // If the user table is empty it is a fresh installation and we can
+ // skip all migrations
needsMigration = !isEmpty
}
if !needsMigration {
- currentVersion.Version = int64(len(migrations))
+ currentVersion.Version = int64(_MIN_DB_VER + len(migrations))
}
if _, err = x.InsertOne(currentVersion); err != nil {
- return err
+ return fmt.Errorf("insert: %v", err)
}
}
v := currentVersion.Version
-
- for i, migration := range migrations[v:] {
- if err = migration(x); err != nil {
- return err
+ for i, m := range migrations[v-_MIN_DB_VER:] {
+ log.Info("Migration: %s", m.Description())
+ if err = m.Migrate(x); err != nil {
+ return fmt.Errorf("do migrate: %v", err)
}
currentVersion.Version = v + int64(i) + 1
if _, err = x.Id(1).Update(currentVersion); err != nil {
@@ -69,52 +103,59 @@ func Migrate(x *xorm.Engine) error {
return nil
}
-func expiredMigration(x *xorm.Engine) error {
- return errors.New("You are migrating from a too old gogs version")
-}
-
-func mustParseInt64(in []byte) int64 {
- i, err := strconv.ParseInt(string(in), 10, 64)
- if err != nil {
- i = 0
- }
- return i
-}
-
func accessToCollaboration(x *xorm.Engine) error {
type Collaboration struct {
- ID int64 `xorm:"pk autoincr"`
- RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- Created time.Time `xorm:"CREATED"`
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ Created time.Time
}
x.Sync(new(Collaboration))
- sql := `SELECT u.id AS uid, a.repo_name AS repo, a.mode AS mode, a.created as created FROM access a JOIN user u ON a.user_name=u.lower_name`
- results, err := x.Query(sql)
+ results, err := x.Query("SELECT u.id AS `uid`, a.repo_name AS `repo`, a.mode AS `mode`, a.created as `created` FROM `access` a JOIN `user` u ON a.user_name=u.lower_name")
if err != nil {
return err
}
- for _, result := range results {
- userID := mustParseInt64(result["uid"])
- repoRefName := string(result["repo"])
- mode := mustParseInt64(result["mode"])
- created := result["created"]
+ sess := x.NewSession()
+ defer func() {
+ if sess.IsCommitedOrRollbacked {
+ sess.Rollback()
+ }
+ sess.Close()
+ }()
+ if err = sess.Begin(); err != nil {
+ return err
+ }
- //Collaborators must have write access
+ offset := strings.Split(time.Now().String(), " ")[2]
+ for _, result := range results {
+ mode := com.StrTo(result["mode"]).MustInt64()
+ // Collaborators must have write access.
if mode < 2 {
continue
}
+ userID := com.StrTo(result["uid"]).MustInt64()
+ repoRefName := string(result["repo"])
+
+ var created time.Time
+ switch {
+ case setting.UseSQLite3:
+ created, _ = time.Parse(time.RFC3339, string(result["created"]))
+ case setting.UseMySQL:
+ created, _ = time.Parse("2006-01-02 15:04:05-0700", string(result["created"])+offset)
+ case setting.UsePostgreSQL:
+ created, _ = time.Parse("2006-01-02T15:04:05Z-0700", string(result["created"])+offset)
+ }
+
// find owner of repository
parts := strings.SplitN(repoRefName, "/", 2)
ownerName := parts[0]
repoName := parts[1]
- sql = `SELECT u.id as uid, ou.uid as memberid FROM user u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?`
- results, err := x.Query(sql, ownerName)
+ results, err := sess.Query("SELECT u.id as `uid`, ou.uid as `memberid` FROM `user` u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?", ownerName)
if err != nil {
return err
}
@@ -122,7 +163,7 @@ func accessToCollaboration(x *xorm.Engine) error {
continue
}
- ownerID := mustParseInt64(results[0]["uid"])
+ ownerID := com.StrTo(results[0]["uid"]).MustInt64()
if ownerID == userID {
continue
}
@@ -130,7 +171,7 @@ func accessToCollaboration(x *xorm.Engine) error {
// test if user is member of owning organization
isMember := false
for _, member := range results {
- memberID := mustParseInt64(member["memberid"])
+ memberID := com.StrTo(member["memberid"]).MustInt64()
// We can skip all cases that a user is member of the owning organization
if memberID == userID {
isMember = true
@@ -140,24 +181,31 @@ func accessToCollaboration(x *xorm.Engine) error {
continue
}
- sql = `SELECT id FROM repository WHERE owner_id=? AND lower_name=?`
- results, err = x.Query(sql, ownerID, repoName)
+ results, err = sess.Query("SELECT id FROM `repository` WHERE owner_id=? AND lower_name=?", ownerID, repoName)
if err != nil {
return err
- }
- if len(results) < 1 {
+ } else if len(results) < 1 {
continue
}
- repoID := results[0]["id"]
-
- sql = `INSERT INTO collaboration (user_id, repo_id, created) VALUES (?,?,?)`
- _, err = x.Exec(sql, userID, repoID, created)
+ collaboration := &Collaboration{
+ UserID: userID,
+ RepoID: com.StrTo(results[0]["id"]).MustInt64(),
+ }
+ has, err := sess.Get(collaboration)
if err != nil {
return err
+ } else if has {
+ continue
+ }
+
+ collaboration.Created = created
+ if _, err = sess.InsertOne(collaboration); err != nil {
+ return err
}
}
- return nil
+
+ return sess.Commit()
}
func accessRefactor(x *xorm.Engine) error {
diff --git a/models/models.go b/models/models.go
index 1a67041b4a..141e3ac497 100644
--- a/models/models.go
+++ b/models/models.go
@@ -24,7 +24,10 @@ import (
type Engine interface {
Delete(interface{}) (int64, error)
Exec(string, ...interface{}) (sql.Result, error)
+ Get(interface{}) (bool, error)
Insert(...interface{}) (int64, error)
+ Id(interface{}) *xorm.Session
+ Where(string, ...interface{}) *xorm.Session
}
var (
@@ -37,24 +40,29 @@ var (
}
EnableSQLite3 bool
- UseSQLite3 bool
)
func init() {
tables = append(tables,
- new(User), new(PublicKey), new(Follow), new(Oauth2), new(AccessToken),
- new(Repository), new(Watch), new(Star), new(Action), new(Access),
+ new(User), new(PublicKey), new(Oauth2), new(AccessToken),
+ new(Repository), new(Collaboration), new(Access),
+ new(Watch), new(Star), new(Follow), new(Action),
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), new(EmailAddress), new(Collaboration))
+ new(Notice), new(EmailAddress))
}
func LoadModelsConfig() {
sec := setting.Cfg.Section("database")
DbCfg.Type = sec.Key("DB_TYPE").String()
- if DbCfg.Type == "sqlite3" {
- UseSQLite3 = true
+ switch DbCfg.Type {
+ case "sqlite3":
+ setting.UseSQLite3 = true
+ case "mysql":
+ setting.UseMySQL = true
+ case "postgres":
+ setting.UsePostgreSQL = true
}
DbCfg.Host = sec.Key("HOST").String()
DbCfg.Name = sec.Key("NAME").String()
@@ -138,7 +146,7 @@ func NewEngine() (err error) {
}
if err = migrations.Migrate(x); err != nil {
- return err
+ return fmt.Errorf("migrate: %v", err)
}
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
diff --git a/models/org.go b/models/org.go
index f6d472a6d9..d667fb26dc 100644
--- a/models/org.go
+++ b/models/org.go
@@ -10,7 +10,6 @@ import (
"strings"
"github.com/Unknwon/com"
- "github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base"
)
@@ -389,7 +388,7 @@ func RemoveOrgUser(orgId, uid int64) error {
return err
}
for _, t := range ts {
- if err = removeTeamMemberWithSess(org.Id, t.Id, u.Id, sess); err != nil {
+ if err = removeTeamMember(sess, org.Id, t.Id, u.Id); err != nil {
return err
}
}
@@ -617,10 +616,9 @@ func GetTeam(orgId int64, name string) (*Team, error) {
return t, nil
}
-// GetTeamById returns team by given ID.
-func GetTeamById(teamId int64) (*Team, error) {
+func getTeamById(e Engine, teamId int64) (*Team, error) {
t := new(Team)
- has, err := x.Id(teamId).Get(t)
+ has, err := e.Id(teamId).Get(t)
if err != nil {
return nil, err
} else if !has {
@@ -629,6 +627,11 @@ func GetTeamById(teamId int64) (*Team, error) {
return t, nil
}
+// GetTeamById returns team by given ID.
+func GetTeamById(teamId int64) (*Team, error) {
+ return getTeamById(x, teamId)
+}
+
// UpdateTeam updates information of team.
func UpdateTeam(t *Team, authChanged bool) (err error) {
if !IsLegalName(t.Name) {
@@ -729,10 +732,14 @@ type TeamUser struct {
TeamId int64
}
+func isTeamMember(e Engine, orgId, teamId, uid int64) bool {
+ has, _ := e.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser))
+ return has
+}
+
// IsTeamMember returns true if given user is a member of team.
func IsTeamMember(orgId, teamId, uid int64) bool {
- has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser))
- return has
+ return isTeamMember(x, orgId, teamId, uid)
}
// GetTeamMembers returns all members in given team of organization.
@@ -742,17 +749,16 @@ func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
return us, err
}
-// GetUserTeams returns all teams that user belongs to in given organization.
-func GetUserTeams(orgId, uid int64) ([]*Team, error) {
+func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
tus := make([]*TeamUser, 0, 5)
- if err := x.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
+ if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
return nil, err
}
ts := make([]*Team, len(tus))
for i, tu := range tus {
t := new(Team)
- has, err := x.Id(tu.TeamId).Get(t)
+ has, err := e.Id(tu.TeamId).Get(t)
if err != nil {
return nil, err
} else if !has {
@@ -763,6 +769,11 @@ func GetUserTeams(orgId, uid int64) ([]*Team, error) {
return ts, nil
}
+// GetUserTeams returns all teams that user belongs to in given organization.
+func GetUserTeams(orgId, uid int64) ([]*Team, error) {
+ return getUserTeams(x, orgId, uid)
+}
+
// AddTeamMember adds new member to given team of given organization.
func AddTeamMember(orgId, teamId, uid int64) error {
if IsTeamMember(orgId, teamId, uid) {
@@ -831,13 +842,13 @@ func AddTeamMember(orgId, teamId, uid int64) error {
return sess.Commit()
}
-func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) error {
- if !IsTeamMember(orgId, teamId, uid) {
+func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
+ if !isTeamMember(e, orgId, teamId, uid) {
return nil
}
// Get team and its repositories.
- t, err := GetTeamById(teamId)
+ t, err := getTeamById(e, teamId)
if err != nil {
return err
}
@@ -865,35 +876,30 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
TeamId: teamId,
}
- if _, err := sess.Delete(tu); err != nil {
- sess.Rollback()
+ if _, err := e.Delete(tu); err != nil {
return err
- } else if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
- sess.Rollback()
+ } else if _, err = e.Id(t.Id).AllCols().Update(t); err != nil {
return err
}
// Delete access to team repositories.
for _, repo := range t.Repos {
if err = repo.RecalcAccessSess(); err != nil {
- sess.Rollback()
return err
}
}
// This must exist.
ou := new(OrgUser)
- _, err = sess.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
+ _, err = e.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
if err != nil {
- sess.Rollback()
return err
}
ou.NumTeams--
if t.IsOwnerTeam() {
ou.IsOwner = false
}
- if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil {
- sess.Rollback()
+ if _, err = e.Id(ou.Id).AllCols().Update(ou); err != nil {
return err
}
return nil
@@ -906,7 +912,8 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
if err := sess.Begin(); err != nil {
return err
}
- if err := removeTeamMemberWithSess(orgId, teamId, uid, sess); err != nil {
+ if err := removeTeamMember(sess, orgId, teamId, uid); err != nil {
+ sess.Rollback()
return err
}
return sess.Commit()
diff --git a/models/publickey.go b/models/publickey.go
index 67ab4242f2..383b85b634 100644
--- a/models/publickey.go
+++ b/models/publickey.go
@@ -29,7 +29,7 @@ import (
const (
// "### autogenerated by gitgos, DO NOT EDIT\n"
- _TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
+ _TPL_PUBLICK_KEY = `command="%s serv key-%d --config='%s'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
)
var (
@@ -98,7 +98,7 @@ func (k *PublicKey) OmitEmail() string {
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
- return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content)
+ return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, setting.CustomConf, key.Content)
}
var (
diff --git a/models/repo.go b/models/repo.go
index 5943dd31ad..5a669d9dd8 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -30,7 +30,7 @@ import (
)
const (
- TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3\n"
+ _TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3 --config='%s'\n"
)
var (
@@ -239,8 +239,8 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil {
return cl, err
}
- if setting.SshPort != 22 {
- cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SshPort, repo.Owner.LowerName, repo.LowerName)
+ if setting.SSHPort != 22 {
+ cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
}
@@ -349,13 +349,16 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
os.RemoveAll(repoPath)
}
- // this command could for both migrate and mirror
+ // FIXME: this command could for both migrate and mirror
_, stderr, err := process.ExecTimeout(10*time.Minute,
fmt.Sprintf("MigrateRepository: %s", repoPath),
"git", "clone", "--mirror", "--bare", url, repoPath)
if err != nil {
- return repo, errors.New("git clone: " + stderr)
+ return repo, fmt.Errorf("git clone --mirror --bare: %v", stderr)
+ } else if err = createUpdateHook(repoPath); err != nil {
+ return repo, fmt.Errorf("create update hook: %v", err)
}
+
return repo, UpdateRepository(repo)
}
@@ -394,15 +397,9 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
return nil
}
-func createHookUpdate(hookPath, content string) error {
- pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777)
- if err != nil {
- return err
- }
- defer pu.Close()
-
- _, err = pu.WriteString(content)
- return err
+func createUpdateHook(repoPath string) error {
+ return ioutil.WriteFile(path.Join(repoPath, "hooks/update"),
+ []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777)
}
// InitRepository initializes README and .gitignore if needed.
@@ -414,9 +411,7 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
return err
}
- // hook/post-update
- if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
- fmt.Sprintf(TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"")); err != nil {
+ if err := createUpdateHook(repoPath); err != nil {
return err
}
@@ -938,58 +933,6 @@ func GetRepositoryCount(user *User) (int64, error) {
return x.Count(&Repository{OwnerId: user.Id})
}
-// GetCollaborators returns the collaborators for a repository
-func (r *Repository) GetCollaborators() ([]*User, error) {
- collaborations := make([]*Collaboration, 0)
- if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil {
- return nil, err
- }
-
- users := make([]*User, len(collaborations))
- for i, c := range collaborations {
- user, err := GetUserById(c.UserID)
- if err != nil {
- return nil, err
- }
- users[i] = user
- }
- return users, nil
-}
-
-// Add collaborator and accompanying access
-func (r *Repository) AddCollaborator(u *User) error {
- collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
-
- has, err := x.Get(collaboration)
- if err != nil {
- return err
- }
- if has {
- return nil
- }
-
- if _, err = x.InsertOne(collaboration); err != nil {
- return err
- }
-
- if err = r.GetOwner(); err != nil {
- return err
- }
-
- return r.RecalcAccessSess()
-}
-
-// Delete collaborator and accompanying access
-func (r *Repository) DeleteCollaborator(u *User) error {
- collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
-
- if has, err := x.Delete(collaboration); err != nil || has == 0 {
- return err
- }
-
- return r.RecalcAccessSess()
-}
-
type SearchOption struct {
Keyword string
Uid int64
@@ -1030,6 +973,18 @@ func DeleteRepositoryArchives() error {
})
}
+// RewriteRepositoryUpdateHook rewrites all repositories' update hook.
+func RewriteRepositoryUpdateHook() error {
+ return x.Where("id > 0").Iterate(new(Repository),
+ func(idx int, bean interface{}) error {
+ repo := bean.(*Repository)
+ if err := repo.GetOwner(); err != nil {
+ return err
+ }
+ return createUpdateHook(RepoPath(repo.Owner.Name, repo.Name))
+ })
+}
+
var (
// Prevent duplicate tasks.
isMirrorUpdating = false
@@ -1125,6 +1080,73 @@ func GitGcRepos() error {
})
}
+// _________ .__ .__ ___. __ .__
+// \_ ___ \ ____ | | | | _____ \_ |__ ________________ _/ |_|__| ____ ____
+// / \ \/ / _ \| | | | \__ \ | __ \ / _ \_ __ \__ \\ __\ |/ _ \ / \
+// \ \___( <_> ) |_| |__/ __ \| \_\ ( <_> ) | \// __ \| | | ( <_> ) | \
+// \______ /\____/|____/____(____ /___ /\____/|__| (____ /__| |__|\____/|___| /
+// \/ \/ \/ \/ \/
+
+// A Collaboration is a relation between an individual and a repository
+type Collaboration struct {
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ Created time.Time `xorm:"CREATED"`
+}
+
+// Add collaborator and accompanying access
+func (r *Repository) AddCollaborator(u *User) error {
+ collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
+
+ has, err := x.Get(collaboration)
+ if err != nil {
+ return err
+ }
+ if has {
+ return nil
+ }
+
+ if _, err = x.InsertOne(collaboration); err != nil {
+ return err
+ }
+
+ if err = r.GetOwner(); err != nil {
+ return err
+ }
+
+ return r.RecalcAccessSess()
+}
+
+// GetCollaborators returns the collaborators for a repository
+func (r *Repository) GetCollaborators() ([]*User, error) {
+ collaborations := make([]*Collaboration, 0)
+ if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil {
+ return nil, err
+ }
+
+ users := make([]*User, len(collaborations))
+ for i, c := range collaborations {
+ user, err := GetUserById(c.UserID)
+ if err != nil {
+ return nil, err
+ }
+ users[i] = user
+ }
+ return users, nil
+}
+
+// Delete collaborator and accompanying access
+func (r *Repository) DeleteCollaborator(u *User) error {
+ collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
+
+ if has, err := x.Delete(collaboration); err != nil || has == 0 {
+ return err
+ }
+
+ return r.RecalcAccessSess()
+}
+
// __ __ __ .__
// / \ / \_____ _/ |_ ____ | |__
// \ \/\/ /\__ \\ __\/ ___\| | \
@@ -1145,7 +1167,7 @@ func IsWatching(uid, repoId int64) bool {
return has
}
-func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) {
+func watchRepo(e Engine, uid, repoId int64, watch bool) (err error) {
if watch {
if IsWatching(uid, repoId) {
return nil
@@ -1168,7 +1190,7 @@ func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) {
// Watch or unwatch repository.
func WatchRepo(uid, repoId int64, watch bool) (err error) {
- return watchRepoWithEngine(x, uid, repoId, watch)
+ return watchRepo(x, uid, repoId, watch)
}
// GetWatchers returns all watchers of given repository.
@@ -1326,14 +1348,14 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
log.Error(4, "GetMembers: %v", err)
} else {
for _, u := range t.Members {
- if err = watchRepoWithEngine(sess, u.Id, repo.Id, true); err != nil {
+ if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo2: %v", err)
}
}
}
}
} else {
- if err = watchRepoWithEngine(sess, u.Id, repo.Id, true); err != nil {
+ if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo3: %v", err)
}
}
@@ -1375,11 +1397,3 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
return repo, nil
}
-
-// A Collaboration is a relation between an individual and a repository
-type Collaboration struct {
- ID int64 `xorm:"pk autoincr"`
- RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- Created time.Time `xorm:"CREATED"`
-}
diff --git a/models/user.go b/models/user.go
index b33e529aa6..7e3dc260e5 100644
--- a/models/user.go
+++ b/models/user.go
@@ -512,8 +512,7 @@ func UserPath(userName string) string {
func GetUserByKeyId(keyId int64) (*User, error) {
user := new(User)
- rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?"
- has, err := x.Sql(rawSql, keyId).Get(user)
+ has, err := x.Sql("SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?", keyId).Get(user)
if err != nil {
return nil, err
} else if !has {
diff --git a/models/webhook.go b/models/webhook.go
index 8e112ac572..96af0b6967 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -5,6 +5,7 @@
package models
import (
+ "crypto/tls"
"encoding/json"
"errors"
"io/ioutil"
@@ -307,13 +308,14 @@ func DeliverHooks() {
defer func() { isShooting = false }()
tasks := make([]*HookTask, 0, 10)
- timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
+ timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Header("X-Gogs-Delivery", t.Uuid).
- Header("X-Gogs-Event", string(t.EventType))
+ Header("X-Gogs-Event", string(t.EventType)).
+ SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
switch t.ContentType {
case JSON:
@@ -329,7 +331,7 @@ func DeliverHooks() {
case GOGS:
{
if _, err := req.Response(); err != nil {
- log.Error(4, "Delivery: %v", err)
+ log.Error(5, "Delivery: %v", err)
} else {
t.IsSucceed = true
}
@@ -337,15 +339,15 @@ func DeliverHooks() {
case SLACK:
{
if res, err := req.Response(); err != nil {
- log.Error(4, "Delivery: %v", err)
+ log.Error(5, "Delivery: %v", err)
} else {
defer res.Body.Close()
contents, err := ioutil.ReadAll(res.Body)
if err != nil {
- log.Error(4, "%s", err)
+ log.Error(5, "%s", err)
} else {
if string(contents) != "ok" {
- log.Error(4, "slack failed with: %s", string(contents))
+ log.Error(5, "slack failed with: %s", string(contents))
} else {
t.IsSucceed = true
}