summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2014-04-05 15:17:57 +0800
committerLunny Xiao <xiaolunwen@gmail.com>2014-04-05 15:17:57 +0800
commit493b0c5ac212a28f46938cf8dfb2efb79f658548 (patch)
tree073c9c244dff9a3efe33fb5e02fc71b62e44e327
parent75db79b4b6bcb8f61dd957c9bd21b32d4746f866 (diff)
downloadgitea-493b0c5ac212a28f46938cf8dfb2efb79f658548.tar.gz
gitea-493b0c5ac212a28f46938cf8dfb2efb79f658548.zip
add ssl support for web
-rw-r--r--conf/app.ini5
-rw-r--r--routers/repo/repo.go96
-rw-r--r--templates/status/401.tmpl6
-rw-r--r--web.go18
4 files changed, 118 insertions, 7 deletions
diff --git a/conf/app.ini b/conf/app.ini
index abc27c39c4..f88c750e09 100644
--- a/conf/app.ini
+++ b/conf/app.ini
@@ -12,10 +12,13 @@ LANG_IGNS = Google Go|C|C++|Python|Ruby|C Sharp
LICENSES = Apache v2 License|GPL v2|MIT License|Affero GPL|Artistic License 2.0|BSD (3-Clause) License
[server]
+PROTOCOL = http
DOMAIN = localhost
-ROOT_URL = http://%(DOMAIN)s:%(HTTP_PORT)s/
+ROOT_URL = %(PROTOCOL)://%(DOMAIN)s:%(HTTP_PORT)s/
HTTP_ADDR =
HTTP_PORT = 3000
+CERT_FILE = cert.pem
+KEY_FILE = key.pem
[database]
; Either "mysql", "postgres" or "sqlite3"(binary release only), it's your choice
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index ae51c55139..cb7febd210 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,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),
diff --git a/templates/status/401.tmpl b/templates/status/401.tmpl
new file mode 100644
index 0000000000..98995381af
--- /dev/null
+++ b/templates/status/401.tmpl
@@ -0,0 +1,6 @@
+{{template "base/head" .}}
+{{template "base/navbar" .}}
+<div class="container">
+ 401 Unauthorized
+</div>
+{{template "base/footer" .}} \ No newline at end of file
diff --git a/web.go b/web.go
index 5fc3350f1f..18e48b84de 100644
--- a/web.go
+++ b/web.go
@@ -169,12 +169,22 @@ func runWeb(*cli.Context) {
// Not found handler.
m.NotFound(routers.NotFound)
+ protocol := base.Cfg.MustValue("server", "PROTOCOL", "http")
listenAddr := fmt.Sprintf("%s:%s",
base.Cfg.MustValue("server", "HTTP_ADDR"),
base.Cfg.MustValue("server", "HTTP_PORT", "3000"))
- log.Info("Listen: %s", listenAddr)
- if err := http.ListenAndServe(listenAddr, m); err != nil {
- fmt.Println(err.Error())
- //log.Critical(err.Error()) // not working now
+
+ if protocol == "http" {
+ log.Info("Listen: http://%s", listenAddr)
+ if err := http.ListenAndServe(listenAddr, m); err != nil {
+ fmt.Println(err.Error())
+ //log.Critical(err.Error()) // not working now
+ }
+ } else if protocol == "https" {
+ log.Info("Listen: https://%s", listenAddr)
+ if err := http.ListenAndServeTLS(listenAddr, base.Cfg.MustValue("server", "CERT_FILE"),
+ base.Cfg.MustValue("server", "KEY_FILE"), m); err != nil {
+ fmt.Println(err.Error())
+ }
}
}