Feat: add models/cache/config
This commit is contained in:
		
							
								
								
									
										115
									
								
								handlers/auth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								handlers/auth.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"crypto/hmac" | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/base64" | ||||
| 	"encoding/json" | ||||
| 	"golias/models" | ||||
| 	"golias/utils" | ||||
| 	"html/template" | ||||
| 	"log/slog" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func abortWithError(w http.ResponseWriter, msg string) { | ||||
| 	tmpl := template.Must(template.ParseGlob("components/*.html")) | ||||
| 	tmpl.ExecuteTemplate(w, "error", msg) | ||||
| } | ||||
|  | ||||
| func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | ||||
| 	r.ParseForm() | ||||
| 	username := r.PostFormValue("username") | ||||
| 	if username == "" { | ||||
| 		msg := "username not provided" | ||||
| 		slog.Error(msg) | ||||
| 		abortWithError(w, msg) | ||||
| 		return | ||||
| 	} | ||||
| 	// make sure username does not exists | ||||
| 	cleanName := utils.RemoveSpacesFromStr(username) | ||||
| 	// TODO: create user in db | ||||
| 	// login user | ||||
| 	cookie, err := makeCookie(cleanName, r.RemoteAddr) | ||||
| 	if err != nil { | ||||
| 		slog.Error("failed to login", "error", err) | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	http.SetCookie(w, cookie) | ||||
| 	tmpl, err := template.ParseGlob("components/*.html") | ||||
| 	if err != nil { | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	tmpl.ExecuteTemplate(w, "main", nil) | ||||
| } | ||||
|  | ||||
| func makeCookie(username string, remote string) (*http.Cookie, error) { | ||||
| 	// secret | ||||
| 	// Create a new random session token | ||||
| 	// sessionToken := xid.New().String() | ||||
| 	sessionToken := "token" | ||||
| 	expiresAt := time.Now().Add(time.Duration(cfg.SessionLifetime) * time.Second) | ||||
| 	// Set the token in the session map, along with the session information | ||||
| 	session := &models.Session{ | ||||
| 		Username: username, | ||||
| 		Expiry:   expiresAt, | ||||
| 	} | ||||
| 	cookieName := "session_token" | ||||
| 	// hmac to protect cookies | ||||
| 	hm := hmac.New(sha256.New, []byte(cfg.CookieSecret)) | ||||
| 	hm.Write([]byte(cookieName)) | ||||
| 	hm.Write([]byte(sessionToken)) | ||||
| 	signature := hm.Sum(nil) | ||||
| 	// b64 enc to avoid non-ascii | ||||
| 	cookieValue := base64.URLEncoding.EncodeToString([]byte( | ||||
| 		string(signature) + sessionToken)) | ||||
| 	cookie := &http.Cookie{ | ||||
| 		Name:     cookieName, | ||||
| 		Value:    cookieValue, | ||||
| 		Secure:   true, | ||||
| 		HttpOnly: true, | ||||
| 		SameSite: http.SameSiteNoneMode, | ||||
| 		Domain:   cfg.ServerConfig.Host, | ||||
| 	} | ||||
| 	slog.Info("check remote addr for cookie set", | ||||
| 		"remote", remote, "session", session) | ||||
| 	if strings.Contains(remote, "192.168.0") { | ||||
| 		// no idea what is going on | ||||
| 		// cookie.Domain = "192.168.0.15" | ||||
| 		cookie.Domain = "home.host" | ||||
| 		slog.Info("changing cookie domain", "domain", cookie.Domain) | ||||
| 	} | ||||
| 	// set ctx? | ||||
| 	// set user in session | ||||
| 	if err := cacheSetSession(sessionToken, session); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return cookie, nil | ||||
| } | ||||
|  | ||||
| func cacheGetSession(key string) (*models.Session, error) { | ||||
| 	userSessionB, err := memcache.Get(key) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	var us *models.Session | ||||
| 	if err := json.Unmarshal(userSessionB, &us); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return us, nil | ||||
| } | ||||
|  | ||||
| func cacheSetSession(key string, session *models.Session) error { | ||||
| 	sesb, err := json.Marshal(session) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	memcache.Set(key, sesb) | ||||
| 	// expire in 10 min | ||||
| 	memcache.Expire(key, 10*60) | ||||
| 	return nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder