1
0
Fork 0
mirror of https://github.com/binwiederhier/ntfy.git synced 2025-05-29 18:05:36 +02:00

Fully support auth in Web UI; persist users in localStorage (for now); add ugly ?auth=... param

This commit is contained in:
Philipp Heckel 2022-02-25 23:25:04 -05:00
parent 6d343c0f1a
commit 530f55c234
16 changed files with 237 additions and 72 deletions
server

View file

@ -862,7 +862,7 @@ func parseSince(r *http.Request, poll bool) (sinceTime, error) {
func (s *Server) handleOptions(w http.ResponseWriter, _ *http.Request) error {
w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST")
w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
w.Header().Set("Access-Control-Allow-Headers", "Authorization") // CORS, allow auth
w.Header().Set("Access-Control-Allow-Headers", "Authorization") // CORS, allow auth via JS
return nil
}
@ -1091,7 +1091,7 @@ func (s *Server) withAuth(next handleFunc, perm auth.Permission) handleFunc {
return err
}
var user *auth.User // may stay nil if no auth header!
username, password, ok := r.BasicAuth()
username, password, ok := extractUserPass(r)
if ok {
if user, err = s.auth.Authenticate(username, password); err != nil {
log.Printf("authentication failed: %s", err.Error())
@ -1108,6 +1108,27 @@ func (s *Server) withAuth(next handleFunc, perm auth.Permission) handleFunc {
}
}
// extractUserPass reads the username/password from the basic auth header (Authorization: Basic ...),
// or from the ?auth=... query param. The latter is required only to support the WebSocket JavaScript
// class, which does not support passing headers during the initial request. The auth query param
// is effectively double base64 encoded. Its format is base64(Basic base64(user:pass)).
func extractUserPass(r *http.Request) (username string, password string, ok bool) {
username, password, ok = r.BasicAuth()
if ok {
return
}
authParam := readQueryParam(r, "authorization", "auth")
if authParam != "" {
a, err := base64.RawURLEncoding.DecodeString(authParam)
if err != nil {
return
}
r.Header.Set("Authorization", string(a))
return r.BasicAuth()
}
return
}
// visitor creates or retrieves a rate.Limiter for the given visitor.
// This function was taken from https://www.alexedwards.net/blog/how-to-rate-limit-http-requests (MIT).
func (s *Server) visitor(r *http.Request) *visitor {