mirror of
https://github.com/hanzo-fi/stack.git
synced 2026-10-30 20:34:43 +00:00
158 lines
5.8 KiB
Go
158 lines
5.8 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/formancehq/go-libs/api"
|
|
"github.com/formancehq/go-libs/auth"
|
|
"github.com/formancehq/go-libs/logging"
|
|
"github.com/formancehq/payments/cmd/connectors/internal/api/backend"
|
|
"github.com/formancehq/payments/internal/models"
|
|
"github.com/gorilla/mux"
|
|
"go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
|
|
)
|
|
|
|
func httpRouter(
|
|
logger logging.Logger,
|
|
b backend.ServiceBackend,
|
|
serviceInfo api.ServiceInfo,
|
|
a auth.Authenticator,
|
|
connectorHandlers []connectorHandler,
|
|
otelTraces bool,
|
|
) *mux.Router {
|
|
rootMux := mux.NewRouter()
|
|
|
|
// We have to keep this recovery handler here to ensure that the health
|
|
// endpoint is not panicking
|
|
rootMux.Use(recoveryHandler(httpRecoveryFunc(otelTraces)))
|
|
rootMux.Use(httpCorsHandler())
|
|
rootMux.Use(httpServeFunc)
|
|
rootMux.Use(func(handler http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
handler.ServeHTTP(w, r.WithContext(logging.ContextWithLogger(r.Context(), logger)))
|
|
})
|
|
})
|
|
|
|
rootMux.Path("/_health").Handler(healthHandler(b))
|
|
|
|
subRouter := rootMux.NewRoute().Subrouter()
|
|
if otelTraces {
|
|
subRouter.Use(otelmux.Middleware(serviceName))
|
|
// Add a second recovery handler to ensure that the otel middleware
|
|
// is catching the error in the trace
|
|
rootMux.Use(recoveryHandler(httpRecoveryFunc(otelTraces)))
|
|
}
|
|
subRouter.Path("/_live").Handler(liveHandler())
|
|
subRouter.Path("/_info").Handler(api.InfoHandler(serviceInfo))
|
|
|
|
authGroup := subRouter.Name("authenticated").Subrouter()
|
|
authGroup.Use(auth.Middleware(a))
|
|
|
|
authGroup.Path("/bank-accounts").Methods(http.MethodPost).Handler(createBankAccountHandler(b))
|
|
authGroup.Path("/bank-accounts/{bankAccountID}/forward").Methods(http.MethodPost).Handler(forwardBankAccountToConnector(b))
|
|
authGroup.Path("/bank-accounts/{bankAccountID}/metadata").Methods(http.MethodPatch).Handler(updateBankAccountMetadataHandler(b))
|
|
|
|
authGroup.Path("/transfer-initiations").Methods(http.MethodPost).Handler(createTransferInitiationHandler(b))
|
|
authGroup.Path("/transfer-initiations/{transferID}/status").Methods(http.MethodPost).Handler(updateTransferInitiationStatusHandler(b))
|
|
authGroup.Path("/transfer-initiations/{transferID}/retry").Methods(http.MethodPost).Handler(retryTransferInitiationHandler(b))
|
|
authGroup.Path("/transfer-initiations/{transferID}/reverse").Methods(http.MethodPost).Handler(reverseTransferInitiationHandler(b))
|
|
authGroup.Path("/transfer-initiations/{transferID}").Methods(http.MethodDelete).Handler(deleteTransferInitiationHandler(b))
|
|
|
|
authGroup.HandleFunc("/connectors", readConnectorsHandler(b))
|
|
|
|
connectorGroupAuthenticated := authGroup.PathPrefix("/connectors").Subrouter()
|
|
connectorGroupAuthenticated.Path("/configs").Handler(connectorConfigsHandler())
|
|
|
|
// Needed for webhooks
|
|
connectorGroupUnauthenticated := subRouter.PathPrefix("/connectors").Subrouter()
|
|
|
|
for _, h := range connectorHandlers {
|
|
connectorGroupAuthenticated.PathPrefix("/" + h.Provider.String()).Handler(
|
|
http.StripPrefix("/connectors", h.Handler))
|
|
|
|
connectorGroupAuthenticated.PathPrefix("/" + h.Provider.StringLower()).Handler(
|
|
http.StripPrefix("/connectors", h.Handler))
|
|
|
|
if h.WebhookHandler != nil {
|
|
connectorGroupUnauthenticated.PathPrefix("/webhooks/" + h.Provider.String()).Handler(
|
|
http.StripPrefix("/connectors", h.WebhookHandler))
|
|
|
|
connectorGroupUnauthenticated.PathPrefix("/webhooks/" + h.Provider.StringLower()).Handler(
|
|
http.StripPrefix("/connectors", h.WebhookHandler))
|
|
}
|
|
}
|
|
|
|
return rootMux
|
|
}
|
|
|
|
func connectorRouter[Config models.ConnectorConfigObject](
|
|
provider models.ConnectorProvider,
|
|
b backend.ManagerBackend[Config],
|
|
) *mux.Router {
|
|
r := mux.NewRouter()
|
|
|
|
addRoute(r, provider, "", http.MethodPost, install(b))
|
|
addRoute(r, provider, "/{connectorID}", http.MethodDelete, uninstall(b, V1))
|
|
addRoute(r, provider, "/{connectorID}/config", http.MethodGet, readConfig(b, V1))
|
|
addRoute(r, provider, "/{connectorID}/config", http.MethodPost, updateConfig(b, V1))
|
|
addRoute(r, provider, "/{connectorID}/reset", http.MethodPost, reset(b, V1))
|
|
addRoute(r, provider, "/{connectorID}/tasks", http.MethodGet, listTasks(b, V1))
|
|
addRoute(r, provider, "/{connectorID}/tasks/{taskID}", http.MethodGet, readTask(b, V1))
|
|
|
|
// Deprecated routes
|
|
addRoute(r, provider, "", http.MethodDelete, uninstall(b, V0))
|
|
addRoute(r, provider, "/config", http.MethodGet, readConfig(b, V0))
|
|
addRoute(r, provider, "/reset", http.MethodPost, reset(b, V0))
|
|
addRoute(r, provider, "/tasks", http.MethodGet, listTasks(b, V0))
|
|
addRoute(r, provider, "/tasks/{taskID}", http.MethodGet, readTask(b, V0))
|
|
|
|
return r
|
|
}
|
|
|
|
func webhookConnectorRouter[Config models.ConnectorConfigObject](
|
|
provider models.ConnectorProvider,
|
|
connectorRouter *mux.Router,
|
|
b backend.ManagerBackend[Config],
|
|
) *mux.Router {
|
|
if connectorRouter == nil {
|
|
return nil
|
|
}
|
|
|
|
r := mux.NewRouter()
|
|
|
|
group := r.PathPrefix("/webhooks/" + provider.String() + "/{connectorID}").Subrouter()
|
|
group.Use(webhooksMiddleware(b, V1))
|
|
addWebhookRoute(group, connectorRouter)
|
|
|
|
groupLower := r.PathPrefix("/webhooks/" + provider.StringLower() + "/{connectorID}").Subrouter()
|
|
groupLower.Use(webhooksMiddleware(b, V1))
|
|
addWebhookRoute(groupLower, connectorRouter)
|
|
|
|
return r
|
|
}
|
|
|
|
func addRoute(r *mux.Router, provider models.ConnectorProvider, path, method string, handler http.Handler) {
|
|
r.Path("/" + provider.String() + path).Methods(method).Handler(handler)
|
|
r.Path("/" + provider.StringLower() + path).Methods(method).Handler(handler)
|
|
}
|
|
|
|
func addWebhookRoute(r *mux.Router, subRouter *mux.Router) {
|
|
subRouter.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
|
pathTemplate, err := route.GetPathTemplate()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
methods, err := route.GetMethods()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, method := range methods {
|
|
r.Path(pathTemplate).Methods(method).Handler(route.GetHandler())
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|