lavender/server/login.go
2024-02-07 01:18:17 +00:00

80 lines
2.2 KiB
Go

package server
import (
"github.com/1f349/lavender/pages"
"github.com/google/uuid"
"github.com/julienschmidt/httprouter"
"golang.org/x/oauth2"
"net/http"
"net/url"
"strings"
"time"
)
func (h *HttpServer) loginGet(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
cookie, err := req.Cookie("lavender-login-name")
if err == nil && cookie.Valid() == nil {
pages.RenderPageTemplate(rw, "login-memory", map[string]any{
"ServiceName": h.conf.ServiceName,
"Origin": req.URL.Query().Get("origin"),
"LoginName": cookie.Value,
})
return
}
pages.RenderPageTemplate(rw, "login", map[string]any{
"ServiceName": h.conf.ServiceName,
"Origin": req.URL.Query().Get("origin"),
})
}
func (h *HttpServer) loginPost(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
if req.PostFormValue("not-you") == "1" {
http.SetCookie(rw, &http.Cookie{
Name: "lavender-login-name",
Value: "",
Path: "/",
MaxAge: -1,
Secure: true,
SameSite: http.SameSiteStrictMode,
})
http.Redirect(rw, req, (&url.URL{
Path: "/login",
RawQuery: url.Values{
"origin": []string{req.PostFormValue("origin")},
}.Encode(),
}).String(), http.StatusFound)
return
}
loginName := req.PostFormValue("loginname")
login := h.manager.FindServiceFromLogin(loginName)
if login == nil {
http.Error(rw, "No login service defined for this username", http.StatusBadRequest)
return
}
// the @ must exist if the service is defined
n := strings.IndexByte(loginName, '@')
loginUn := loginName[:n]
now := time.Now()
future := now.AddDate(1, 0, 0)
http.SetCookie(rw, &http.Cookie{
Name: "lavender-login-name",
Value: loginName,
Path: "/",
Expires: future,
MaxAge: int(future.Sub(now).Seconds()),
Secure: true,
SameSite: http.SameSiteStrictMode,
})
// save state for use later
state := login.Config.Namespace + ":" + uuid.NewString()
h.flowState.Set(state, flowStateData{login}, time.Now().Add(15*time.Minute))
// generate oauth2 config and redirect to authorize URL
oa2conf := login.OAuth2Config
oa2conf.RedirectURL = h.conf.BaseUrl + "/callback"
nextUrl := oa2conf.AuthCodeURL(state, oauth2.SetAuthURLParam("login_name", loginUn))
http.Redirect(rw, req, nextUrl, http.StatusFound)
}