client/web: fix serveAPIAuth in Login mode

In Login mode, must first run system auth. But once authorized,
should be able to reach rest of auth logic to check whether the
user can manage the node. This results in showing/hiding the
sign in button in the frontend login toggle.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
pull/10537/head
Sonia Appasamy 10 months ago committed by Sonia Appasamy
parent 7c172df791
commit c2319f0dfa

@ -400,11 +400,22 @@ type viewerIdentity struct {
// and returns an authResponse indicating the current auth state and any steps the user needs to take. // and returns an authResponse indicating the current auth state and any steps the user needs to take.
func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) { func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) {
var resp authResponse var resp authResponse
session, whois, status, sErr := s.getSession(r)
session, whois, status, err := s.getSession(r) if whois != nil {
switch { resp.ViewerIdentity = &viewerIdentity{
case s.mode == LoginServerMode || errors.Is(err, errNotUsingTailscale): LoginName: whois.UserProfile.LoginName,
// not using tailscale, so perform platform auth NodeName: whois.Node.Name,
ProfilePicURL: whois.UserProfile.ProfilePicURL,
}
if addrs := whois.Node.Addresses; len(addrs) > 0 {
resp.ViewerIdentity.NodeIP = addrs[0].Addr().String()
}
}
// First verify platform auth.
// If platform auth is needed, this should happen first.
if s.mode == LoginServerMode {
switch distro.Get() { switch distro.Get() {
case distro.Synology: case distro.Synology:
authorized, err := authorizeSynology(r) authorized, err := authorizeSynology(r)
@ -414,6 +425,8 @@ func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) {
} }
if !authorized { if !authorized {
resp.AuthNeeded = synoAuth resp.AuthNeeded = synoAuth
writeJSON(w, resp)
return
} }
case distro.QNAP: case distro.QNAP:
if _, err := authorizeQNAP(r); err != nil { if _, err := authorizeQNAP(r); err != nil {
@ -423,21 +436,24 @@ func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) {
default: default:
// no additional auth for this distro // no additional auth for this distro
} }
case err != nil && errors.Is(err, errNotOwner): }
switch {
case sErr != nil && errors.Is(sErr, errNotOwner):
// Restricted to the readonly view, no auth action to take. // Restricted to the readonly view, no auth action to take.
s.lc.IncrementCounter(r.Context(), "web_client_viewing_not_owner", 1) s.lc.IncrementCounter(r.Context(), "web_client_viewing_not_owner", 1)
resp.AuthNeeded = "" resp.AuthNeeded = ""
case err != nil && errors.Is(err, errTaggedLocalSource): case sErr != nil && errors.Is(sErr, errTaggedLocalSource):
// Restricted to the readonly view, no auth action to take. // Restricted to the readonly view, no auth action to take.
s.lc.IncrementCounter(r.Context(), "web_client_viewing_local_tag", 1) s.lc.IncrementCounter(r.Context(), "web_client_viewing_local_tag", 1)
resp.AuthNeeded = "" resp.AuthNeeded = ""
case err != nil && errors.Is(err, errTaggedRemoteSource): case sErr != nil && errors.Is(sErr, errTaggedRemoteSource):
// Restricted to the readonly view, no auth action to take. // Restricted to the readonly view, no auth action to take.
s.lc.IncrementCounter(r.Context(), "web_client_viewing_remote_tag", 1) s.lc.IncrementCounter(r.Context(), "web_client_viewing_remote_tag", 1)
resp.AuthNeeded = "" resp.AuthNeeded = ""
case err != nil && !errors.Is(err, errNoSession): case sErr != nil && !errors.Is(sErr, errNoSession):
// Any other error. // Any other error.
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, sErr.Error(), http.StatusInternalServerError)
return return
case session.isAuthorized(s.timeNow()): case session.isAuthorized(s.timeNow()):
if whois.Node.StableID == status.Self.ID { if whois.Node.StableID == status.Self.ID {
@ -451,16 +467,6 @@ func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) {
resp.AuthNeeded = tailscaleAuth resp.AuthNeeded = tailscaleAuth
} }
if whois != nil {
resp.ViewerIdentity = &viewerIdentity{
LoginName: whois.UserProfile.LoginName,
NodeName: whois.Node.Name,
ProfilePicURL: whois.UserProfile.ProfilePicURL,
}
if addrs := whois.Node.Addresses; len(addrs) > 0 {
resp.ViewerIdentity.NodeIP = addrs[0].Addr().String()
}
}
writeJSON(w, resp) writeJSON(w, resp)
} }

Loading…
Cancel
Save