Merge branch 'dev' of github.com:gogits/gogs into dev

This commit is contained in:
2014-06-28 15:00:32 +08:00
113 changed files with 5708 additions and 1868 deletions
-2
View File
@@ -19,8 +19,6 @@ github.com/gogits/session = `commit:7ab78d4`
github.com/juju2013/goldap = `commit:f4a7f67`
github.com/lib/pq = `commit:529edd9`
github.com/nfnt/resize = `commit:8aee0d9`
github.com/qiniu/log = `commit:891d1cb`
github.com/robfig/cron = `commit:b024fc5`
[res]
include = templates|public
+3 -6
View File
@@ -5,11 +5,11 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language
![Demo](http://gowalker.org/public/gogs_demo.gif)
##### Current version: 0.4.0 Alpha
##### Current version: 0.4.5 Alpha
### NOTICES
- Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in **April 14, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in **June 21, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Demo site [try.gogits.org](http://try.gogits.org) is running under `dev` branch.
#### Other language version
@@ -33,7 +33,7 @@ More importantly, Gogs only needs one binary to setup your own project hosting o
- Activity timeline
- SSH/HTTP(S) protocol support
- SMTP/LDAP authentication support
- SMTP/LDAP/reverse proxy authentication support
- Register/delete/rename account
- Create/migrate/mirror/delete/watch/rename/transfer public/private repository
- Repository viewer/release/issue tracker/webhooks
@@ -75,9 +75,6 @@ There are 5 ways to install Gogs:
The [core team](http://gogs.io/team) of this project. See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
[koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1
## License
This project is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text.
+2 -5
View File
@@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。
![Demo](http://gowalker.org/public/gogs_demo.gif)
##### 当前版本:0.4.0 Alpha
##### 当前版本:0.4.5 Alpha
## 开发目的
@@ -24,7 +24,7 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依
- 活动时间线
- 支持 SSH/HTTP(S) 协议
- 支持 SMTP/LDAP 用户认证
- 支持 SMTP/LDAP/反向代理 用户认证
- 注册/删除/重命名用户
- 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库
- 仓库 浏览器/发布/缺陷管理/Web 钩子
@@ -66,9 +66,6 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依
本项目的 [开发团队](http://gogs.io/team)。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
[koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1
## 授权许可
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。
+150 -20
View File
@@ -5,10 +5,16 @@
package cmd
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"strings"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/setting"
)
@@ -16,28 +22,152 @@ import (
var CmdFix = cli.Command{
Name: "fix",
Usage: "This command for upgrade from old version",
Description: `Fix provide upgrade from old version`,
Action: runFix,
Subcommands: fixCommands,
Flags: []cli.Flag{},
}
func runFix(k *cli.Context) {
workDir, _ := setting.WorkDir()
newLogger(workDir)
setting.NewConfigContext()
models.LoadModelsConfig()
if models.UseSQLite3 {
os.Chdir(workDir)
}
models.SetEngine()
err := models.Fix()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Fix successfully!")
}
func runFix(ctx *cli.Context) {
}
var fixCommands = []cli.Command{
{
Name: "location",
Usage: "Change Gogs app location",
Description: `Command location fixes location change of Gogs
gogs fix location <old Gogs path>
`,
Action: runFixLocation,
},
}
// rewriteAuthorizedKeys replaces old Gogs path to the new one.
func rewriteAuthorizedKeys(sshPath, oldPath, newPath string) error {
fr, err := os.Open(sshPath)
if err != nil {
return err
}
defer fr.Close()
tmpPath := sshPath + ".tmp"
fw, err := os.Create(tmpPath)
if err != nil {
return err
}
defer fw.Close()
oldPath = "command=\"" + oldPath + " serv"
newPath = "command=\"" + newPath + " serv"
buf := bufio.NewReader(fr)
for {
line, errRead := buf.ReadString('\n')
line = strings.TrimSpace(line)
if errRead != nil {
if errRead != io.EOF {
return errRead
}
// Reached end of file, if nothing to read then break,
// otherwise handle the last line.
if len(line) == 0 {
break
}
}
// Still finding the line, copy the line that currently read.
if _, err = fw.WriteString(strings.Replace(line, oldPath, newPath, 1) + "\n"); err != nil {
return err
}
if errRead == io.EOF {
break
}
}
if err = os.Remove(sshPath); err != nil {
return err
}
return os.Rename(tmpPath, sshPath)
}
func rewriteUpdateHook(path, appPath string) error {
rp := strings.NewReplacer("\\", "/", " ", "\\ ")
if err := ioutil.WriteFile(path, []byte(fmt.Sprintf(models.TPL_UPDATE_HOOK,
setting.ScriptType, rp.Replace(appPath))), os.ModePerm); err != nil {
return err
}
return nil
}
func walkDir(rootPath, recPath, appPath string, depth int) error {
depth++
if depth > 3 {
return nil
} else if depth == 3 {
if err := rewriteUpdateHook(path.Join(rootPath, "hooks/update"), appPath); err != nil {
return err
}
}
dir, err := os.Open(rootPath)
if err != nil {
return err
}
defer dir.Close()
fis, err := dir.Readdir(0)
if err != nil {
return err
}
for _, fi := range fis {
if strings.Contains(fi.Name(), ".DS_Store") {
continue
}
relPath := path.Join(recPath, fi.Name())
curPath := path.Join(rootPath, fi.Name())
if fi.IsDir() {
if err = walkDir(curPath, relPath, appPath, depth); err != nil {
return err
}
}
}
return nil
}
func runFixLocation(ctx *cli.Context) {
if len(ctx.Args()) != 1 {
fmt.Println("Incorrect arguments number, expect 1")
os.Exit(2)
}
execPath, _ := setting.ExecPath()
oldPath := ctx.Args().First()
fmt.Printf("Old location: %s\n", oldPath)
fmt.Println("This command should be executed in the new Gogs path")
fmt.Printf("Do you want to change Gogs app path from old location to:\n")
fmt.Printf("-> %s?\n", execPath)
fmt.Print("Press <enter> to continue, use <Ctrl+c> to exit.")
fmt.Scanln()
// Fix in authorized_keys file.
sshPath := path.Join(models.SshPath, "authorized_keys")
fmt.Printf("Fixing pathes in file: %s\n", sshPath)
if err := rewriteAuthorizedKeys(sshPath, oldPath, execPath); err != nil {
fmt.Println(err)
os.Exit(1)
}
// Fix position in gogs-repositories.
setting.NewConfigContext()
fmt.Printf("Fixing pathes in repositories: %s\n", setting.RepoRootPath)
if err := walkDir(setting.RepoRootPath, "", execPath, 0); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("Fix position finished!")
}
+30 -53
View File
@@ -13,9 +13,9 @@ import (
"strings"
"github.com/codegangsta/cli"
qlog "github.com/qiniu/log"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
@@ -27,27 +27,13 @@ var CmdServ = cli.Command{
Flags: []cli.Flag{},
}
func newLogger(logPath string) {
os.MkdirAll(path.Dir(logPath), os.ModePerm)
f, err := os.OpenFile(logPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.ModePerm)
if err != nil {
qlog.Fatal(err)
}
qlog.SetOutput(f)
//qlog.SetOutputLevel(qlog.Ldebug)
qlog.Info("Start logging serv...")
}
func setup(logPath string) {
workDir, _ := setting.WorkDir()
newLogger(path.Join(workDir, logPath))
setting.NewConfigContext()
log.NewGitLogger(path.Join(setting.LogRootPath, logPath))
models.LoadModelsConfig()
if models.UseSQLite3 {
workDir, _ := setting.WorkDir()
os.Chdir(workDir)
}
@@ -70,45 +56,45 @@ func parseCmd(cmd string) (string, string) {
}
var (
COMMANDS_READONLY = map[string]int{
"git-upload-pack": models.AU_WRITABLE,
"git upload-pack": models.AU_WRITABLE,
"git-upload-archive": models.AU_WRITABLE,
COMMANDS_READONLY = map[string]models.AccessType{
"git-upload-pack": models.WRITABLE,
"git upload-pack": models.WRITABLE,
"git-upload-archive": models.WRITABLE,
}
COMMANDS_WRITE = map[string]int{
"git-receive-pack": models.AU_READABLE,
"git receive-pack": models.AU_READABLE,
COMMANDS_WRITE = map[string]models.AccessType{
"git-receive-pack": models.READABLE,
"git receive-pack": models.READABLE,
}
)
func In(b string, sl map[string]int) bool {
func In(b string, sl map[string]models.AccessType) bool {
_, e := sl[b]
return e
}
func runServ(k *cli.Context) {
setup(path.Join(setting.LogRootPath, "serv.log"))
setup("serv.log")
keys := strings.Split(os.Args[2], "-")
if len(keys) != 2 {
println("Gogs: auth file format error")
qlog.Fatal("Invalid auth file format: %s", os.Args[2])
log.GitLogger.Fatal("Invalid auth file format: %s", os.Args[2])
}
keyId, err := strconv.ParseInt(keys[1], 10, 64)
if err != nil {
println("Gogs: auth file format error")
qlog.Fatalf("Invalid auth file format: %v", err)
log.GitLogger.Fatal("Invalid auth file format: %v", err)
}
user, err := models.GetUserByKeyId(keyId)
if err != nil {
if err == models.ErrUserNotKeyOwner {
println("Gogs: you are not the owner of SSH key")
qlog.Fatalf("Invalid owner of SSH key: %d", keyId)
log.GitLogger.Fatal("Invalid owner of SSH key: %d", keyId)
}
println("Gogs: internal error:", err)
qlog.Fatalf("Fail to get user by key ID(%d): %v", keyId, err)
log.GitLogger.Fatal("Fail to get user by key ID(%d): %v", keyId, err)
}
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
@@ -122,7 +108,7 @@ func runServ(k *cli.Context) {
rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
println("Gogs: unavailable repository", args)
qlog.Fatalf("Unavailable repository: %v", args)
log.GitLogger.Fatal("Unavailable repository: %v", args)
}
repoUserName := rr[0]
repoName := strings.TrimSuffix(rr[1], ".git")
@@ -134,45 +120,45 @@ func runServ(k *cli.Context) {
if err != nil {
if err == models.ErrUserNotExist {
println("Gogs: given repository owner are not registered")
qlog.Fatalf("Unregistered owner: %s", repoUserName)
log.GitLogger.Fatal("Unregistered owner: %s", repoUserName)
}
println("Gogs: internal error:", err)
qlog.Fatalf("Fail to get repository owner(%s): %v", repoUserName, err)
log.GitLogger.Fatal("Fail to get repository owner(%s): %v", repoUserName, err)
}
// Access check.
switch {
case isWrite:
has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_WRITABLE)
has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.WRITABLE)
if err != nil {
println("Gogs: internal error:", err)
qlog.Fatal("Fail to check write access:", err)
log.GitLogger.Fatal("Fail to check write access:", err)
} else if !has {
println("You have no right to write this repository")
qlog.Fatalf("User %s has no right to write repository %s", user.Name, repoPath)
log.GitLogger.Fatal("User %s has no right to write repository %s", user.Name, repoPath)
}
case isRead:
repo, err := models.GetRepositoryByName(repoUser.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
println("Gogs: given repository does not exist")
qlog.Fatalf("Repository does not exist: %s/%s", repoUser.Name, repoName)
log.GitLogger.Fatal("Repository does not exist: %s/%s", repoUser.Name, repoName)
}
println("Gogs: internal error:", err)
qlog.Fatalf("Fail to get repository: %v", err)
log.GitLogger.Fatal("Fail to get repository: %v", err)
}
if !repo.IsPrivate {
break
}
has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_READABLE)
has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.READABLE)
if err != nil {
println("Gogs: internal error:", err)
qlog.Fatal("Fail to check read access:", err)
log.GitLogger.Fatal("Fail to check read access:", err)
} else if !has {
println("You have no right to access this repository")
qlog.Fatalf("User %s has no right to read repository %s", user.Name, repoPath)
log.GitLogger.Fatal("User %s has no right to read repository %s", user.Name, repoPath)
}
default:
println("Unknown command")
@@ -186,18 +172,9 @@ func runServ(k *cli.Context) {
gitcmd.Stdout = os.Stdout
gitcmd.Stdin = os.Stdin
gitcmd.Stderr = os.Stderr
if err = gitcmd.Run(); err != nil {
err = gitcmd.Run()
if err != nil {
println("Gogs: internal error:", err)
qlog.Fatalf("Fail to execute git command: %v", err)
log.GitLogger.Fatal("Fail to execute git command: %v", err)
}
//refName := os.Getenv("refName")
//oldCommitId := os.Getenv("oldCommitId")
//newCommitId := os.Getenv("newCommitId")
//qlog.Error("get envs:", refName, oldCommitId, newCommitId)
// update
//models.Update(refName, oldCommitId, newCommitId, repoUserName, repoName, user.Id)
}
+7 -17
View File
@@ -6,14 +6,12 @@ package cmd
import (
"os"
"path"
"strconv"
"github.com/codegangsta/cli"
qlog "github.com/qiniu/log"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/log"
)
var CmdUpdate = cli.Command{
@@ -24,35 +22,27 @@ var CmdUpdate = cli.Command{
Flags: []cli.Flag{},
}
func updateEnv(refName, oldCommitId, newCommitId string) {
os.Setenv("refName", refName)
os.Setenv("oldCommitId", oldCommitId)
os.Setenv("newCommitId", newCommitId)
qlog.Info("set envs:", refName, oldCommitId, newCommitId)
}
func runUpdate(c *cli.Context) {
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" {
return
}
setup(path.Join(setting.LogRootPath, "update.log"))
setup("update.log")
args := c.Args()
if len(args) != 3 {
qlog.Fatal("received less 3 parameters")
log.GitLogger.Fatal("received less 3 parameters")
} else if args[0] == "" {
qlog.Fatal("refName is empty, shouldn't use")
log.GitLogger.Fatal("refName is empty, shouldn't use")
}
//updateEnv(args[0], args[1], args[2])
userName := os.Getenv("userName")
userId, _ := strconv.ParseInt(os.Getenv("userId"), 10, 64)
//repoId := os.Getenv("repoId")
repoUserName := os.Getenv("repoUserName")
repoName := os.Getenv("repoName")
models.Update(args[0], args[1], args[2], userName, repoUserName, repoName, userId)
if err := models.Update(args[0], args[1], args[2], userName, repoUserName, repoName, userId); err != nil {
log.GitLogger.Fatal(err.Error())
}
}
+29 -7
View File
@@ -27,6 +27,7 @@ import (
"github.com/gogits/gogs/routers/admin"
"github.com/gogits/gogs/routers/api/v1"
"github.com/gogits/gogs/routers/dev"
"github.com/gogits/gogs/routers/org"
"github.com/gogits/gogs/routers/repo"
"github.com/gogits/gogs/routers/user"
)
@@ -89,11 +90,13 @@ func runWeb(*cli.Context) {
m.Get("/", ignSignIn, routers.Home)
m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Get("/issues", reqSignIn, user.Issues)
m.Get("/pulls", reqSignIn, user.Pulls)
m.Get("/stars", reqSignIn, user.Stars)
m.Group("", func(r martini.Router) {
r.Get("/issues", user.Issues)
r.Get("/pulls", user.Pulls)
r.Get("/stars", user.Stars)
}, reqSignIn)
m.Group("/api", func(r martini.Router) {
m.Group("/api", func(_ martini.Router) {
m.Group("/v1", func(r martini.Router) {
// Miscellaneous.
r.Post("/markdown", bindIgnErr(apiv1.MarkdownForm{}), v1.Markdown)
@@ -159,8 +162,9 @@ func runWeb(*cli.Context) {
m.Group("/admin", func(r martini.Router) {
r.Get("/users", admin.Users)
r.Get("/repos", admin.Repositories)
r.Get("/config", admin.Config)
r.Get("/auths", admin.Auths)
r.Get("/config", admin.Config)
r.Get("/monitor", admin.Monitor)
}, adminReq)
m.Group("/admin/users", func(r martini.Router) {
r.Get("/new", admin.NewUser)
@@ -184,6 +188,22 @@ func runWeb(*cli.Context) {
reqOwner := middleware.RequireOwner()
m.Group("/org", func(r martini.Router) {
r.Get("/create", org.New)
r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.NewPost)
r.Get("/:org", org.Organization)
r.Get("/:org/dashboard", org.Dashboard)
r.Get("/:org/members", org.Members)
r.Get("/:org/teams/:team/edit", org.EditTeam)
r.Get("/:org/teams/new", org.NewTeam)
r.Get("/:org/teams", org.Teams)
r.Get("/:org/settings", org.Settings)
r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost)
r.Post("/:org/settings/delete", org.DeletePost)
}, reqSignIn)
m.Group("/:username/:reponame", func(r martini.Router) {
r.Get("/settings", repo.Setting)
r.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingPost)
@@ -221,11 +241,13 @@ func runWeb(*cli.Context) {
})
r.Post("/comment/:action", repo.Comment)
r.Get("/releases/new", repo.ReleasesNew)
r.Get("/releases/new", repo.NewRelease)
r.Get("/releases/edit/:tagname", repo.EditRelease)
}, reqSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func(r martini.Router) {
r.Post("/releases/new", bindIgnErr(auth.NewReleaseForm{}), repo.ReleasesNewPost)
r.Post("/releases/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
r.Post("/releases/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, reqSignIn, middleware.RepoAssignment(true, true))
m.Group("/:username/:reponame", func(r martini.Router) {
+12
View File
@@ -51,6 +51,8 @@ SECRET_KEY = !#@FDEWREWR&*(
LOGIN_REMEMBER_DAYS = 7
COOKIE_USERNAME = gogs_awesome
COOKIE_REMEMBER_NAME = gogs_incredible
; Reverse proxy authentication header name of user name
REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
[service]
ACTIVE_CODE_LIVE_MINUTES = 180
@@ -65,6 +67,14 @@ REQUIRE_SIGNIN_VIEW = false
ENABLE_CACHE_AVATAR = false
; Mail notification
ENABLE_NOTIFY_MAIL = false
; More detail: https://github.com/gogits/gogs/issues/165
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
[webhook]
; Cron task interval in minutes
TASK_INTERVAL = 1
; Deliver timeout in seconds
DELIVER_TIMEOUT = 5
[mailer]
ENABLED = false
@@ -227,5 +237,7 @@ RECEIVERS =
; For "database" mode only
[log.database]
LEVEL =
; Either "mysql" or "postgres"
DRIVER =
; Based on xorm, e.g.: root:root@localhost/gogs?charset=utf8
CONN =
+12 -6
View File
@@ -10,6 +10,12 @@ HOST_PORT="YOUR_HOST_PORT" # The port on host, which will be redirected t
# apt source, you can select 'nchc'(mirror in Taiwan) or 'aliyun'(best for mainlance China users) according to your network, if you could connect to the official unbunt mirror in a fast speed, just leave it to "".
APT_SOURCE=""
DOCKER_BIN=$(which docker.io || which docker)
if [ -z "$DOCKER_BIN" ] ; then
echo "Please install docker. You can install docker by running \"wget -qO- https://get.docker.io/ | sh\"."
exit 1
fi
# Replace the database root password in database image Dockerfile.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/$DB_TYPE/Dockerfile
# Replace the database root password in gogits image deploy.sh file.
@@ -36,22 +42,22 @@ if [ $MEM_TYPE != "" ]
sed -i "${GOGS_BUILD_LINE}s/$/ -tags $MEM_TYPE/" images/gogits/Dockerfile
cd images/$MEM_TYPE
docker build -t gogits/$MEM_TYPE .
docker run -d --name $MEM_RUN_NAME gogits/$MEM_TYPE
$DOCKER_BIN build -t gogits/$MEM_TYPE .
$DOCKER_BIN run -d --name $MEM_RUN_NAME gogits/$MEM_TYPE
MEM_LINK=" --link $MEM_RUN_NAME:mem "
cd ../../
fi
# Build the database image
cd images/$DB_TYPE
docker build -t gogits/$DB_TYPE .
$DOCKER_BIN build -t gogits/$DB_TYPE .
#
## Build the gogits image
cd ../gogits
docker build -t gogits/gogs .
$DOCKER_BIN build -t gogits/gogs .
#sed -i "s#RUN go get -u -tags $MEM_TYPE github.com/gogits/gogs#RUN go get -u github.com/gogits/gogs#g" Dockerfile
@@ -60,9 +66,9 @@ sed -i "s/ -tags $MEM_TYPE//" Dockerfile
#
## Run MySQL image with name
docker run -d --name $DB_RUN_NAME gogits/$DB_TYPE
$DOCKER_BIN run -d --name $DB_RUN_NAME gogits/$DB_TYPE
#
## Run gogits image and link it to the database image
echo "Now we have the $DB_TYPE image(running) and gogs image, use the follow command to start gogs service:"
echo -e "\033[33m docker run -i -t --link $DB_RUN_NAME:db $MEM_LINK -p $HOST_PORT:3000 gogits/gogs \033[0m"
echo -e "\033[33m $DOCKER_BIN run -i -t --link $DB_RUN_NAME:db $MEM_LINK -p $HOST_PORT:3000 gogits/gogs \033[0m"
+8 -2
View File
@@ -5,9 +5,15 @@ typeset -u MYSQL_ALIAS
MYSQL_ALIAS="db"
HOST_PORT="3000"
DOCKER_BIN=$(which docker.io || which docker)
if [ -z "$DOCKER_BIN" ] ; then
echo "Please install docker. You can install docker by running \"wget -qO- https://get.docker.io/ | sh\"."
exit 1
fi
## Run MySQL image with name
docker run -d --name $MYSQL_RUN_NAME gogs/mysql
$DOCKER_BIN run -d --name $MYSQL_RUN_NAME gogs/mysql
#
## Run gogits image and link it to the MySQL image
docker run --link $MYSQL_RUN_NAME:$MYSQL_ALIAS -p $HOST_PORT:3000 gogs/gogits
$DOCKER_BIN run --link $MYSQL_RUN_NAME:$MYSQL_ALIAS -p $HOST_PORT:3000 gogs/gogits
+3 -3
View File
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.4.1.0601 Alpha"
const APP_VER = "0.4.5.0628 Alpha"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
@@ -31,10 +31,10 @@ func main() {
app.Version = APP_VER
app.Commands = []cli.Command{
cmd.CmdWeb,
// cmd.CmdFix,
cmd.CmdDump,
cmd.CmdServ,
cmd.CmdUpdate,
cmd.CmdFix,
cmd.CmdDump,
}
app.Flags = append(app.Flags, []cli.Flag{}...)
app.Run(os.Args)
+10 -9
View File
@@ -11,10 +11,11 @@ import (
"github.com/go-xorm/xorm"
)
// Access types.
type AccessType int
const (
AU_READABLE = iota + 1
AU_WRITABLE
READABLE AccessType = iota + 1
WRITABLE
)
// Access represents the accessibility of user to repository.
@@ -22,7 +23,7 @@ type Access struct {
Id int64
UserName string `xorm:"unique(s)"`
RepoName string `xorm:"unique(s)"` // <user name>/<repo name>
Mode int `xorm:"unique(s)"`
Mode AccessType `xorm:"unique(s)"`
Created time.Time `xorm:"created"`
}
@@ -30,7 +31,7 @@ type Access struct {
func AddAccess(access *Access) error {
access.UserName = strings.ToLower(access.UserName)
access.RepoName = strings.ToLower(access.RepoName)
_, err := orm.Insert(access)
_, err := x.Insert(access)
return err
}
@@ -38,13 +39,13 @@ func AddAccess(access *Access) error {
func UpdateAccess(access *Access) error {
access.UserName = strings.ToLower(access.UserName)
access.RepoName = strings.ToLower(access.RepoName)
_, err := orm.Id(access.Id).Update(access)
_, err := x.Id(access.Id).Update(access)
return err
}
// DeleteAccess deletes access record.
func DeleteAccess(access *Access) error {
_, err := orm.Delete(access)
_, err := x.Delete(access)
return err
}
@@ -59,7 +60,7 @@ func UpdateAccessWithSession(sess *xorm.Session, access *Access) error {
// HasAccess returns true if someone can read or write to given repository.
// The repoName should be in format <username>/<reponame>.
func HasAccess(uname, repoName string, mode int) (bool, error) {
func HasAccess(uname, repoName string, mode AccessType) (bool, error) {
if len(repoName) == 0 {
return false, nil
}
@@ -67,7 +68,7 @@ func HasAccess(uname, repoName string, mode int) (bool, error) {
UserName: strings.ToLower(uname),
RepoName: strings.ToLower(repoName),
}
has, err := orm.Get(access)
has, err := x.Get(access)
if err != nil {
return false, err
} else if !has {
+22 -17
View File
@@ -12,10 +12,8 @@ import (
"time"
"github.com/gogits/git"
qlog "github.com/qiniu/log"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/hooks"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
@@ -116,7 +114,7 @@ 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)
//qlog.Info("action.CommitRepoAction(end): %d/%s", repoUserId, repoName)
// New push event hook.
if err := repo.GetOwner(); err != nil {
@@ -131,35 +129,35 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
commits := make([]*hooks.PayloadCommit, len(commit.Commits))
commits := make([]*PayloadCommit, len(commit.Commits))
for i, cmt := range commit.Commits {
commits[i] = &hooks.PayloadCommit{
commits[i] = &PayloadCommit{
Id: cmt.Sha1,
Message: cmt.Message,
Url: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1),
Author: &hooks.PayloadAuthor{
Author: &PayloadAuthor{
Name: cmt.AuthorName,
Email: cmt.AuthorEmail,
},
}
}
p := &hooks.Payload{
p := &Payload{
Ref: refFullName,
Commits: commits,
Repo: &hooks.PayloadRepo{
Repo: &PayloadRepo{
Id: repo.Id,
Name: repo.LowerName,
Url: repoLink,
Description: repo.Description,
Website: repo.Website,
Watchers: repo.NumWatches,
Owner: &hooks.PayloadAuthor{
Owner: &PayloadAuthor{
Name: repoUserName,
Email: actEmail,
},
Private: repo.IsPrivate,
},
Pusher: &hooks.PayloadAuthor{
Pusher: &PayloadAuthor{
Name: repo.Owner.LowerName,
Email: repo.Owner.Email,
},
@@ -172,20 +170,27 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
p.Secret = w.Secret
hooks.AddHookTask(&hooks.HookTask{hooks.HTT_WEBHOOK, w.Url, p, w.ContentType, w.IsSsl})
CreateHookTask(&HookTask{
Type: WEBHOOK,
Url: w.Url,
Payload: p,
ContentType: w.ContentType,
IsSsl: w.IsSsl,
})
}
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, IsPrivate: repo.IsPrivate}); err != nil {
log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
func NewRepoAction(u *User, repo *Repository) (err error) {
if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoUserName: repo.Owner.Name, RepoName: repo.Name,
IsPrivate: repo.IsPrivate}); err != nil {
log.Error("action.NewRepoAction(notify watchers): %d/%s", u.Id, repo.Name)
return err
}
log.Trace("action.NewRepoAction: %s/%s", user.LowerName, repo.LowerName)
log.Trace("action.NewRepoAction: %s/%s", u.LowerName, repo.LowerName)
return err
}
@@ -205,7 +210,7 @@ func TransferRepoAction(user, newUser *User, repo *Repository) (err error) {
// GetFeeds returns action list of given user in given context.
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)
sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid)
if isProfile {
sess.Where("is_private=?", false).And("act_user_id=?", userid)
} else {
-6
View File
@@ -1,6 +0,0 @@
package models
func Fix() error {
_, err := orm.Exec("alter table repository drop column num_releases")
return err
}
+6 -7
View File
@@ -6,6 +6,7 @@ package models
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
@@ -15,6 +16,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
)
// Diff line types.
@@ -67,7 +69,7 @@ func (diff *Diff) NumFiles() int {
const DIFF_HEAD = "diff --git "
func ParsePatch(cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
scanner := bufio.NewScanner(reader)
var (
curFile *DiffFile
@@ -169,11 +171,8 @@ func ParsePatch(cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
}
// In case process became zombie.
if !cmd.ProcessState.Exited() {
log.Debug("git_diff.ParsePatch: process doesn't exit and now will be killed")
if err := cmd.Process.Kill(); err != nil {
log.Error("git_diff.ParsePatch: fail to kill zombie process: %v", err)
}
if err := process.Kill(pid); err != nil {
log.Error("git_diff.ParsePatch(Kill): %v", err)
}
return diff, nil
}
@@ -207,5 +206,5 @@ func GetDiff(repoPath, commitid string) (*Diff, error) {
wr.Close()
}()
defer rd.Close()
return ParsePatch(cmd, rd)
return ParsePatch(process.Add(fmt.Sprintf("GetDiff(%s)", repoPath), cmd), cmd, rd)
}
+45 -45
View File
File diff suppressed because it is too large Load Diff
+50 -57
View File
@@ -1,4 +1,4 @@
// Copyright github.com/juju2013. All rights reserved.
// 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.
@@ -20,12 +20,13 @@ import (
"github.com/gogits/gogs/modules/log"
)
// Login types.
type LoginType int
const (
LT_NOTYPE = iota
LT_PLAIN
LT_LDAP
LT_SMTP
NOTYPE LoginType = iota
PLAIN
LDAP
SMTP
)
var (
@@ -34,9 +35,9 @@ var (
ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users")
)
var LoginTypes = map[int]string{
LT_LDAP: "LDAP",
LT_SMTP: "SMTP",
var LoginTypes = map[LoginType]string{
LDAP: "LDAP",
SMTP: "SMTP",
}
// Ensure structs implmented interface.
@@ -49,7 +50,6 @@ type LDAPConfig struct {
ldap.Ldapsource
}
// implement
func (cfg *LDAPConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, &cfg.Ldapsource)
}
@@ -65,7 +65,6 @@ type SMTPConfig struct {
TLS bool
}
// implement
func (cfg *SMTPConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, cfg)
}
@@ -76,13 +75,13 @@ func (cfg *SMTPConfig) ToDB() ([]byte, error) {
type LoginSource struct {
Id int64
Type int
Name string `xorm:"unique"`
IsActived bool `xorm:"not null default false"`
Type LoginType
Name string `xorm:"UNIQUE"`
IsActived bool `xorm:"NOT NULL DEFAULT false"`
Cfg core.Conversion `xorm:"TEXT"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
AllowAutoRegister bool `xorm:"not null default false"`
AllowAutoRegister bool `xorm:"NOT NULL DEFAULT false"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
}
func (source *LoginSource) TypeString() string {
@@ -97,61 +96,59 @@ func (source *LoginSource) SMTP() *SMTPConfig {
return source.Cfg.(*SMTPConfig)
}
// for xorm callback
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
if colName == "type" {
ty := (*val).(int64)
switch ty {
case LT_LDAP:
switch LoginType(ty) {
case LDAP:
source.Cfg = new(LDAPConfig)
case LT_SMTP:
case SMTP:
source.Cfg = new(SMTPConfig)
}
}
}
func CreateSource(source *LoginSource) error {
_, err := x.Insert(source)
return err
}
func GetAuths() ([]*LoginSource, error) {
var auths = make([]*LoginSource, 0)
err := orm.Find(&auths)
var auths = make([]*LoginSource, 0, 5)
err := x.Find(&auths)
return auths, err
}
func GetLoginSourceById(id int64) (*LoginSource, error) {
source := new(LoginSource)
has, err := orm.Id(id).Get(source)
has, err := x.Id(id).Get(source)
if err != nil {
return nil, err
}
if !has {
} else if !has {
return nil, ErrAuthenticationNotExist
}
return source, nil
}
func AddSource(source *LoginSource) error {
_, err := orm.Insert(source)
return err
}
func UpdateSource(source *LoginSource) error {
_, err := orm.Id(source.Id).AllCols().Update(source)
_, err := x.Id(source.Id).AllCols().Update(source)
return err
}
func DelLoginSource(source *LoginSource) error {
cnt, err := orm.Count(&User{LoginSource: source.Id})
cnt, err := x.Count(&User{LoginSource: source.Id})
if err != nil {
return err
}
if cnt > 0 {
return ErrAuthenticationUserUsed
}
_, err = orm.Id(source.Id).Delete(&LoginSource{})
_, err = x.Id(source.Id).Delete(&LoginSource{})
return err
}
// login a user
func LoginUser(uname, passwd string) (*User, error) {
// UserSignIn validates user name and password.
func UserSignIn(uname, passwd string) (*User, error) {
var u *User
if strings.Contains(uname, "@") {
u = &User{Email: uname}
@@ -159,19 +156,19 @@ func LoginUser(uname, passwd string) (*User, error) {
u = &User{LowerName: strings.ToLower(uname)}
}
has, err := orm.Get(u)
has, err := x.Get(u)
if err != nil {
return nil, err
}
if u.LoginType == LT_NOTYPE {
if u.LoginType == NOTYPE {
if has {
u.LoginType = LT_PLAIN
u.LoginType = PLAIN
}
}
// for plain login, user must have existed.
if u.LoginType == LT_PLAIN {
if u.LoginType == PLAIN {
if !has {
return nil, ErrUserNotExist
}
@@ -185,28 +182,26 @@ func LoginUser(uname, passwd string) (*User, error) {
} else {
if !has {
var sources []LoginSource
if err = orm.UseBool().Find(&sources,
if err = x.UseBool().Find(&sources,
&LoginSource{IsActived: true, AllowAutoRegister: true}); err != nil {
return nil, err
}
for _, source := range sources {
if source.Type == LT_LDAP {
if source.Type == LDAP {
u, err := LoginUserLdapSource(nil, uname, passwd,
source.Id, source.Cfg.(*LDAPConfig), true)
if err == nil {
return u, nil
} else {
log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
}
} else if source.Type == LT_SMTP {
log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
} else if source.Type == SMTP {
u, err := LoginUserSMTPSource(nil, uname, passwd,
source.Id, source.Cfg.(*SMTPConfig), true)
if err == nil {
return u, nil
} else {
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
}
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
}
}
@@ -214,7 +209,7 @@ func LoginUser(uname, passwd string) (*User, error) {
}
var source LoginSource
hasSource, err := orm.Id(u.LoginSource).Get(&source)
hasSource, err := x.Id(u.LoginSource).Get(&source)
if err != nil {
return nil, err
} else if !hasSource {
@@ -224,10 +219,10 @@ func LoginUser(uname, passwd string) (*User, error) {
}
switch u.LoginType {
case LT_LDAP:
case LDAP:
return LoginUserLdapSource(u, u.LoginName, passwd,
source.Id, source.Cfg.(*LDAPConfig), false)
case LT_SMTP:
case SMTP:
return LoginUserSMTPSource(u, u.LoginName, passwd,
source.Id, source.Cfg.(*SMTPConfig), false)
}
@@ -252,7 +247,7 @@ func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *L
user = &User{
LowerName: strings.ToLower(name),
Name: strings.ToLower(name),
LoginType: LT_LDAP,
LoginType: LDAP,
LoginSource: sourceId,
LoginName: name,
IsActive: true,
@@ -260,7 +255,7 @@ func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *L
Email: mail,
}
return RegisterUser(user)
return CreateUser(user)
}
type loginAuth struct {
@@ -320,9 +315,8 @@ func SmtpAuth(host string, port int, a smtp.Auth, useTls bool) error {
return err
}
return nil
} else {
return ErrUnsupportedLoginType
}
return ErrUnsupportedLoginType
}
// Query if name/passwd can login against the LDAP direcotry pool
@@ -358,13 +352,12 @@ func LoginUserSMTPSource(user *User, name, passwd string, sourceId int64, cfg *S
user = &User{
LowerName: strings.ToLower(loginName),
Name: strings.ToLower(loginName),
LoginType: LT_SMTP,
LoginType: SMTP,
LoginSource: sourceId,
LoginName: name,
IsActive: true,
Passwd: passwd,
Email: name,
}
return RegisterUser(user)
return CreateUser(user)
}
+27 -26
View File
@@ -18,7 +18,7 @@ import (
)
var (
orm *xorm.Engine
x *xorm.Engine
tables []interface{}
HasEngine bool
@@ -35,7 +35,7 @@ func init() {
tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
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(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser))
}
func LoadModelsConfig() {
@@ -46,7 +46,9 @@ func LoadModelsConfig() {
DbCfg.Host = setting.Cfg.MustValue("database", "HOST")
DbCfg.Name = setting.Cfg.MustValue("database", "NAME")
DbCfg.User = setting.Cfg.MustValue("database", "USER")
if len(DbCfg.Pwd) == 0 {
DbCfg.Pwd = setting.Cfg.MustValue("database", "PASSWD")
}
DbCfg.SslMode = setting.Cfg.MustValue("database", "SSL_MODE")
DbCfg.Path = setting.Cfg.MustValue("database", "PATH", "data/gogs.db")
}
@@ -67,7 +69,6 @@ func NewTestEngine(x *xorm.Engine) (err error) {
}
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)
//fmt.Println(cnnstr)
x, err = xorm.NewEngine("postgres", cnnstr)
case "sqlite3":
if !EnableSQLite3 {
@@ -87,7 +88,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
func SetEngine() (err error) {
switch DbCfg.Type {
case "mysql":
orm, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
x, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name))
case "postgres":
var host, port = "127.0.0.1", "5432"
@@ -98,11 +99,11 @@ func SetEngine() (err error) {
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",
x, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode))
case "sqlite3":
os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
orm, err = xorm.NewEngine("sqlite3", DbCfg.Path)
x, err = xorm.NewEngine("sqlite3", DbCfg.Path)
default:
return fmt.Errorf("Unknown database type: %s", DbCfg.Type)
}
@@ -119,11 +120,11 @@ func SetEngine() (err error) {
if err != nil {
return fmt.Errorf("models.init(fail to create xorm.log): %v", err)
}
orm.Logger = xorm.NewSimpleLogger(f)
x.Logger = xorm.NewSimpleLogger(f)
orm.ShowSQL = true
orm.ShowDebug = true
orm.ShowErr = true
x.ShowSQL = true
x.ShowDebug = true
x.ShowErr = true
return nil
}
@@ -131,7 +132,7 @@ func NewEngine() (err error) {
if err = SetEngine(); err != nil {
return err
}
if err = orm.Sync(tables...); err != nil {
if err = x.Sync2(tables...); err != nil {
return fmt.Errorf("sync database struct error: %v\n", err)
}
return nil
@@ -146,24 +147,24 @@ type Statistic struct {
}
func GetStatistic() (stats Statistic) {
stats.Counter.User, _ = orm.Count(new(User))
stats.Counter.PublicKey, _ = orm.Count(new(PublicKey))
stats.Counter.Repo, _ = orm.Count(new(Repository))
stats.Counter.Watch, _ = orm.Count(new(Watch))
stats.Counter.Action, _ = orm.Count(new(Action))
stats.Counter.Access, _ = orm.Count(new(Access))
stats.Counter.Issue, _ = orm.Count(new(Issue))
stats.Counter.Comment, _ = orm.Count(new(Comment))
stats.Counter.Mirror, _ = orm.Count(new(Mirror))
stats.Counter.Oauth, _ = orm.Count(new(Oauth2))
stats.Counter.Release, _ = orm.Count(new(Release))
stats.Counter.LoginSource, _ = orm.Count(new(LoginSource))
stats.Counter.Webhook, _ = orm.Count(new(Webhook))
stats.Counter.Milestone, _ = orm.Count(new(Milestone))
stats.Counter.User, _ = x.Count(new(User))
stats.Counter.PublicKey, _ = x.Count(new(PublicKey))
stats.Counter.Repo, _ = x.Count(new(Repository))
stats.Counter.Watch, _ = x.Count(new(Watch))
stats.Counter.Action, _ = x.Count(new(Action))
stats.Counter.Access, _ = x.Count(new(Access))
stats.Counter.Issue, _ = x.Count(new(Issue))
stats.Counter.Comment, _ = x.Count(new(Comment))
stats.Counter.Mirror, _ = x.Count(new(Mirror))
stats.Counter.Oauth, _ = x.Count(new(Oauth2))
stats.Counter.Release, _ = x.Count(new(Release))
stats.Counter.LoginSource, _ = x.Count(new(LoginSource))
stats.Counter.Webhook, _ = x.Count(new(Webhook))
stats.Counter.Milestone, _ = x.Count(new(Milestone))
return
}
// DumpDatabase dumps all data from database to file system.
func DumpDatabase(filePath string) error {
return orm.DumpAllToFile(filePath)
return x.DumpAllToFile(filePath)
}
+16 -16
View File
@@ -8,16 +8,16 @@ import (
"errors"
)
// OT: Oauth2 Type
type OauthType int
const (
OT_GITHUB = iota + 1
OT_GOOGLE
OT_TWITTER
OT_QQ
OT_WEIBO
OT_BITBUCKET
OT_OSCHINA
OT_FACEBOOK
GITHUB OauthType = iota + 1
GOOGLE
TWITTER
QQ
WEIBO
BITBUCKET
FACEBOOK
)
var (
@@ -35,18 +35,18 @@ type Oauth2 struct {
}
func BindUserOauth2(userId, oauthId int64) error {
_, err := orm.Id(oauthId).Update(&Oauth2{Uid: userId})
_, err := x.Id(oauthId).Update(&Oauth2{Uid: userId})
return err
}
func AddOauth2(oa *Oauth2) error {
_, err := orm.Insert(oa)
_, err := x.Insert(oa)
return err
}
func GetOauth2(identity string) (oa *Oauth2, err error) {
oa = &Oauth2{Identity: identity}
isExist, err := orm.Get(oa)
isExist, err := x.Get(oa)
if err != nil {
return
} else if !isExist {
@@ -60,7 +60,7 @@ func GetOauth2(identity string) (oa *Oauth2, err error) {
func GetOauth2ById(id int64) (oa *Oauth2, err error) {
oa = new(Oauth2)
has, err := orm.Id(id).Get(oa)
has, err := x.Id(id).Get(oa)
if err != nil {
return nil, err
} else if !has {
@@ -71,18 +71,18 @@ func GetOauth2ById(id int64) (oa *Oauth2, err error) {
// GetOauthByUserId returns list of oauthes that are releated to given user.
func GetOauthByUserId(uid int64) (oas []*Oauth2, err error) {
err = orm.Find(&oas, Oauth2{Uid: uid})
err = x.Find(&oas, Oauth2{Uid: uid})
return oas, err
}
// DeleteOauth2ById deletes a oauth2 by ID.
func DeleteOauth2ById(id int64) error {
_, err := orm.Delete(&Oauth2{Id: id})
_, err := x.Delete(&Oauth2{Id: id})
return err
}
// CleanUnbindOauth deletes all unbind OAuthes.
func CleanUnbindOauth() error {
_, err := orm.Delete(&Oauth2{Uid: -1})
_, err := x.Delete(&Oauth2{Uid: -1})
return err
}
+236
View File
@@ -0,0 +1,236 @@
// 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 (
"strings"
"github.com/gogits/gogs/modules/base"
)
// GetOwnerTeam returns owner team of organization.
func (org *User) GetOwnerTeam() (*Team, error) {
t := &Team{
OrgId: org.Id,
Name: OWNER_TEAM,
}
_, err := x.Get(t)
return t, err
}
// CreateOrganization creates record of a new organization.
func CreateOrganization(org, owner *User) (*User, error) {
if !IsLegalName(org.Name) {
return nil, ErrUserNameIllegal
}
isExist, err := IsUserExist(org.Name)
if err != nil {
return nil, err
} else if isExist {
return nil, ErrUserAlreadyExist
}
isExist, err = IsEmailUsed(org.Email)
if err != nil {
return nil, err
} else if isExist {
return nil, ErrEmailAlreadyUsed
}
org.LowerName = strings.ToLower(org.Name)
org.FullName = org.Name
org.Avatar = base.EncodeMd5(org.Email)
org.AvatarEmail = org.Email
// No password for organization.
org.NumTeams = 1
org.NumMembers = 1
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return nil, err
}
if _, err = sess.Insert(org); err != nil {
sess.Rollback()
return nil, err
}
// Create default owner team.
t := &Team{
OrgId: org.Id,
Name: OWNER_TEAM,
Authorize: ORG_ADMIN,
NumMembers: 1,
}
if _, err = sess.Insert(t); err != nil {
sess.Rollback()
return nil, err
}
// Add initial creator to organization and owner team.
ou := &OrgUser{
Uid: owner.Id,
OrgId: org.Id,
IsOwner: true,
NumTeam: 1,
}
if _, err = sess.Insert(ou); err != nil {
sess.Rollback()
return nil, err
}
tu := &TeamUser{
Uid: owner.Id,
OrgId: org.Id,
TeamId: t.Id,
}
if _, err = sess.Insert(tu); err != nil {
sess.Rollback()
return nil, err
}
return org, sess.Commit()
}
// TODO: need some kind of mechanism to record failure.
// DeleteOrganization completely and permanently deletes everything of organization.
func DeleteOrganization(org *User) (err error) {
if err := DeleteUser(org); err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Delete(&Team{OrgId: org.Id}); err != nil {
sess.Rollback()
return err
}
if _, err = sess.Delete(&OrgUser{OrgId: org.Id}); err != nil {
sess.Rollback()
return err
}
if _, err = sess.Delete(&TeamUser{OrgId: org.Id}); err != nil {
sess.Rollback()
return err
}
return sess.Commit()
}
type AuthorizeType int
const (
ORG_READABLE AuthorizeType = iota + 1
ORG_WRITABLE
ORG_ADMIN
)
const OWNER_TEAM = "Owner"
// Team represents a organization team.
type Team struct {
Id int64
OrgId int64 `xorm:"INDEX"`
Name string
Description string
Authorize AuthorizeType
RepoIds string `xorm:"TEXT"`
NumMembers int
NumRepos int
}
// NewTeam creates a record of new team.
func NewTeam(t *Team) error {
_, err := x.Insert(t)
return err
}
func UpdateTeam(t *Team) error {
if len(t.Description) > 255 {
t.Description = t.Description[:255]
}
_, err := x.Id(t.Id).AllCols().Update(t)
return err
}
// ________ ____ ___
// \_____ \_______ ____ | | \______ ___________
// / | \_ __ \/ ___\| | / ___// __ \_ __ \
// / | \ | \/ /_/ > | /\___ \\ ___/| | \/
// \_______ /__| \___ /|______//____ >\___ >__|
// \/ /_____/ \/ \/
// OrgUser represents an organization-user relation.
type OrgUser struct {
Id int64
Uid int64 `xorm:"INDEX"`
OrgId int64 `xorm:"INDEX"`
IsPublic bool
IsOwner bool
NumTeam int
}
// GetOrgUsersByUserId returns all organization-user relations by user ID.
func GetOrgUsersByUserId(uid int64) ([]*OrgUser, error) {
ous := make([]*OrgUser, 0, 10)
err := x.Where("uid=?", uid).Find(&ous)
return ous, err
}
// GetOrgUsersByOrgId returns all organization-user relations by organization ID.
func GetOrgUsersByOrgId(orgId int64) ([]*OrgUser, error) {
ous := make([]*OrgUser, 0, 10)
err := x.Where("org_id=?", orgId).Find(&ous)
return ous, err
}
func GetOrganizationCount(u *User) (int64, error) {
return x.Where("uid=?", u.Id).Count(new(OrgUser))
}
// IsOrganizationOwner returns true if given user ID is in the owner team.
func IsOrganizationOwner(orgId, uid int64) bool {
has, _ := x.Where("is_owner=?", true).Get(&OrgUser{Uid: uid, OrgId: orgId})
return has
}
// ___________ ____ ___
// \__ ___/___ _____ _____ | | \______ ___________
// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \
// | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/
// |____| \___ >____ /__|_| /______//____ >\___ >__|
// \/ \/ \/ \/ \/
// TeamUser represents an team-user relation.
type TeamUser struct {
Id int64
Uid int64
OrgId int64 `xorm:"INDEX"`
TeamId int64
}
// 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
}
+18 -18
View File
@@ -19,9 +19,9 @@ import (
"time"
"github.com/Unknwon/com"
qlog "github.com/qiniu/log"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
)
const (
@@ -37,7 +37,7 @@ var (
var sshOpLocker = sync.Mutex{}
var (
sshPath string // SSH directory.
SshPath string // SSH directory.
appPath string // Execution(binary) path.
)
@@ -54,7 +54,7 @@ func exePath() (string, error) {
func homeDir() string {
home, err := com.HomeDir()
if err != nil {
qlog.Fatalln(err)
log.Fatal("Fail to get home directory: %v", err)
}
return home
}
@@ -63,13 +63,13 @@ func init() {
var err error
if appPath, err = exePath(); err != nil {
qlog.Fatalf("publickey.init(fail to get app path): %v\n", err)
log.Fatal("publickey.init(fail to get app path): %v\n", err)
}
// Determine and create .ssh path.
sshPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(sshPath, os.ModePerm); err != nil {
qlog.Fatalf("publickey.init(fail to create sshPath(%s)): %v\n", sshPath, err)
SshPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(SshPath, os.ModePerm); err != nil {
log.Fatal("publickey.init(fail to create SshPath(%s)): %v\n", SshPath, err)
}
}
@@ -94,7 +94,7 @@ func saveAuthorizedKeyFile(key *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
@@ -107,7 +107,7 @@ func saveAuthorizedKeyFile(key *PublicKey) error {
// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(key *PublicKey) (err error) {
has, err := orm.Get(key)
has, err := x.Get(key)
if err != nil {
return err
} else if has {
@@ -121,7 +121,7 @@ func AddPublicKey(key *PublicKey) (err error) {
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
return err
}
stdout, stderr, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath)
if err != nil {
return errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
@@ -130,11 +130,11 @@ func AddPublicKey(key *PublicKey) (err error) {
key.Fingerprint = strings.Split(stdout, " ")[1]
// Save SSH key.
if _, err = orm.Insert(key); err != nil {
if _, err = x.Insert(key); err != nil {
return err
} else if err = saveAuthorizedKeyFile(key); err != nil {
// Roll back.
if _, err2 := orm.Delete(key); err2 != nil {
if _, err2 := x.Delete(key); err2 != nil {
return err2
}
return err
@@ -146,7 +146,7 @@ func AddPublicKey(key *PublicKey) (err error) {
// ListPublicKey returns a list of all public keys that user has.
func ListPublicKey(uid int64) ([]PublicKey, error) {
keys := make([]PublicKey, 0, 5)
err := orm.Find(&keys, &PublicKey{OwnerId: uid})
err := x.Find(&keys, &PublicKey{OwnerId: uid})
return keys, err
}
@@ -161,7 +161,7 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
}
defer fr.Close()
fw, err := os.Create(tmpP)
fw, err := os.OpenFile(tmpP, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
}
@@ -205,19 +205,19 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
func DeletePublicKey(key *PublicKey) error {
has, err := orm.Get(key)
has, err := x.Get(key)
if err != nil {
return err
} else if !has {
return ErrKeyNotExist
}
if _, err = orm.Delete(key); err != nil {
if _, err = x.Delete(key); err != nil {
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")
log.Trace("publickey.DeletePublicKey(authorized_keys): %s", fpath)
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
+85 -22
View File
@@ -6,15 +6,16 @@ package models
import (
"errors"
"sort"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/gogits/git"
)
var (
ErrReleaseAlreadyExist = errors.New("Release already exist")
ErrReleaseNotExist = errors.New("Release does not exist")
)
// Release represents a release of repository.
@@ -23,21 +24,17 @@ type Release struct {
RepoId int64
PublisherId int64
Publisher *User `xorm:"-"`
Title string
TagName string
LowerTagName string
SHA1 string
Target string
Title string
Sha1 string `xorm:"VARCHAR(40)"`
NumCommits int
NumCommitsBehind int `xorm:"-"`
Note string `xorm:"TEXT"`
IsDraft bool `xorm:"NOT NULL DEFAULT false"`
IsPrerelease bool
Created time.Time `xorm:"created"`
}
// GetReleasesByRepoId returns a list of releases of repository.
func GetReleasesByRepoId(repoId int64) (rels []*Release, err error) {
err = orm.Desc("created").Find(&rels, Release{RepoId: repoId})
return rels, err
Created time.Time `xorm:"CREATED"`
}
// IsReleaseExist returns true if release with given tag name already exists.
@@ -46,24 +43,20 @@ func IsReleaseExist(repoId int64, tagName string) (bool, error) {
return false, nil
}
return orm.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)})
return x.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)})
}
// CreateRelease creates a new release of repository.
func CreateRelease(gitRepo *git.Repository, rel *Release) error {
isExist, err := IsReleaseExist(rel.RepoId, rel.TagName)
func createTag(gitRepo *git.Repository, rel *Release) error {
// Only actual create when publish.
if !rel.IsDraft {
if !gitRepo.IsTagExist(rel.TagName) {
commit, err := gitRepo.GetCommitOfBranch(rel.Target)
if err != nil {
return err
} else if isExist {
return ErrReleaseAlreadyExist
}
if !gitRepo.IsTagExist(rel.TagName) {
_, stderr, err := com.ExecCmdDir(gitRepo.Path, "git", "tag", rel.TagName, "-m", rel.Title)
if err != nil {
if err = gitRepo.CreateTag(rel.TagName, commit.Id.String()); err != nil {
return err
} else if strings.Contains(stderr, "fatal:") {
return errors.New(stderr)
}
} else {
commit, err := gitRepo.GetCommitOfTag(rel.TagName)
@@ -76,8 +69,78 @@ func CreateRelease(gitRepo *git.Repository, rel *Release) error {
return err
}
}
}
return nil
}
// CreateRelease creates a new release of repository.
func CreateRelease(gitRepo *git.Repository, rel *Release) error {
isExist, err := IsReleaseExist(rel.RepoId, rel.TagName)
if err != nil {
return err
} else if isExist {
return ErrReleaseAlreadyExist
}
if err = createTag(gitRepo, rel); err != nil {
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)
_, err = orm.InsertOne(rel)
_, err = x.InsertOne(rel)
return err
}
// GetRelease returns release by given ID.
func GetRelease(repoId int64, tagName string) (*Release, error) {
isExist, err := IsReleaseExist(repoId, tagName)
if err != nil {
return nil, err
} else if !isExist {
return nil, ErrReleaseNotExist
}
rel := &Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)}
_, err = x.Get(rel)
return rel, err
}
// GetReleasesByRepoId returns a list of releases of repository.
func GetReleasesByRepoId(repoId int64) (rels []*Release, err error) {
err = x.Desc("created").Find(&rels, Release{RepoId: repoId})
return rels, err
}
type ReleaseSorter struct {
rels []*Release
}
func (rs *ReleaseSorter) Len() int {
return len(rs.rels)
}
func (rs *ReleaseSorter) Less(i, j int) bool {
diffNum := rs.rels[i].NumCommits - rs.rels[j].NumCommits
if diffNum != 0 {
return diffNum > 0
}
return rs.rels[i].Created.After(rs.rels[j].Created)
}
func (rs *ReleaseSorter) Swap(i, j int) {
rs.rels[i], rs.rels[j] = rs.rels[j], rs.rels[i]
}
// SortReleases sorts releases by number of commits and created time.
func SortReleases(rels []*Release) {
sorter := &ReleaseSorter{rels: rels}
sort.Sort(sorter)
}
// UpdateRelease updates information of a release.
func UpdateRelease(gitRepo *git.Repository, rel *Release) (err error) {
if err = createTag(gitRepo, rel); err != nil {
return err
}
_, err = x.Id(rel.Id).AllCols().Update(rel)
return err
}
+289 -215
View File
File diff suppressed because it is too large Load Diff
+15 -16
View File
@@ -6,21 +6,21 @@ package models
import (
"container/list"
"fmt"
"os/exec"
"strings"
qlog "github.com/qiniu/log"
"github.com/gogits/git"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
)
func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) {
func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) error {
isNew := strings.HasPrefix(oldCommitId, "0000000")
if isNew &&
strings.HasPrefix(newCommitId, "0000000") {
qlog.Fatal("old rev and new rev both 000000")
return fmt.Errorf("old rev and new rev both 000000")
}
f := RepoPath(repoUserName, repoName)
@@ -31,19 +31,18 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
isDel := strings.HasPrefix(newCommitId, "0000000")
if isDel {
qlog.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId)
return
log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId)
return nil
}
repo, err := git.OpenRepository(f)
if err != nil {
qlog.Fatalf("runUpdate.Open repoId: %v", err)
return fmt.Errorf("runUpdate.Open repoId: %v", err)
}
newCommit, err := repo.GetCommit(newCommitId)
if err != nil {
qlog.Fatalf("runUpdate GetCommit of newCommitId: %v", err)
return
return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err)
}
var l *list.List
@@ -51,28 +50,27 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
if isNew {
l, err = newCommit.CommitsBefore()
if err != nil {
qlog.Fatalf("Find CommitsBefore erro: %v", err)
return fmt.Errorf("Find CommitsBefore erro: %v", err)
}
} else {
l, err = newCommit.CommitsBeforeUntil(oldCommitId)
if err != nil {
qlog.Fatalf("Find CommitsBeforeUntil erro: %v", err)
return
return fmt.Errorf("Find CommitsBeforeUntil erro: %v", err)
}
}
if err != nil {
qlog.Fatalf("runUpdate.Commit repoId: %v", err)
return fmt.Errorf("runUpdate.Commit repoId: %v", err)
}
ru, err := GetUserByName(repoUserName)
if err != nil {
qlog.Fatalf("runUpdate.GetUserByName: %v", err)
return fmt.Errorf("runUpdate.GetUserByName: %v", err)
}
repos, err := GetRepositoryByName(ru.Id, repoName)
if err != nil {
qlog.Fatalf("runUpdate.GetRepositoryByName userId: %v", err)
return fmt.Errorf("runUpdate.GetRepositoryByName userId: %v", err)
}
commits := make([]*base.PushCommit, 0)
@@ -96,6 +94,7 @@ 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}); err != nil {
qlog.Fatalf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
}
return nil
}
+135 -88
View File
File diff suppressed because it is too large Load Diff
+126 -17
View File
@@ -7,29 +7,35 @@ package models
import (
"encoding/json"
"errors"
"time"
"github.com/gogits/gogs/modules/httplib"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
var (
ErrWebhookNotExist = errors.New("Webhook does not exist")
)
// Content types.
type HookContentType int
const (
CT_JSON = iota + 1
CT_FORM
JSON HookContentType = iota + 1
FORM
)
// HookEvent represents events that will delivery hook.
type HookEvent struct {
PushOnly bool `json:"push_only"`
}
// Webhook represents a web hook object.
type Webhook struct {
Id int64
RepoId int64
Url string `xorm:"TEXT"`
ContentType int
ContentType HookContentType
Secret string `xorm:"TEXT"`
Events string `xorm:"TEXT"`
*HookEvent `xorm:"-"`
@@ -37,6 +43,7 @@ type Webhook struct {
IsActive bool
}
// GetEvent handles conversion from Events to HookEvent.
func (w *Webhook) GetEvent() {
w.HookEvent = &HookEvent{}
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
@@ -44,12 +51,14 @@ func (w *Webhook) GetEvent() {
}
}
func (w *Webhook) SaveEvent() error {
// UpdateEvent handles conversion from HookEvent to Events.
func (w *Webhook) UpdateEvent() error {
data, err := json.Marshal(w.HookEvent)
w.Events = string(data)
return err
}
// HasPushEvent returns true if hook enbaled push event.
func (w *Webhook) HasPushEvent() bool {
if w.PushOnly {
return true
@@ -57,22 +66,16 @@ func (w *Webhook) HasPushEvent() bool {
return false
}
// CreateWebhook creates new webhook.
// CreateWebhook creates a new web hook.
func CreateWebhook(w *Webhook) error {
_, err := orm.Insert(w)
return err
}
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
_, err := orm.AllCols().Update(w)
_, err := x.Insert(w)
return err
}
// GetWebhookById returns webhook by given ID.
func GetWebhookById(hookId int64) (*Webhook, error) {
w := &Webhook{Id: hookId}
has, err := orm.Get(w)
has, err := x.Get(w)
if err != nil {
return nil, err
} else if !has {
@@ -83,18 +86,124 @@ func GetWebhookById(hookId int64) (*Webhook, error) {
// GetActiveWebhooksByRepoId returns all active webhooks of repository.
func GetActiveWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
err = orm.Find(&ws, &Webhook{RepoId: repoId, IsActive: true})
err = x.Find(&ws, &Webhook{RepoId: repoId, IsActive: true})
return ws, err
}
// GetWebhooksByRepoId returns all webhooks of repository.
func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
err = orm.Find(&ws, &Webhook{RepoId: repoId})
err = x.Find(&ws, &Webhook{RepoId: repoId})
return ws, err
}
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
_, err := x.AllCols().Update(w)
return err
}
// DeleteWebhook deletes webhook of repository.
func DeleteWebhook(hookId int64) error {
_, err := orm.Delete(&Webhook{Id: hookId})
_, err := x.Delete(&Webhook{Id: hookId})
return err
}
// ___ ___ __ ___________ __
// / | \ ____ ____ | | _\__ ___/____ _____| | __
// / ~ \/ _ \ / _ \| |/ / | | \__ \ / ___/ |/ /
// \ Y ( <_> | <_> ) < | | / __ \_\___ \| <
// \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
// \/ \/ \/ \/ \/
type HookTaskType int
const (
WEBHOOK HookTaskType = iota + 1
SERVICE
)
type PayloadAuthor struct {
Name string `json:"name"`
Email string `json:"email"`
}
type PayloadCommit struct {
Id string `json:"id"`
Message string `json:"message"`
Url string `json:"url"`
Author *PayloadAuthor `json:"author"`
}
type PayloadRepo struct {
Id int64 `json:"id"`
Name string `json:"name"`
Url string `json:"url"`
Description string `json:"description"`
Website string `json:"website"`
Watchers int `json:"watchers"`
Owner *PayloadAuthor `json:"author"`
Private bool `json:"private"`
}
// Payload represents a payload information of hook.
type Payload struct {
Secret string `json:"secret"`
Ref string `json:"ref"`
Commits []*PayloadCommit `json:"commits"`
Repo *PayloadRepo `json:"repository"`
Pusher *PayloadAuthor `json:"pusher"`
}
// HookTask represents a hook task.
type HookTask struct {
Id int64
Type HookTaskType
Url string
*Payload `xorm:"-"`
PayloadContent string `xorm:"TEXT"`
ContentType HookContentType
IsSsl bool
IsDeliveried bool
}
// CreateHookTask creates a new hook task,
// it handles conversion from Payload to PayloadContent.
func CreateHookTask(t *HookTask) error {
data, err := json.Marshal(t.Payload)
if err != nil {
return err
}
t.PayloadContent = string(data)
_, err = x.Insert(t)
return err
}
// UpdateHookTask updates information of hook task.
func UpdateHookTask(t *HookTask) error {
_, err := x.AllCols().Update(t)
return err
}
// DeliverHooks checks and delivers undelivered hooks.
func DeliverHooks() {
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
x.Where("is_deliveried=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
// Only support JSON now.
if _, err := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Body([]byte(t.PayloadContent)).Response(); err != nil {
log.Error("webhook.DeliverHooks(Delivery): %v", err)
return nil
}
t.IsDeliveried = true
if err := UpdateHookTask(t); err != nil {
log.Error("webhook.DeliverHooks(UpdateHookTask): %v", err)
return nil
}
log.Trace("Hook delivered: %s", t.PayloadContent)
return nil
})
}
+57
View File
@@ -0,0 +1,57 @@
// 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 auth
import (
"net/http"
"reflect"
"github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/middleware/binding"
)
type CreateOrgForm struct {
OrgName string `form:"orgname" binding:"Required;AlphaDashDot;MaxSize(30)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
}
func (f *CreateOrgForm) Name(field string) string {
names := map[string]string{
"OrgName": "Organization name",
"Email": "E-mail address",
}
return names[field]
}
func (f *CreateOrgForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
validate(errs, data, f)
}
type OrgSettingForm struct {
DisplayName string `form:"display_name" binding:"Required;MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Website string `form:"site" binding:"Url;MaxSize(100)"`
Location string `form:"location" binding:"MaxSize(50)"`
}
func (f *OrgSettingForm) Name(field string) string {
names := map[string]string{
"DisplayName": "Display name",
"Email": "E-mail address",
"Description": "Description",
"Website": "Website address",
"Location": "Location",
}
return names[field]
}
func (f *OrgSettingForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
validate(errors, data, f)
}
+30 -3
View File
@@ -22,9 +22,10 @@ import (
// \/ \/|__| \/ \/
type CreateRepoForm struct {
Uid int64 `form:"uid" binding:"Required"`
RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(100)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Language string `form:"language"`
License string `form:"license"`
InitReadme bool `form:"initReadme"`
@@ -47,10 +48,11 @@ type MigrateRepoForm struct {
Url string `form:"url" binding:"Url"`
AuthUserName string `form:"auth_username"`
AuthPasswd string `form:"auth_password"`
Uid int64 `form:"uid" binding:"Required"`
RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
Mirror bool `form:"mirror"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(100)"`
Description string `form:"desc" binding:"MaxSize(255)"`
}
func (f *MigrateRepoForm) Name(field string) string {
@@ -69,7 +71,7 @@ func (f *MigrateRepoForm) Validate(errors *binding.Errors, req *http.Request, co
type RepoSettingForm struct {
RepoName string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"`
Description string `form:"desc" binding:"MaxSize(100)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Website string `form:"site" binding:"Url;MaxSize(100)"`
Branch string `form:"branch"`
Interval int `form:"interval"`
@@ -205,14 +207,17 @@ func (f *CreateLabelForm) Validate(errors *binding.Errors, req *http.Request, co
type NewReleaseForm struct {
TagName string `form:"tag_name" binding:"Required"`
Target string `form:"tag_target" binding:"Required"`
Title string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Draft string `form:"draft"`
Prerelease bool `form:"prerelease"`
}
func (f *NewReleaseForm) Name(field string) string {
names := map[string]string{
"TagName": "Tag name",
"Target": "Target",
"Title": "Release title",
"Content": "Release content",
}
@@ -223,3 +228,25 @@ func (f *NewReleaseForm) Validate(errors *binding.Errors, req *http.Request, con
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
validate(errors, data, f)
}
type EditReleaseForm struct {
Target string `form:"tag_target" binding:"Required"`
Title string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Draft string `form:"draft"`
Prerelease bool `form:"prerelease"`
}
func (f *EditReleaseForm) Name(field string) string {
names := map[string]string{
"Target": "Target",
"Title": "Release title",
"Content": "Release content",
}
return names[field]
}
func (f *EditReleaseForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
validate(errors, data, f)
}
+33 -27
View File
@@ -16,57 +16,63 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding"
"github.com/gogits/gogs/modules/setting"
)
// SignedInId returns the id of signed in user.
func SignedInId(session session.SessionStore) int64 {
func SignedInId(header http.Header, sess session.SessionStore) int64 {
if !models.HasEngine {
return 0
}
userId := session.Get("userId")
if userId == nil {
return 0
}
if s, ok := userId.(int64); ok {
if _, err := models.GetUserById(s); err != nil {
return 0
}
return s
if setting.Service.EnableReverseProxyAuth {
webAuthUser := header.Get(setting.ReverseProxyAuthUser)
if len(webAuthUser) > 0 {
u, err := models.GetUserByName(webAuthUser)
if err != nil {
if err != models.ErrUserNotExist {
log.Error("auth.user.SignedInId(GetUserByName): %v", err)
}
return 0
}
}
return u.Id
}
}
// SignedInName returns the name of signed in user.
func SignedInName(session session.SessionStore) string {
userName := session.Get("userName")
if userName == nil {
return ""
uid := sess.Get("userId")
if uid == nil {
return 0
}
if s, ok := userName.(string); ok {
return s
if id, ok := uid.(int64); ok {
if _, err := models.GetUserById(id); err != nil {
if err != models.ErrUserNotExist {
log.Error("auth.user.SignedInId(GetUserById): %v", err)
}
return ""
return 0
}
return id
}
return 0
}
// SignedInUser returns the user object of signed user.
func SignedInUser(session session.SessionStore) *models.User {
id := SignedInId(session)
if id <= 0 {
func SignedInUser(header http.Header, sess session.SessionStore) *models.User {
uid := SignedInId(header, sess)
if uid <= 0 {
return nil
}
user, err := models.GetUserById(id)
u, err := models.GetUserById(uid)
if err != nil {
log.Error("user.SignedInUser: %v", err)
return nil
}
return user
return u
}
// IsSignedIn check if any user has signed in.
func IsSignedIn(session session.SessionStore) bool {
return SignedInId(session) > 0
func IsSignedIn(header http.Header, sess session.SessionStore) bool {
return SignedInId(header, sess) > 0
}
type FeedsForm struct {
@@ -87,7 +93,7 @@ func (f *UpdateProfileForm) Name(field string) string {
names := map[string]string{
"UserName": "Username",
"Email": "E-mail address",
"Website": "Website",
"Website": "Website address",
"Location": "Location",
"Avatar": "Gravatar Email",
}
+1
View File
@@ -7,6 +7,7 @@ package base
type (
// Type TmplData represents data in the templates.
TmplData map[string]interface{}
TplName string
ApiJsonErr struct {
Message string `json:"message"`

Some files were not shown because too many files have changed in this diff Show More