Add authentication to MakeHTMLAPI and use it for media requests
This commit is contained in:
parent
40eb7cbeef
commit
ccd337e1d4
|
@ -732,7 +732,7 @@ func Setup(
|
||||||
).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)
|
).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)
|
||||||
|
|
||||||
v3mux.Handle("/auth/{authType}/fallback/web",
|
v3mux.Handle("/auth/{authType}/fallback/web",
|
||||||
httputil.MakeHTMLAPI("auth_fallback", enableMetrics, func(w http.ResponseWriter, req *http.Request) {
|
httputil.MakeHTMLAPI("auth_fallback", userAPI, enableMetrics, func(w http.ResponseWriter, req *http.Request) {
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
AuthFallback(w, req, vars["authType"], cfg)
|
AuthFallback(w, req, vars["authType"], cfg)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package httputil
|
package httputil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -44,6 +45,7 @@ type BasicAuth struct {
|
||||||
|
|
||||||
type AuthAPIOpts struct {
|
type AuthAPIOpts struct {
|
||||||
GuestAccessAllowed bool
|
GuestAccessAllowed bool
|
||||||
|
WithAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthAPIOption is an option to MakeAuthAPI to add additional checks (e.g. guest access) to verify
|
// AuthAPIOption is an option to MakeAuthAPI to add additional checks (e.g. guest access) to verify
|
||||||
|
@ -57,6 +59,13 @@ func WithAllowGuests() AuthAPIOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAuth is an option to MakeHTMLAPI to add authentication.
|
||||||
|
func WithAuth() AuthAPIOption {
|
||||||
|
return func(opts *AuthAPIOpts) {
|
||||||
|
opts.WithAuth = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MakeAuthAPI turns a util.JSONRequestHandler function into an http.Handler which authenticates the request.
|
// MakeAuthAPI turns a util.JSONRequestHandler function into an http.Handler which authenticates the request.
|
||||||
func MakeAuthAPI(
|
func MakeAuthAPI(
|
||||||
metricsName string, userAPI userapi.QueryAcccessTokenAPI,
|
metricsName string, userAPI userapi.QueryAcccessTokenAPI,
|
||||||
|
@ -199,11 +208,31 @@ func MakeExternalAPI(metricsName string, f func(*http.Request) util.JSONResponse
|
||||||
|
|
||||||
// MakeHTMLAPI adds Span metrics to the HTML Handler function
|
// MakeHTMLAPI adds Span metrics to the HTML Handler function
|
||||||
// This is used to serve HTML alongside JSON error messages
|
// This is used to serve HTML alongside JSON error messages
|
||||||
func MakeHTMLAPI(metricsName string, enableMetrics bool, f func(http.ResponseWriter, *http.Request)) http.Handler {
|
func MakeHTMLAPI(metricsName string, userAPI userapi.QueryAcccessTokenAPI, enableMetrics bool, f func(http.ResponseWriter, *http.Request), checks ...AuthAPIOption) http.Handler {
|
||||||
withSpan := func(w http.ResponseWriter, req *http.Request) {
|
withSpan := func(w http.ResponseWriter, req *http.Request) {
|
||||||
trace, ctx := internal.StartTask(req.Context(), metricsName)
|
trace, ctx := internal.StartTask(req.Context(), metricsName)
|
||||||
defer trace.EndTask()
|
defer trace.EndTask()
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
|
// apply additional checks, if any
|
||||||
|
opts := AuthAPIOpts{}
|
||||||
|
for _, opt := range checks {
|
||||||
|
opt(&opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.WithAuth {
|
||||||
|
logger := util.GetLogger(req.Context())
|
||||||
|
_, jsonErr := auth.VerifyUserFromRequest(req, userAPI)
|
||||||
|
if jsonErr != nil {
|
||||||
|
logger.Debugf("VerifyUserFromRequest %s -> HTTP %d", req.RemoteAddr, jsonErr.Code)
|
||||||
|
w.WriteHeader(jsonErr.Code)
|
||||||
|
if err := json.NewEncoder(w).Encode(jsonErr); err != nil {
|
||||||
|
logger.WithError(err).Error("failed to encode JSON response")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f(w, req)
|
f(w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ func Setup(
|
||||||
rateLimits := httputil.NewRateLimits(&cfg.ClientAPI.RateLimiting)
|
rateLimits := httputil.NewRateLimits(&cfg.ClientAPI.RateLimiting)
|
||||||
|
|
||||||
v3mux := routers.Media.PathPrefix("/{apiversion:(?:r0|v1|v3)}/").Subrouter()
|
v3mux := routers.Media.PathPrefix("/{apiversion:(?:r0|v1|v3)}/").Subrouter()
|
||||||
|
v1mux := routers.Client.PathPrefix("/v1/media/").Subrouter()
|
||||||
|
|
||||||
activeThumbnailGeneration := &types.ActiveThumbnailGeneration{
|
activeThumbnailGeneration := &types.ActiveThumbnailGeneration{
|
||||||
PathToResult: map[string]*types.ThumbnailGenerationResult{},
|
PathToResult: map[string]*types.ThumbnailGenerationResult{},
|
||||||
|
@ -97,6 +98,15 @@ func Setup(
|
||||||
v3mux.Handle("/thumbnail/{serverName}/{mediaId}",
|
v3mux.Handle("/thumbnail/{serverName}/{mediaId}",
|
||||||
makeDownloadAPI("thumbnail", &cfg.MediaAPI, rateLimits, db, client, activeRemoteRequests, activeThumbnailGeneration),
|
makeDownloadAPI("thumbnail", &cfg.MediaAPI, rateLimits, db, client, activeRemoteRequests, activeThumbnailGeneration),
|
||||||
).Methods(http.MethodGet, http.MethodOptions)
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
|
||||||
|
// v1 client endpoints requiring auth
|
||||||
|
v1mux.Handle("/config", configHandler).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
v1mux.Handle("/download/{serverName}/{mediaId}", httputil.MakeHTMLAPI("download", userAPI, cfg.Global.Metrics.Enabled, downloadHandler, httputil.WithAuth())).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
v1mux.Handle("/download/{serverName}/{mediaId}/{downloadName}", httputil.MakeHTMLAPI("download", userAPI, cfg.Global.Metrics.Enabled, downloadHandler, httputil.WithAuth())).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
|
||||||
|
v1mux.Handle("/thumbnail/{serverName}/{mediaId}",
|
||||||
|
httputil.MakeHTMLAPI("thumbnail", userAPI, cfg.Global.Metrics.Enabled, makeDownloadAPI("thumbnail", &cfg.MediaAPI, rateLimits, db, client, activeRemoteRequests, activeThumbnailGeneration), httputil.WithAuth()),
|
||||||
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeDownloadAPI(
|
func makeDownloadAPI(
|
||||||
|
|
Loading…
Reference in a new issue