mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	add ssl support for web
This commit is contained in:
		@@ -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
 | 
					LICENSES = Apache v2 License|GPL v2|MIT License|Affero GPL|Artistic License 2.0|BSD (3-Clause) License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[server]
 | 
					[server]
 | 
				
			||||||
 | 
					PROTOCOL = http
 | 
				
			||||||
DOMAIN = localhost
 | 
					DOMAIN = localhost
 | 
				
			||||||
ROOT_URL = http://%(DOMAIN)s:%(HTTP_PORT)s/
 | 
					ROOT_URL = %(PROTOCOL)://%(DOMAIN)s:%(HTTP_PORT)s/
 | 
				
			||||||
HTTP_ADDR = 
 | 
					HTTP_ADDR = 
 | 
				
			||||||
HTTP_PORT = 3000
 | 
					HTTP_PORT = 3000
 | 
				
			||||||
 | 
					CERT_FILE = cert.pem
 | 
				
			||||||
 | 
					KEY_FILE = key.pem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[database]
 | 
					[database]
 | 
				
			||||||
; Either "mysql", "postgres" or "sqlite3"(binary release only), it's your choice
 | 
					; Either "mysql", "postgres" or "sqlite3"(binary release only), it's your choice
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,8 @@
 | 
				
			|||||||
package repo
 | 
					package repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
@@ -237,15 +239,105 @@ func SingleDownload(ctx *middleware.Context, params martini.Params) {
 | 
				
			|||||||
	ctx.Res.Write(data)
 | 
						ctx.Res.Write(data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Http(ctx *middleware.Context, params martini.Params) {
 | 
					func basicEncode(username, password string) string {
 | 
				
			||||||
	// TODO: access check
 | 
						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"]
 | 
						username := params["username"]
 | 
				
			||||||
	reponame := params["reponame"]
 | 
						reponame := params["reponame"]
 | 
				
			||||||
	if strings.HasSuffix(reponame, ".git") {
 | 
						if strings.HasSuffix(reponame, ".git") {
 | 
				
			||||||
		reponame = reponame[:len(reponame)-4]
 | 
							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"])
 | 
						prefix := path.Join("/", username, params["reponame"])
 | 
				
			||||||
	server := webdav.NewServer(
 | 
						server := webdav.NewServer(
 | 
				
			||||||
		models.RepoPath(username, reponame),
 | 
							models.RepoPath(username, reponame),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								templates/status/401.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								templates/status/401.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					{{template "base/head" .}}
 | 
				
			||||||
 | 
					{{template "base/navbar" .}}
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
						401 Unauthorized
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{{template "base/footer" .}}
 | 
				
			||||||
							
								
								
									
										12
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								web.go
									
									
									
									
									
								
							@@ -169,12 +169,22 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
	// Not found handler.
 | 
						// Not found handler.
 | 
				
			||||||
	m.NotFound(routers.NotFound)
 | 
						m.NotFound(routers.NotFound)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protocol := base.Cfg.MustValue("server", "PROTOCOL", "http")
 | 
				
			||||||
	listenAddr := fmt.Sprintf("%s:%s",
 | 
						listenAddr := fmt.Sprintf("%s:%s",
 | 
				
			||||||
		base.Cfg.MustValue("server", "HTTP_ADDR"),
 | 
							base.Cfg.MustValue("server", "HTTP_ADDR"),
 | 
				
			||||||
		base.Cfg.MustValue("server", "HTTP_PORT", "3000"))
 | 
							base.Cfg.MustValue("server", "HTTP_PORT", "3000"))
 | 
				
			||||||
	log.Info("Listen: %s", listenAddr)
 | 
					
 | 
				
			||||||
 | 
						if protocol == "http" {
 | 
				
			||||||
 | 
							log.Info("Listen: http://%s", listenAddr)
 | 
				
			||||||
		if err := http.ListenAndServe(listenAddr, m); err != nil {
 | 
							if err := http.ListenAndServe(listenAddr, m); err != nil {
 | 
				
			||||||
			fmt.Println(err.Error())
 | 
								fmt.Println(err.Error())
 | 
				
			||||||
			//log.Critical(err.Error()) // not working now
 | 
								//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())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user