Goit

Simple and lightweight Git web server
git clone http://git.omkov.net/Goit
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2023-11-27 11:01:06
Commit473d02cac949c8b69172128569571b64cf335b3a
Parentb8047017f5dc43349e044cdcee1994c6e906ca47

Move all authentication to unified function

Diffstat

M src/goit/auth.go | 37 -------------------------------------
M src/repo/commit.go | 10 +++++++---
M src/repo/create.go | 11 ++++++++---
M src/repo/file.go | 10 +++++++---
M src/repo/refs.go | 10 +++++++---
M src/repo/tree.go | 11 ++++++++---
M src/user/edit.go | 20 +++++++-------------
M src/user/login.go | 8 +++++++-
M src/user/sessions.go | 15 ++++++++++-----

9 files changed, 61 insertions, 71 deletions

diff --git a/src/goit/auth.go b/src/goit/auth.go
index 809cf18..f6b287c 100644
--- a/src/goit/auth.go
+++ b/src/goit/auth.go
@@ -197,43 +197,6 @@ func Auth(w http.ResponseWriter, r *http.Request, renew bool) (bool, *User, erro
 	return true, user, nil
 }
 
-/* Authenticate a user session cookie. */
-func AuthCookie(w http.ResponseWriter, r *http.Request, renew bool) (bool, int64) {
-	if uid, s := GetSessionCookie(r); s != (Session{}) {
-		if s.Expiry.After(time.Now()) {
-			if renew && time.Until(s.Expiry) < 24*time.Hour {
-				ip, _, _ := net.SplitHostPort(r.RemoteAddr)
-				s1, err := NewSession(uid, ip, time.Now().Add(2*24*time.Hour))
-				if err != nil {
-					log.Println("[Renew Auth]", err.Error())
-				} else {
-					SetSessionCookie(w, uid, s1)
-					EndSession(uid, s.Token)
-				}
-			}
-
-			return true, uid
-		}
-
-		EndSession(uid, s.Token)
-	}
-
-	return false, -1
-}
-
-/* Authenticate a user session cookie and check admin status. */
-func AuthCookieAdmin(w http.ResponseWriter, r *http.Request, renew bool) (bool, bool, int64) {
-	if ok, uid := AuthCookie(w, r, renew); ok {
-		if user, err := GetUser(uid); err == nil && user.IsAdmin {
-			return true, true, uid
-		}
-
-		return true, false, uid
-	}
-
-	return false, false, -1
-}
-
 /* Hash a password with a salt using Argon2. */
 func Hash(pass string, salt []byte) []byte {
 	return argon2.IDKey([]byte(pass), salt, 3, 64*1024, 4, 32)
diff --git a/src/repo/commit.go b/src/repo/commit.go
index 3ce03b5..c409427 100644
--- a/src/repo/commit.go
+++ b/src/repo/commit.go
@@ -20,13 +20,17 @@ import (
 )
 
 func HandleCommit(w http.ResponseWriter, r *http.Request) {
-	auth, uid := goit.AuthCookie(w, r, true)
+	auth, user, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[/repo/commit]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
 
 	repo, err := goit.GetRepoByName(mux.Vars(r)["repo"])
 	if err != nil {
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
-	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != uid)) {
+	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != user.Id)) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	}
@@ -49,7 +53,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 	}{
 		Title: repo.Name + " - Log", Name: repo.Name, Description: repo.Description,
 		Url:      util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name,
-		Editable: (auth && repo.OwnerId == uid),
+		Editable: (auth && repo.OwnerId == user.Id),
 	}
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
diff --git a/src/repo/create.go b/src/repo/create.go
index 48f5a3f..37d6ee1 100644
--- a/src/repo/create.go
+++ b/src/repo/create.go
@@ -11,8 +11,13 @@ import (
 )
 
 func HandleCreate(w http.ResponseWriter, r *http.Request) {
-	ok, uid := goit.AuthCookie(w, r, true)
-	if !ok {
+	auth, user, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[admin]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
+
+	if !auth {
 		goit.HttpError(w, http.StatusUnauthorized)
 		return
 	}
@@ -45,7 +50,7 @@ func HandleCreate(w http.ResponseWriter, r *http.Request) {
 		} else if exists {
 			data.Message = "Name \"" + data.Name + "\" is taken"
 		} else if err := goit.CreateRepo(goit.Repo{
-			OwnerId: uid, Name: data.Name, Description: data.Description, IsPrivate: data.IsPrivate,
+			OwnerId: user.Id, Name: data.Name, Description: data.Description, IsPrivate: data.IsPrivate,
 		}); err != nil {
 			log.Println("[/repo/create]", err.Error())
 			goit.HttpError(w, http.StatusInternalServerError)
diff --git a/src/repo/file.go b/src/repo/file.go
index 440ad1d..edc42db 100644
--- a/src/repo/file.go
+++ b/src/repo/file.go
@@ -18,7 +18,11 @@ import (
 )
 
 func HandleFile(w http.ResponseWriter, r *http.Request) {
-	auth, uid := goit.AuthCookie(w, r, true)
+	auth, user, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[admin]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
 
 	treepath := mux.Vars(r)["path"]
 	// if treepath == "" {
@@ -30,7 +34,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 	if err != nil {
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
-	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != uid)) {
+	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != user.Id)) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	}
@@ -45,7 +49,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 	}{
 		Title: repo.Name + " - File", Name: repo.Name, Description: repo.Description,
 		Url:      util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name,
-		Editable: (auth && repo.OwnerId == uid),
+		Editable: (auth && repo.OwnerId == user.Id),
 	}
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
diff --git a/src/repo/refs.go b/src/repo/refs.go
index a42e938..b0f2af4 100644
--- a/src/repo/refs.go
+++ b/src/repo/refs.go
@@ -16,13 +16,17 @@ import (
 )
 
 func HandleRefs(w http.ResponseWriter, r *http.Request) {
-	auth, uid := goit.AuthCookie(w, r, true)
+	auth, user, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[admin]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
 
 	repo, err := goit.GetRepoByName(mux.Vars(r)["repo"])
 	if err != nil {
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
-	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != uid)) {
+	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != user.Id)) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	}
@@ -36,7 +40,7 @@ func HandleRefs(w http.ResponseWriter, r *http.Request) {
 	}{
 		Title: repo.Name + " - References", Name: repo.Name, Description: repo.Description,
 		Url:      util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name,
-		Editable: (auth && repo.OwnerId == uid),
+		Editable: (auth && repo.OwnerId == user.Id),
 	}
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
diff --git a/src/repo/tree.go b/src/repo/tree.go
index 5657b60..e4f3bc6 100644
--- a/src/repo/tree.go
+++ b/src/repo/tree.go
@@ -18,14 +18,19 @@ import (
 )
 
 func HandleTree(w http.ResponseWriter, r *http.Request) {
-	auth, uid := goit.AuthCookie(w, r, true)
+	auth, user, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[admin]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
+
 	path := mux.Vars(r)["path"]
 
 	repo, err := goit.GetRepoByName(mux.Vars(r)["repo"])
 	if err != nil {
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
-	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != uid)) {
+	} else if repo == nil || (repo.IsPrivate && (!auth || repo.OwnerId != user.Id)) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	}
@@ -42,7 +47,7 @@ func HandleTree(w http.ResponseWriter, r *http.Request) {
 	}{
 		Title: repo.Name + " - Tree", Name: repo.Name, Description: repo.Description,
 		Url:      util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name,
-		Editable: (auth && repo.OwnerId == uid),
+		Editable: (auth && repo.OwnerId == user.Id),
 	}
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
diff --git a/src/user/edit.go b/src/user/edit.go
index 19cda31..f3a4486 100644
--- a/src/user/edit.go
+++ b/src/user/edit.go
@@ -13,20 +13,14 @@ import (
 )
 
 func HandleEdit(w http.ResponseWriter, r *http.Request) {
-	auth, uid := goit.AuthCookie(w, r, true)
-	if !auth {
-		goit.HttpError(w, http.StatusUnauthorized)
-		return
-	}
-
-	user, err := goit.GetUser(uid)
+	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		log.Println("[/user/edit]", err.Error())
-		goit.HttpError(w, http.StatusInternalServerError)
-		return
-	} else if user == nil {
-		log.Println("[/user/edit]", uid, "is a nonexistent UID")
+		log.Println("[admin]", err.Error())
 		goit.HttpError(w, http.StatusInternalServerError)
+	}
+
+	if !auth {
+		goit.HttpError(w, http.StatusUnauthorized)
 		return
 	}
 
@@ -53,7 +47,7 @@ func HandleEdit(w http.ResponseWriter, r *http.Request) {
 
 			if data.Form.Name == "" {
 				data.MessageA = "Username cannot be empty"
-			} else if slices.Contains(goit.Reserved, data.Form.Name) && uid != 0 {
+			} else if slices.Contains(goit.Reserved, data.Form.Name) && user.Id != 0 {
 				data.MessageA = "Username \"" + data.Form.Name + "\" is reserved"
 			} else if exists, err := goit.UserExists(data.Form.Name); err != nil {
 				log.Println("[/user/edit]", err.Error())
diff --git a/src/user/login.go b/src/user/login.go
index a87e7fa..cc8a7ee 100644
--- a/src/user/login.go
+++ b/src/user/login.go
@@ -17,7 +17,13 @@ import (
 )
 
 func HandleLogin(w http.ResponseWriter, r *http.Request) {
-	if auth, _ := goit.AuthCookie(w, r, true); auth {
+	auth, _, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[admin]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
+
+	if auth {
 		http.Redirect(w, r, "/", http.StatusFound)
 	}
 
diff --git a/src/user/sessions.go b/src/user/sessions.go
index b046091..1c3b6ae 100644
--- a/src/user/sessions.go
+++ b/src/user/sessions.go
@@ -12,7 +12,12 @@ import (
 )
 
 func HandleSessions(w http.ResponseWriter, r *http.Request) {
-	auth, uid := goit.AuthCookie(w, r, true)
+	auth, user, err := goit.Auth(w, r, true)
+	if err != nil {
+		log.Println("[admin]", err.Error())
+		goit.HttpError(w, http.StatusInternalServerError)
+	}
+
 	if !auth {
 		goit.HttpError(w, http.StatusUnauthorized)
 		return
@@ -34,14 +39,14 @@ func HandleSessions(w http.ResponseWriter, r *http.Request) {
 	goit.SessionsMutex.RLock()
 	goit.Debugln("[goit.HandleSessions] SessionsMutex rlock")
 
-	if revoke >= 0 && revoke < int64(len(goit.Sessions[uid])) {
-		var token = goit.Sessions[uid][revoke].Token
+	if revoke >= 0 && revoke < int64(len(goit.Sessions[user.Id])) {
+		var token = goit.Sessions[user.Id][revoke].Token
 		var current = token == ss.Token
 
 		goit.SessionsMutex.RUnlock()
 		goit.Debugln("[goit.HandleSessions] SessionsMutex runlock")
 
-		goit.EndSession(uid, token)
+		goit.EndSession(user.Id, token)
 
 		if current {
 			goit.EndSessionCookie(w)
@@ -53,7 +58,7 @@ func HandleSessions(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	for i, v := range goit.Sessions[uid] {
+	for i, v := range goit.Sessions[user.Id] {
 		data.Sessions = append(data.Sessions, row{
 			Index: fmt.Sprint(i), Ip: v.Ip, Seen: v.Seen.Format(time.DateTime), Expiry: v.Expiry.Format(time.DateTime),
 			Current: util.If(v.Token == ss.Token, "(current)", ""),