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) }