client/web: move more session logic to auth.go

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
Sonia Appasamy
2023-11-01 16:09:59 -04:00
committed by Sonia Appasamy
parent 535cb6c3f5
commit 7a725bb4f0
3 changed files with 58 additions and 35 deletions

View File

@@ -214,10 +214,10 @@ func (s *Server) authorizeRequest(w http.ResponseWriter, r *http.Request) (ok bo
case strings.HasPrefix(r.URL.Path, "/api/"):
// All other /api/ endpoints require a valid browser session.
//
// TODO(sonia): s.getTailscaleBrowserSession calls whois again,
// TODO(sonia): s.getSession calls whois again,
// should try and use the above call instead of running another
// localapi request.
session, _, err := s.getTailscaleBrowserSession(r)
session, _, err := s.getSession(r)
if err != nil || !session.isAuthorized(s.timeNow()) {
http.Error(w, "no valid session", http.StatusUnauthorized)
return false
@@ -289,57 +289,34 @@ func (s *Server) serveTailscaleAuth(w http.ResponseWriter, r *http.Request) {
}
var resp authResponse
session, whois, err := s.getTailscaleBrowserSession(r)
session, whois, err := s.getSession(r)
switch {
case err != nil && !errors.Is(err, errNoSession):
http.Error(w, err.Error(), http.StatusUnauthorized)
return
case session == nil:
// Create a new session.
d, err := s.getOrAwaitAuth(r.Context(), "", whois.Node.ID)
session, err := s.newSession(r.Context(), whois)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sid, err := s.newSessionID()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session := &browserSession{
ID: sid,
SrcNode: whois.Node.ID,
SrcUser: whois.UserProfile.ID,
AuthID: d.ID,
AuthURL: d.URL,
Created: s.timeNow(),
}
s.browserSessions.Store(sid, session)
// Set the cookie on browser.
http.SetCookie(w, &http.Cookie{
Name: sessionCookieName,
Value: sid,
Raw: sid,
Value: session.ID,
Raw: session.ID,
Path: "/",
Expires: session.expires(),
})
resp = authResponse{OK: false, AuthURL: d.URL}
resp = authResponse{OK: false, AuthURL: session.AuthURL}
case !session.isAuthorized(s.timeNow()):
if r.URL.Query().Get("wait") == "true" {
// Client requested we block until user completes auth.
d, err := s.getOrAwaitAuth(r.Context(), session.AuthID, whois.Node.ID)
if err != nil {
if err := s.awaitUserAuth(r.Context(), session); err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
// Clean up the session. Doing this on any error from control
// server to avoid the user getting stuck with a bad session
// cookie.
s.browserSessions.Delete(session.ID)
return
}
if d.Complete {
session.Authenticated = d.Complete
s.browserSessions.Store(session.ID, session)
}
}
if session.isAuthorized(s.timeNow()) {
resp = authResponse{OK: true}