authorizeRequest reports whether the request from the web client is authorized to be completed. It reports true if the request is authorized, and false otherwise. authorizeRequest manages writing out any relevant authorization errors to the ResponseWriter itself.
(w http.ResponseWriter, r *http.Request)
| 471 | // authorizeRequest manages writing out any relevant authorization |
| 472 | // errors to the ResponseWriter itself. |
| 473 | func (s *Server) authorizeRequest(w http.ResponseWriter, r *http.Request) (ok bool) { |
| 474 | if s.mode == ManageServerMode { // client using tailscale auth |
| 475 | session, _, _, err := s.getSession(r) |
| 476 | switch { |
| 477 | case errors.Is(err, errNotUsingTailscale): |
| 478 | // All requests must be made over tailscale. |
| 479 | http.Error(w, "must access over tailscale", http.StatusUnauthorized) |
| 480 | return false |
| 481 | case r.URL.Path == "/api/data" && r.Method == httpm.GET: |
| 482 | // Readonly endpoint allowed without valid browser session. |
| 483 | return true |
| 484 | case r.URL.Path == "/api/device-details-click" && r.Method == httpm.POST: |
| 485 | // Special case metric endpoint that is allowed without a browser session. |
| 486 | return true |
| 487 | case strings.HasPrefix(r.URL.Path, "/api/"): |
| 488 | // All other /api/ endpoints require a valid browser session. |
| 489 | if err != nil || !session.isAuthorized(s.timeNow()) { |
| 490 | http.Error(w, "no valid session", http.StatusUnauthorized) |
| 491 | return false |
| 492 | } |
| 493 | return true |
| 494 | default: |
| 495 | // No additional auth on non-api (assets, index.html, etc). |
| 496 | return true |
| 497 | } |
| 498 | } |
| 499 | // Client using system-specific auth. |
| 500 | switch distro.Get() { |
| 501 | case distro.Synology: |
| 502 | if !buildfeatures.HasSynology { |
| 503 | // Synology support not built in. |
| 504 | return false |
| 505 | } |
| 506 | authorized, _ := authorizeSynology(r) |
| 507 | return authorized |
| 508 | case distro.QNAP: |
| 509 | authorized, _ := authorizeQNAP(r) |
| 510 | return authorized |
| 511 | default: |
| 512 | return true // no additional auth for this distro |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | // serveLoginAPI serves requests for the web login client. |
| 517 | // It should only be called by Server.ServeHTTP, via Server.apiHandler, |