Files
opencloud/services/collaboration/pkg/middleware/proofkeys.go
Jörn Friedrich Dreyer 8e028f17e9 change module name
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2025-01-13 09:58:18 +01:00

68 lines
2.2 KiB
Go

package middleware
import (
"net/http"
"net/url"
"time"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/config"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/proofkeys"
"github.com/rs/zerolog"
)
// ProofKeysMiddleware will verify the proof keys of the requests.
// This is a middleware that could be disabled / not set.
//
// Requests will fail with a 500 HTTP status if the verification fails.
// As said, this can be disabled (via configuration) if you want to skip
// the verification.
// The middleware requires hitting the "/hosting/discovery" endpoint of the
// WOPI app in order to get the keys. The keys will be cached in memory for
// 12 hours (or the configured value) before hitting the endpoint again to
// request new / updated keys.
func ProofKeysMiddleware(cfg *config.Config, next http.Handler) http.Handler {
wopiDiscovery := cfg.App.Addr + "/hosting/discovery"
insecure := cfg.App.Insecure
cacheDuration, err := time.ParseDuration(cfg.App.ProofKeys.Duration)
if err != nil {
cacheDuration = 12 * time.Hour
}
pkHandler := proofkeys.NewVerifyHandler(wopiDiscovery, insecure, cacheDuration)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger := zerolog.Ctx(r.Context())
// the url we need is the one being requested, but we need the
// scheme and host, so we'll get those from the configured WOPISrc
wopiSrcURL, _ := url.Parse(cfg.Wopi.WopiSrc)
if cfg.Wopi.ProxyURL != "" {
wopiSrcURL, _ = url.Parse(cfg.Wopi.ProxyURL)
}
currentURL, _ := url.Parse(r.URL.String())
currentURL.Scheme = wopiSrcURL.Scheme
currentURL.Host = wopiSrcURL.Host
accessToken := r.URL.Query().Get("access_token")
stamp := r.Header.Get("X-WOPI-TimeStamp")
err := pkHandler.Verify(
accessToken,
currentURL.String(),
stamp,
r.Header.Get("X-WOPI-Proof"),
r.Header.Get("X-WOPI-ProofOld"),
proofkeys.VerifyWithLogger(logger),
)
if err != nil {
logger.Error().Err(err).Msg("ProofKeys verification failed")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
logger.Debug().Msg("ProofKeys verified")
next.ServeHTTP(w, r)
})
}