Merge branch 'dev' into newcollaboration

This commit is contained in:
Peter Smit 2015-02-05 11:08:10 +02:00
commit 03af37554e
47 changed files with 1297 additions and 359 deletions

View file

@ -41,12 +41,14 @@ var (
var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
IssueKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueKeywordsPat *regexp.Regexp
IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueCloseKeywordsPat *regexp.Regexp
IssueReferenceKeywordsPat *regexp.Regexp
)
func init() {
IssueKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueKeywords, "|")))
IssueCloseKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueCloseKeywords, "|")))
IssueReferenceKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:) \S+`))
}
// Action represents user operation type and other information to repository.,
@ -110,13 +112,13 @@ func (a Action) GetIssueInfos() []string {
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits {
refs := IssueKeywordsPat.FindAllString(c.Message, -1)
for _, ref := range refs {
references := IssueReferenceKeywordsPat.FindAllString(c.Message, -1)
for _, ref := range references {
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
@ -144,6 +146,35 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
return err
}
}
closes := IssueCloseKeywordsPat.FindAllString(c.Message, -1)
for _, ref := range closes {
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 {
@ -168,6 +199,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
}
}
}
return nil

View file

@ -33,7 +33,7 @@ var (
HasEngine bool
DbCfg struct {
Type, Host, Name, User, Pwd, Path, SslMode string
Type, Host, Name, User, Passwd, Path, SSLMode string
}
EnableSQLite3 bool
@ -59,10 +59,10 @@ func LoadModelsConfig() {
DbCfg.Host = sec.Key("HOST").String()
DbCfg.Name = sec.Key("NAME").String()
DbCfg.User = sec.Key("USER").String()
if len(DbCfg.Pwd) == 0 {
DbCfg.Pwd = sec.Key("PASSWD").String()
if len(DbCfg.Passwd) == 0 {
DbCfg.Passwd = sec.Key("PASSWD").String()
}
DbCfg.SslMode = sec.Key("SSL_MODE").String()
DbCfg.SSLMode = sec.Key("SSL_MODE").String()
DbCfg.Path = sec.Key("PATH").MustString("data/gogs.db")
}
@ -71,7 +71,7 @@ func getEngine() (*xorm.Engine, error) {
switch DbCfg.Type {
case "mysql":
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name)
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
case "postgres":
var host, port = "127.0.0.1", "5432"
fields := strings.Split(DbCfg.Host, ":")
@ -82,7 +82,7 @@ func getEngine() (*xorm.Engine, error) {
port = fields[1]
}
cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode)
DbCfg.User, DbCfg.Passwd, host, port, DbCfg.Name, DbCfg.SSLMode)
case "sqlite3":
if !EnableSQLite3 {
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
@ -98,7 +98,7 @@ func getEngine() (*xorm.Engine, error) {
func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to connect to database): %v", err)
return fmt.Errorf("connect to database: %v", err)
}
x.SetMapper(core.GonicMapper{})
@ -108,7 +108,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
func SetEngine() (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to connect to database): %v", err)
return fmt.Errorf("connect to database: %v", err)
}
x.SetMapper(core.GonicMapper{})

View file

@ -33,7 +33,7 @@ const (
)
var (
ErrKeyAlreadyExist = errors.New("Public key already exist")
ErrKeyAlreadyExist = errors.New("Public key already exists")
ErrKeyNotExist = errors.New("Public key does not exist")
ErrKeyUnableVerify = errors.New("Unable to verify public key")
)
@ -41,7 +41,7 @@ var (
var sshOpLocker = sync.Mutex{}
var (
SshPath string // SSH directory.
SSHPath string // SSH directory.
appPath string // Execution(binary) path.
)
@ -72,9 +72,9 @@ func init() {
appPath = strings.Replace(appPath, "\\", "/", -1)
// Determine and create .ssh path.
SshPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(SshPath, 0700); err != nil {
log.Fatal(4, "fail to create SshPath(%s): %v\n", SshPath, err)
SSHPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(SSHPath, 0700); err != nil {
log.Fatal(4, "fail to create '%s': %v", SSHPath, err)
}
}
@ -244,16 +244,17 @@ func CheckPublicKeyString(content string) (bool, error) {
}
// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
func saveAuthorizedKeyFile(key *PublicKey) error {
func saveAuthorizedKeyFile(keys ...*PublicKey) error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
fpath := filepath.Join(SshPath, "authorized_keys")
fpath := filepath.Join(SSHPath, "authorized_keys")
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
}
defer f.Close()
finfo, err := f.Stat()
if err != nil {
return err
@ -269,8 +270,12 @@ func saveAuthorizedKeyFile(key *PublicKey) error {
}
}
_, err = f.WriteString(key.GetAuthorizedString())
return err
for _, key := range keys {
if _, err = f.WriteString(key.GetAuthorizedString()); err != nil {
return err
}
}
return nil
}
// AddPublicKey adds new public key to database and authorized_keys file.
@ -413,8 +418,8 @@ func DeletePublicKey(key *PublicKey) error {
return err
}
fpath := filepath.Join(SshPath, "authorized_keys")
tmpPath := filepath.Join(SshPath, "authorized_keys.tmp")
fpath := filepath.Join(SSHPath, "authorized_keys")
tmpPath := filepath.Join(SSHPath, "authorized_keys.tmp")
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
return err
} else if err = os.Remove(fpath); err != nil {
@ -422,3 +427,37 @@ func DeletePublicKey(key *PublicKey) error {
}
return os.Rename(tmpPath, fpath)
}
// RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
func RewriteAllPublicKeys() error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
tmpPath := filepath.Join(SSHPath, "authorized_keys.tmp")
f, err := os.Create(tmpPath)
if err != nil {
return err
}
defer os.Remove(tmpPath)
err = x.Iterate(new(PublicKey), func(idx int, bean interface{}) (err error) {
_, err = f.WriteString((bean.(*PublicKey)).GetAuthorizedString())
return err
})
f.Close()
if err != nil {
return err
}
fpath := filepath.Join(SSHPath, "authorized_keys")
if com.IsExist(fpath) {
if err = os.Remove(fpath); err != nil {
return err
}
}
if err = os.Rename(tmpPath, fpath); err != nil {
return err
}
return nil
}

View file

@ -7,7 +7,6 @@ package models
import (
"errors"
"fmt"
"html"
"html/template"
"io/ioutil"
"os"
@ -218,11 +217,9 @@ func (repo *Repository) HasAccess(uname string) bool {
// DescriptionHtml does special handles to description and return HTML string.
func (repo *Repository) DescriptionHtml() template.HTML {
sanitize := func(s string) string {
// TODO(nuss-justin): Improve sanitization. Strip all tags?
ss := html.EscapeString(s)
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss)
return fmt.Sprintf(`<a href="%[1]s" target="_blank">%[1]s</a>`, s)
}
return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize))
return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize))
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
@ -507,6 +504,11 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
}
if len(fileName) == 0 {
// Re-fetch the repository from database before updating it (else it would
// override changes that were done earlier with sql)
if repo, err = GetRepositoryById(repo.Id); err != nil {
return err
}
repo.IsBare = true
repo.DefaultBranch = "master"
return UpdateRepository(repo)

View file

@ -477,6 +477,7 @@ func UpdateUser(u *User) error {
}
u.Avatar = avatar.HashEmail(u.AvatarEmail)
u.FullName = base.Sanitizer.Sanitize(u.FullName)
_, err = x.Id(u.Id).AllCols().Update(u)
return err
}