|
@@ -5,6 +5,8 @@
|
|
|
package repo
|
|
|
|
|
|
import (
|
|
|
+ "encoding/base64"
|
|
|
+ "errors"
|
|
|
"fmt"
|
|
|
"path"
|
|
|
"path/filepath"
|
|
@@ -237,15 +239,105 @@ 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="Gogs Auth"`)
|
|
|
+ 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]
|
|
|
}
|
|
|
|
|
|
+ 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 != "" {
|
|
|
+ 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
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ authRequired(ctx)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
prefix := path.Join("/", username, params["reponame"])
|
|
|
server := webdav.NewServer(
|
|
|
models.RepoPath(username, reponame),
|