git.sophuwu.com > authuwu   
              103
            
             package authuwu

import (
	"fmt"
	"git.sophuwu.com/authuwu/cookie"
	uwudb "git.sophuwu.com/authuwu/db"
	"git.sophuwu.com/authuwu/userpass"
	"net/http"
	"time"
)

func OpenDB(path string) error {
	return uwudb.Open(path)
}
func CloseDB() error {
	return uwudb.Close()
}

func NewAuthuwuHandler(h http.Handler, cookieTime time.Duration, loginPage string) *AuthuwuHandler {
	if loginPage == "" {
		loginPage = LoginPage
	}
	return &AuthuwuHandler{
		Handler:    h,
		CookieTime: cookieTime,
		LoginPage:  loginPage,
	}
}

type AuthuwuHandler struct {
	Handler    http.Handler
	CookieTime time.Duration
	LoginPage  string
}

// LoginPage is the HTML template for the login page. Should contain a form that submits to the login handler.
// Must action to "?authuwu:login" with method POST.
// Must contain inputs for username, password
var LoginPage = `<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form method="POST" action="?authuwu:login">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<input type="submit" value="Login">
</form>
</body>
</html>
`

func (h *AuthuwuHandler) loginHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, h.LoginPage)
		return
	}
	username := r.FormValue("username")
	password := r.FormValue("password")
	if username == "" || password == "" {
		http.Redirect(w, r, r.URL.Path+"?authuwu:login", http.StatusBadRequest)
		return
	}
	ok, err := userpass.UserAuth(username, password)
	if err != nil || !ok {
		http.Redirect(w, r, r.URL.Path+"?authuwu:login", http.StatusUnauthorized)
		return
	}
	c, err := cookie.NewCookie(username, h.CookieTime)
	if err != nil {
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}
	http.SetCookie(w, &c)
	http.Redirect(w, r, r.URL.Path, http.StatusSeeOther)
}

func (h *AuthuwuHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.URL.RawQuery == "authuwu:login" {
		h.loginHandler(w, r)
		return
	}
	ok, user, err := cookie.GetCookie(r)
	if err == nil && ok && user != "" {
		var u *userpass.User
		u, err = userpass.GetUser(user)
		if err == nil && u != nil && u.Username != "" {
			if r.URL.RawQuery == "authuwu:logout" {
				_ = cookie.DeleteCookie(r)
				http.Redirect(w, r, r.URL.Path, http.StatusSeeOther)
				return
			}
			h.Handler.ServeHTTP(w, r)
			return
		}
	}
	h.loginHandler(w, r)
}