serverAPIAuth handles requests to the /api/auth endpoint and returns an authResponse indicating the current auth state and any steps the user needs to take.
(w http.ResponseWriter, r *http.Request)
| 652 | // serverAPIAuth handles requests to the /api/auth endpoint |
| 653 | // and returns an authResponse indicating the current auth state and any steps the user needs to take. |
| 654 | func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) { |
| 655 | var resp authResponse |
| 656 | resp.ServerMode = s.mode |
| 657 | session, whois, status, sErr := s.getSession(r) |
| 658 | var caps peerCapabilities |
| 659 | |
| 660 | if whois != nil { |
| 661 | var err error |
| 662 | caps, err = toPeerCapabilities(status, whois) |
| 663 | if err != nil { |
| 664 | http.Error(w, sErr.Error(), http.StatusInternalServerError) |
| 665 | return |
| 666 | } |
| 667 | resp.ViewerIdentity = &viewerIdentity{ |
| 668 | LoginName: whois.UserProfile.LoginName, |
| 669 | NodeName: whois.Node.Name, |
| 670 | ProfilePicURL: whois.UserProfile.ProfilePicURL, |
| 671 | Capabilities: caps, |
| 672 | } |
| 673 | if addrs := whois.Node.Addresses; len(addrs) > 0 { |
| 674 | resp.ViewerIdentity.NodeIP = addrs[0].Addr().String() |
| 675 | } |
| 676 | } |
| 677 | |
| 678 | // First verify platform auth. |
| 679 | // If platform auth is needed, this should happen first. |
| 680 | if s.mode == LoginServerMode || s.mode == ReadOnlyServerMode { |
| 681 | switch distro.Get() { |
| 682 | case distro.Synology: |
| 683 | authorized, err := authorizeSynology(r) |
| 684 | if err != nil { |
| 685 | http.Error(w, err.Error(), http.StatusUnauthorized) |
| 686 | return |
| 687 | } |
| 688 | if !authorized { |
| 689 | resp.NeedsSynoAuth = true |
| 690 | writeJSON(w, resp) |
| 691 | return |
| 692 | } |
| 693 | case distro.QNAP: |
| 694 | if _, err := authorizeQNAP(r); err != nil { |
| 695 | http.Error(w, err.Error(), http.StatusUnauthorized) |
| 696 | return |
| 697 | } |
| 698 | default: |
| 699 | // no additional auth for this distro |
| 700 | } |
| 701 | } |
| 702 | |
| 703 | // We might have a session for which we haven't awaited the result yet. |
| 704 | // This can happen when the AuthURL opens in the same browser tab instead |
| 705 | // of a new one due to browser settings. |
| 706 | // (See https://github.com/tailscale/tailscale/issues/11905) |
| 707 | // We therefore set a PendingAuth flag when creating a new session, check |
| 708 | // it here and call awaitUserAuth if we find it to be true. Once the auth |
| 709 | // wait completes, awaitUserAuth will set PendingAuth to false. |
| 710 | if sErr == nil && session.PendingAuth == true { |
| 711 | if err := s.awaitUserAuth(r.Context(), session); err != nil { |