diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2014-02-19 17:50:53 +0800 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2014-02-19 17:50:53 +0800 |
commit | be0ba9ea88aff8a658d0495d36accf944b74888d (patch) | |
tree | ff0b9b7eea8cd0d702a1a1ec1d9050110a5dab0e /serve.go | |
parent | 94311e187f07b4ee2344db03279f39f200b4d39c (diff) | |
download | gitea-be0ba9ea88aff8a658d0495d36accf944b74888d.tar.gz gitea-be0ba9ea88aff8a658d0495d36accf944b74888d.zip |
add ssh supports(unfinished)
Diffstat (limited to 'serve.go')
-rw-r--r-- | serve.go | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/serve.go b/serve.go new file mode 100644 index 0000000000..066faa30ec --- /dev/null +++ b/serve.go @@ -0,0 +1,164 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + + "github.com/codegangsta/cli" + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/utils/log" +) + +var ( + COMMANDS_READONLY = map[string]int{ + "git-upload-pack": models.AU_WRITABLE, + "git upload-pack": models.AU_WRITABLE, + } + + COMMANDS_WRITE = map[string]int{ + "git-receive-pack": models.AU_READABLE, + "git receive-pack": models.AU_READABLE, + } +) + +var CmdServ = cli.Command{ + Name: "serv", + Usage: "just run", + Description: ` +gogs serv`, + Action: runServ, + Flags: []cli.Flag{ + //cli.BoolFlag{"update, u", "update pakcage(s) and dependencies if any"}, + //cli.BoolFlag{"verbose, v", "show process details"}, + }, +} + +func In(b string, sl map[string]int) bool { + _, e := sl[b] + return e +} + +func runServ(*cli.Context) { + keys := strings.Split(os.Args[2], "-") + if len(keys) != 2 { + fmt.Println("auth file format error") + return + } + + keyId, err := strconv.ParseInt(keys[1], 10, 64) + if err != nil { + fmt.Println("auth file format error") + return + } + user, err := models.GetUserByKeyId(keyId) + if err != nil { + fmt.Println("You have no right to access") + return + } + + cmd := os.Getenv("SSH_ORIGINAL_COMMAND") + if cmd == "" { + fmt.Printf("Hi %s! You've successfully authenticated, but Gogits does not provide shell access.\n", user.Name) + return + } + + f, _ := os.Create("test2.log") + f.WriteString(cmd) + f.Close() + + log.Info("cmd is %s", cmd) + + verb, args := parseCmd(cmd) + rr := strings.SplitN(strings.Trim(args, "'"), "/", 1) + if len(rr) != 2 { + fmt.Printf("Unavilable repository") + return + } + repoName := rr[1] + if strings.HasSuffix(repoName, ".git") { + repoName = repoName[:len(repoName)-4] + } + isWrite := In(verb, COMMANDS_WRITE) + isRead := In(verb, COMMANDS_READONLY) + switch { + case isWrite: + has, err := models.HasAccess(user.Name, repoName, COMMANDS_WRITE[verb]) + if err != nil { + fmt.Println("Inernel error") + return + } + if !has { + fmt.Println("You have no right to access this repository") + return + } + case isRead: + has, err := models.HasAccess(user.Name, repoName, COMMANDS_READONLY[verb]) + if err != nil { + fmt.Println("Inernel error") + return + } + if !has { + has, err = models.HasAccess(user.Name, repoName, COMMANDS_WRITE[verb]) + if err != nil { + fmt.Println("Inernel error") + return + } + } + if !has { + fmt.Println("You have no right to access this repository") + return + } + default: + fmt.Println("Unknown command") + return + } + + isExist, err := models.IsRepositoryExist(user, repoName) + if err != nil { + fmt.Println("Inernel error") + return + } + + if !isExist { + if isRead { + fmt.Println("Repository is not exist") + return + } else if isWrite { + _, err := models.CreateRepository(user, repoName) + if err != nil { + fmt.Println("Create repository failed") + return + } + } + } + + fullPath := filepath.Join(models.RepoRootPath, user.Name, repoName+".git") + newcmd := fmt.Sprintf("%s '%s'", verb, fullPath) + fmt.Println(newcmd) + gitcmd := exec.Command("git", "shell", "-c", newcmd) + gitcmd.Stdout = os.Stdout + gitcmd.Stderr = os.Stderr + + err = gitcmd.Run() + if err != nil { + log.Error("execute command error: %s", err) + } +} + +func parseCmd(cmd string) (string, string) { + ss := strings.SplitN(cmd, " ", 1) + if len(ss) != 2 { + return "", "" + } + verb, args := ss[0], ss[1] + if verb == "git" { + ss = strings.SplitN(args, " ", 1) + args = ss[1] + verb = fmt.Sprintf("%s %s", verb, ss[0]) + } + return verb, args +} |