webapi: Add option for some URLs to accept the API key in the parameter, instead of the "x-api-key" HTTP header. By default add /file/read and /file/view.

This allows embedding the URLs into existing code that may not be able to set the special HTTP header.
This commit is contained in:
Kleissner
2021-12-13 16:49:56 +01:00
parent 7adadf9ad5
commit cab881ebdb

View File

@@ -23,7 +23,8 @@ type WebapiInstance struct {
backend *core.Backend backend *core.Backend
// Router can be used to register additional API functions // Router can be used to register additional API functions
Router *mux.Router Router *mux.Router
AllowKeyInParam []string // List of paths that accept the API key as &k= parameter
} }
// WSUpgrader is used for websocket functionality. It allows all requests. // WSUpgrader is used for websocket functionality. It allows all requests.
@@ -45,12 +46,13 @@ func Start(Backend *core.Backend, ListenAddresses []string, UseSSL bool, Certifi
} }
api = &WebapiInstance{ api = &WebapiInstance{
backend: Backend, backend: Backend,
Router: mux.NewRouter(), Router: mux.NewRouter(),
AllowKeyInParam: []string{"/file/read", "/file/view"},
} }
if APIKey != uuid.Nil { if APIKey != uuid.Nil {
api.Router.Use(authenticateMiddleware(APIKey)) api.Router.Use(api.authenticateMiddleware(APIKey))
} }
api.Router.HandleFunc("/test", apiTest).Methods("GET") api.Router.HandleFunc("/test", apiTest).Methods("GET")
@@ -152,10 +154,19 @@ func DecodeJSON(w http.ResponseWriter, r *http.Request, data interface{}) (err e
} }
// authenticateMiddleware returns a middleware function to be used with mux.Router.Use(). It handles all authentication functionality. // authenticateMiddleware returns a middleware function to be used with mux.Router.Use(). It handles all authentication functionality.
func authenticateMiddleware(APIKey uuid.UUID) func(http.Handler) http.Handler { func (api *WebapiInstance) authenticateMiddleware(APIKey uuid.UUID) func(http.Handler) http.Handler {
return (func(next http.Handler) http.Handler { return (func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
keyID, err := uuid.Parse(r.Header.Get("x-api-key")) keyID, err := uuid.Parse(r.Header.Get("x-api-key"))
if err != nil { // special case for some paths
for _, exceptPath := range api.AllowKeyInParam {
if exceptPath == r.URL.Path {
r.ParseForm()
keyID, err = uuid.Parse(r.Form.Get("k"))
break
}
}
}
if err != nil { // Invalid key format if err != nil { // Invalid key format
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
return return