aboutsummaryrefslogtreecommitdiff
path: root/routers/repo/repo.go
diff options
context:
space:
mode:
author无闻 <joe2010xtmf@163.com>2014-04-07 15:47:26 -0400
committer无闻 <joe2010xtmf@163.com>2014-04-07 15:47:26 -0400
commit2577940c30f6a6d15390974ab36f8c3d1e00f9f4 (patch)
treec5f8fac19903327e78d5ac4f0fa2f8004a10974d /routers/repo/repo.go
parentef6b9784962d3152d3ec46833303bad72915af57 (diff)
parent22feddf804c7fbf3418cbbc8e7302da271da4e5a (diff)
Merge pull request #68 from gogits/dev
Dev
Diffstat (limited to 'routers/repo/repo.go')
-rw-r--r--routers/repo/repo.go99
1 files changed, 97 insertions, 2 deletions
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 6a5a7ae4..d223600c 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -5,6 +5,8 @@
package repo
import (
+ "encoding/base64"
+ "errors"
"fmt"
"path"
"path/filepath"
@@ -237,16 +239,109 @@ func SingleDownload(ctx *middleware.Context, params martini.Params) {
ctx.Res.Write(data)
}
-func Http(ctx *middleware.Context, params martini.Params) {
- // TODO: access check
+func basicEncode(username, password string) string {
+ auth := username + ":" + password
+ return base64.StdEncoding.EncodeToString([]byte(auth))
+}
+
+func basicDecode(encoded string) (user string, name string, err error) {
+ var s []byte
+ s, err = base64.StdEncoding.DecodeString(encoded)
+ if err != nil {
+ return
+ }
+
+ a := strings.Split(string(s), ":")
+ if len(a) == 2 {
+ user, name = a[0], a[1]
+ } else {
+ err = errors.New("decode failed")
+ }
+ return
+}
+
+func authRequired(ctx *middleware.Context) {
+ ctx.ResponseWriter.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
+ ctx.Data["ErrorMsg"] = "no basic auth and digit auth"
+ ctx.HTML(401, fmt.Sprintf("status/401"))
+}
+func Http(ctx *middleware.Context, params martini.Params) {
username := params["username"]
reponame := params["reponame"]
if strings.HasSuffix(reponame, ".git") {
reponame = reponame[:len(reponame)-4]
}
+ //fmt.Println("req:", ctx.Req.Header)
+
+ repoUser, err := models.GetUserByName(username)
+ if err != nil {
+ ctx.Handle(500, "repo.GetUserByName", nil)
+ return
+ }
+
+ repo, err := models.GetRepositoryByName(repoUser.Id, reponame)
+ if err != nil {
+ ctx.Handle(500, "repo.GetRepositoryByName", nil)
+ return
+ }
+
+ isPull := webdav.IsPullMethod(ctx.Req.Method)
+ var askAuth = !(!repo.IsPrivate && isPull)
+
+ //authRequired(ctx)
+ //return
+
+ // check access
+ if askAuth {
+ // check digit auth
+
+ // check basic auth
+ baHead := ctx.Req.Header.Get("Authorization")
+ if baHead == "" {
+ authRequired(ctx)
+ return
+ }
+
+ auths := strings.Fields(baHead)
+ if len(auths) != 2 || auths[0] != "Basic" {
+ ctx.Handle(401, "no basic auth and digit auth", nil)
+ return
+ }
+ authUsername, passwd, err := basicDecode(auths[1])
+ if err != nil {
+ ctx.Handle(401, "no basic auth and digit auth", nil)
+ return
+ }
+
+ authUser, err := models.GetUserByName(authUsername)
+ if err != nil {
+ ctx.Handle(401, "no basic auth and digit auth", nil)
+ return
+ }
+
+ newUser := &models.User{Passwd: passwd}
+ newUser.EncodePasswd()
+ if authUser.Passwd != newUser.Passwd {
+ ctx.Handle(401, "no basic auth and digit auth", nil)
+ return
+ }
+
+ var tp = models.AU_WRITABLE
+ if isPull {
+ tp = models.AU_READABLE
+ }
+
+ has, err := models.HasAccess(authUsername, username+"/"+reponame, tp)
+ if err != nil || !has {
+ ctx.Handle(401, "no basic auth and digit auth", nil)
+ return
+ }
+ }
+
dir := models.RepoPath(username, reponame)
+
prefix := path.Join("/", username, params["reponame"])
server := webdav.NewServer(
dir, prefix, true)