Repository: owncloud/ocis
Pull request #10323 (2024-10-16 18:27:16)

enhancement: simplify ready and health check handler usage
## Description
WIP

## Related Issue
-  https://github.com/owncloud/ocis/issues/10281

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
- test environment:
- test case 1:
- test case 2:
- ...

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [ ] Code changes
- [ ] Unit tests added
- [ ] Acceptance tests added
- [ ] Documentation ticket raised: <link> 



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ac72e21deb..f960e7026b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -60,7 +60,6 @@ The following sections list the changes for unreleased.
 * Bugfix - Continue listing shares on error: [#10243](https://github.com/owncloud/ocis/pull/10243)
 * Bugfix - Avoid re-creating thumbnails: [#10251](https://github.com/owncloud/ocis/pull/10251)
 * Bugfix - Thumbnail request limit: [#10280](https://github.com/owncloud/ocis/pull/10280)
-* Bugfix - Use secure config defaults for OCM: [#10307](https://github.com/owncloud/ocis/pull/10307)
 * Enhancement - Add OCM wellknown configuration: [#9815](https://github.com/owncloud/ocis/pull/9815)
 * Enhancement - Bump reva to 2.xx.x: [#10236](https://github.com/owncloud/ocis/pull/10236)
 * Enhancement - Load IDP logo from theme: [#10274](https://github.com/owncloud/ocis/pull/10274)
@@ -107,10 +106,6 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/pull/10280
    https://github.com/owncloud/ocis/pull/10225
 
-* Bugfix - Use secure config defaults for OCM: [#10307](https://github.com/owncloud/ocis/pull/10307)
-
-   https://github.com/owncloud/ocis/pull/10307
-
 * Enhancement - Add OCM wellknown configuration: [#9815](https://github.com/owncloud/ocis/pull/9815)
 
    We now configure the `wellknown` service for OCM.
diff --git a/changelog/unreleased/secure-ocm-by-default.md b/changelog/unreleased/secure-ocm-by-default.md
deleted file mode 100644
index d7948432ad5..00000000000
--- a/changelog/unreleased/secure-ocm-by-default.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix: use secure config defaults for OCM
-
-https://github.com/owncloud/ocis/pull/10307
-
diff --git a/ocis-pkg/handlers/checkgrpc.go b/ocis-pkg/checks/checkgrpc.go
similarity index 83%
rename from ocis-pkg/handlers/checkgrpc.go
rename to ocis-pkg/checks/checkgrpc.go
index 5018f42349f..5690c67def7 100644
--- a/ocis-pkg/handlers/checkgrpc.go
+++ b/ocis-pkg/checks/checkgrpc.go
@@ -1,4 +1,4 @@
-package handlers
+package checks
 
 import (
 	"context"
@@ -10,7 +10,7 @@ import (
 )
 
 // NewGRPCCheck checks the reachability of a grpc server.
-func NewGRPCCheck(address string) func(ctx context.Context) error {
+func NewGRPCCheck(address string) func(context.Context) error {
 	return func(_ context.Context) error {
 		conn, err := grpc.NewClient(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
 		if err != nil {
diff --git a/ocis-pkg/handlers/checkhttp.go b/ocis-pkg/checks/checkhttp.go
similarity index 82%
rename from ocis-pkg/handlers/checkhttp.go
rename to ocis-pkg/checks/checkhttp.go
index a2af7c14cf7..462749fb87b 100644
--- a/ocis-pkg/handlers/checkhttp.go
+++ b/ocis-pkg/checks/checkhttp.go
@@ -1,4 +1,4 @@
-package handlers
+package checks
 
 import (
 	"context"
@@ -7,7 +7,7 @@ import (
 	"time"
 )
 
-// NewHttpCheck checks the reachability of a http server.
+// NewHTTPCheck checks the reachability of a http server.
 func NewHTTPCheck(url string) func(context.Context) error {
 	return func(_ context.Context) error {
 		c := http.Client{
diff --git a/ocis-pkg/handlers/checknats.go b/ocis-pkg/checks/checknats.go
similarity index 96%
rename from ocis-pkg/handlers/checknats.go
rename to ocis-pkg/checks/checknats.go
index 7eba98e9067..0424942c5fa 100644
--- a/ocis-pkg/handlers/checknats.go
+++ b/ocis-pkg/checks/checknats.go
@@ -1,4 +1,4 @@
-package handlers
+package checks
 
 import (
 	"context"
diff --git a/ocis-pkg/handlers/checktcp.go b/ocis-pkg/checks/checktcp.go
similarity index 79%
rename from ocis-pkg/handlers/checktcp.go
rename to ocis-pkg/checks/checktcp.go
index 0db97bfabf8..475ff50e825 100644
--- a/ocis-pkg/handlers/checktcp.go
+++ b/ocis-pkg/checks/checktcp.go
@@ -1,4 +1,4 @@
-package handlers
+package checks
 
 import (
 	"context"
@@ -7,7 +7,7 @@ import (
 )
 
 // NewTCPCheck returns a check that connects to a given tcp endpoint.
-func NewTCPCheck(address string) func(ctx context.Context) error {
+func NewTCPCheck(address string) func(context.Context) error {
 	return func(_ context.Context) error {
 		conn, err := net.DialTimeout("tcp", address, 3*time.Second)
 		if err != nil {
diff --git a/ocis-pkg/handlers/checker.go b/ocis-pkg/handlers/checker.go
index d8902897898..76e1399fafb 100644
--- a/ocis-pkg/handlers/checker.go
+++ b/ocis-pkg/handlers/checker.go
@@ -13,12 +13,14 @@ import (
 )
 
 // check is a function that performs a check.
-type check func(ctx context.Context) error
+type checker func(ctx context.Context) error
+
+// checks is a map of check names to check functions.
+type checkers map[string]func(ctx context.Context) error
 
 // CheckHandlerConfiguration defines the configuration for the CheckHandler.
 type CheckHandlerConfiguration struct {
-	Checks map[string]check
-
+	checks        checkers
 	logger        log.Logger
 	limit         int
 	statusFailed  int
@@ -28,7 +30,7 @@ type CheckHandlerConfiguration struct {
 // NewCheckHandlerConfiguration initializes a new CheckHandlerConfiguration.
 func NewCheckHandlerConfiguration() CheckHandlerConfiguration {
 	return CheckHandlerConfiguration{
-		Checks: make(map[string]check),
+		checks: make(checkers),
 
 		limit:         -1,
 		statusFailed:  http.StatusInternalServerError,
@@ -43,19 +45,21 @@ func (c CheckHandlerConfiguration) WithLogger(l log.Logger) CheckHandlerConfigur
 }
 
 // WithCheck sets a check for the CheckHandlerConfiguration.
-func (c CheckHandlerConfiguration) WithCheck(name string, f check) CheckHandlerConfiguration {
-	if _, ok := c.Checks[name]; ok {
+func (c CheckHandlerConfiguration) WithCheck(name string, check checker) CheckHandlerConfiguration {
+	if _, ok := c.checks[name]; ok {
 		c.logger.Panic().Str("check", name).Msg("check already exists")
 	}
 
-	c.Checks[name] = f
+	c.checks = maps.Clone(c.checks) // prevent propagated check duplication, maps are references;
+	c.checks[name] = check
+
 	return c
 }
 
-// WithInheritedChecksFrom appends the checks from another CheckHandlerConfiguration.
-func (c CheckHandlerConfiguration) WithInheritedChecksFrom(other CheckHandlerConfiguration) CheckHandlerConfiguration {
-	for name, check := range other.Checks {
-		c.WithCheck(name, check)
+// WithChecks adds multiple checks to the CheckHandlerConfiguration.
+func (c CheckHandlerConfiguration) WithChecks(checks checkers) CheckHandlerConfiguration {
+	for name, check := range checks {
+		c.checks = c.WithCheck(name, check).checks
 	}
 
 	return c
@@ -81,27 +85,26 @@ func (c CheckHandlerConfiguration) WithStatusSuccess(status int) CheckHandlerCon
 
 // CheckHandler is a http Handler that performs different checks.
 type CheckHandler struct {
-	Conf CheckHandlerConfiguration
+	conf CheckHandlerConfiguration
 }
 
 // NewCheckHandler initializes a new CheckHandler.
 func NewCheckHandler(c CheckHandlerConfiguration) *CheckHandler {
-	c.Checks = maps.Clone(c.Checks) // prevent check duplication after initialization
+	c.checks = maps.Clone(c.checks) // prevent check duplication after initialization
 	return &CheckHandler{
-		Conf: c,
+		conf: c,
 	}
 }
 
-// AddCheck adds a check to the CheckHandler.
-func (h *CheckHandler) AddCheck(name string, c check) {
-	h.Conf.WithCheck(name, c)
+func (h *CheckHandler) Checks() map[string]func(ctx context.Context) error {
+	return maps.Clone(h.conf.checks)
 }
 
 func (h *CheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	g, ctx := errgroup.WithContext(r.Context())
-	g.SetLimit(h.Conf.limit)
+	g.SetLimit(h.conf.limit)
 
-	for name, check := range h.Conf.Checks {
+	for name, check := range h.conf.checks {
 		checker := check
 		checkerName := name
 		g.Go(func() error { // https://go.dev/blog/loopvar-preview per iteration scope since go 1.22
@@ -113,16 +116,16 @@ func (h *CheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		})
 	}
 
-	status := h.Conf.statusSuccess
+	status := h.conf.statusSuccess
 	if err := g.Wait(); err != nil {
-		status = h.Conf.statusFailed
-		h.Conf.logger.Error().Err(err).Msg("check failed")
+		status = h.conf.statusFailed
+		h.conf.logger.Error().Err(err).Msg("check failed")
 	}
 
 	w.Header().Set("Content-Type", "text/plain")
 	w.WriteHeader(status)
 
 	if _, err := io.WriteString(w, http.StatusText(status)); err != nil { // io.WriteString should not fail, but if it does, we want to know.
-		h.Conf.logger.Panic().Err(err).Msg("failed to write response")
+		h.conf.logger.Panic().Err(err).Msg("failed to write response")
 	}
 }
diff --git a/services/activitylog/pkg/server/debug/server.go b/services/activitylog/pkg/server/debug/server.go
index 20a332f7863..60c1c697e1e 100644
--- a/services/activitylog/pkg/server/debug/server.go
+++ b/services/activitylog/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,14 +16,14 @@ func Server(opts ...Option) (*http.Server, error) {
 	healthHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("http reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("http reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
-			WithInheritedChecksFrom(healthHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
+			WithChecks(healthHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/antivirus/pkg/server/debug/server.go b/services/antivirus/pkg/server/debug/server.go
index 73009607de3..60f69cd06e5 100644
--- a/services/antivirus/pkg/server/debug/server.go
+++ b/services/antivirus/pkg/server/debug/server.go
@@ -6,6 +6,8 @@ import (
 	"net/http"
 
 	"github.com/dutchcoders/go-clamd"
+
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -23,7 +25,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
 			WithCheck("antivirus reachability", func(ctx context.Context) error {
 				cfg := options.Config
 				switch cfg.Scanner.Type {
@@ -32,7 +34,7 @@ func Server(opts ...Option) (*http.Server, error) {
 				case "clamav":
 					return clamd.NewClamd(cfg.Scanner.ClamAV.Socket).Ping()
 				case "icap":
-					return handlers.NewTCPCheck(cfg.Scanner.ICAP.URL)(ctx)
+					return checks.NewTCPCheck(cfg.Scanner.ICAP.URL)(ctx)
 				}
 			}),
 	)
diff --git a/services/audit/pkg/server/debug/server.go b/services/audit/pkg/server/debug/server.go
index f1599e0f7b2..c00ee35b2c3 100644
--- a/services/audit/pkg/server/debug/server.go
+++ b/services/audit/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -20,8 +21,8 @@ func Server(opts ...Option) (*http.Server, error) {
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/clientlog/pkg/server/debug/server.go b/services/clientlog/pkg/server/debug/server.go
index f1599e0f7b2..c00ee35b2c3 100644
--- a/services/clientlog/pkg/server/debug/server.go
+++ b/services/clientlog/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -20,8 +21,8 @@ func Server(opts ...Option) (*http.Server, error) {
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/eventhistory/pkg/server/debug/server.go b/services/eventhistory/pkg/server/debug/server.go
index e2bb0946626..b0f8386b543 100644
--- a/services/eventhistory/pkg/server/debug/server.go
+++ b/services/eventhistory/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,14 +16,14 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("grpc reachability", handlers.NewGRPCCheck(options.Config.GRPC.Addr)),
+			WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr)),
 	)
 
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/frontend/pkg/command/health.go b/services/frontend/pkg/command/health.go
index 041dea70a3b..5f39b3bd305 100644
--- a/services/frontend/pkg/command/health.go
+++ b/services/frontend/pkg/command/health.go
@@ -1,14 +1,16 @@
 package command
 
 import (
+	"errors"
 	"fmt"
 	"net/http"
 
+	"github.com/urfave/cli/v2"
+
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
 	"github.com/owncloud/ocis/v2/services/frontend/pkg/config"
 	"github.com/owncloud/ocis/v2/services/frontend/pkg/config/parser"
 	"github.com/owncloud/ocis/v2/services/frontend/pkg/logging"
-	"github.com/urfave/cli/v2"
 )
 
 // Health is the entrypoint for the health command.
@@ -30,6 +32,10 @@ func Health(cfg *config.Config) *cli.Command {
 				),
 			)
 
+			if resp.StatusCode != http.StatusOK {
+				err = errors.New("foo")
+			}
+
 			if err != nil {
 				logger.Fatal().
 					Err(err).
diff --git a/services/graph/pkg/server/debug/server.go b/services/graph/pkg/server/debug/server.go
index 8d1462a72ac..5db859a866f 100644
--- a/services/graph/pkg/server/debug/server.go
+++ b/services/graph/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,7 +16,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/idp/pkg/server/debug/server.go b/services/idp/pkg/server/debug/server.go
index 2c55b5de5d9..6ff3ce29681 100644
--- a/services/idp/pkg/server/debug/server.go
+++ b/services/idp/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,14 +16,14 @@ func Server(opts ...Option) (*http.Server, error) {
 	healthHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("http reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("http reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	readinessHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("ldap-check", handlers.NewTCPCheck(options.Config.Ldap.URI)).
-			WithInheritedChecksFrom(healthHandler.Conf),
+			WithCheck("ldap-check", checks.NewTCPCheck(options.Config.Ldap.URI)).
+			WithChecks(healthHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/invitations/pkg/server/debug/server.go b/services/invitations/pkg/server/debug/server.go
index 99179d7d48b..4a831899dd5 100644
--- a/services/invitations/pkg/server/debug/server.go
+++ b/services/invitations/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,7 +16,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/nats/pkg/server/debug/server.go b/services/nats/pkg/server/debug/server.go
index 18048620abf..e133a8bdd23 100644
--- a/services/nats/pkg/server/debug/server.go
+++ b/services/nats/pkg/server/debug/server.go
@@ -4,6 +4,7 @@ import (
 	"net/http"
 	"strconv"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -18,7 +19,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Nats.Host+":"+strconv.Itoa(options.Config.Nats.Port))),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Nats.Host+":"+strconv.Itoa(options.Config.Nats.Port))),
 	)
 
 	return debug.NewService(
diff --git a/services/notifications/pkg/server/debug/server.go b/services/notifications/pkg/server/debug/server.go
index 8a71ca3cdd0..6029bfeb610 100644
--- a/services/notifications/pkg/server/debug/server.go
+++ b/services/notifications/pkg/server/debug/server.go
@@ -4,6 +4,7 @@ import (
 	"net/http"
 	"strconv"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -21,9 +22,9 @@ func Server(opts ...Option) (*http.Server, error) {
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Notifications.Events.Cluster)).
-			WithCheck("smtp-check", handlers.NewTCPCheck(options.Config.Notifications.SMTP.Host+":"+strconv.Itoa(options.Config.Notifications.SMTP.Port))).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Notifications.Events.Cluster)).
+			WithCheck("smtp-check", checks.NewTCPCheck(options.Config.Notifications.SMTP.Host+":"+strconv.Itoa(options.Config.Notifications.SMTP.Port))).
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/ocm/pkg/config/defaults/defaultconfig.go b/services/ocm/pkg/config/defaults/defaultconfig.go
index 34fec3570e8..1b4cdae30c5 100644
--- a/services/ocm/pkg/config/defaults/defaultconfig.go
+++ b/services/ocm/pkg/config/defaults/defaultconfig.go
@@ -109,8 +109,7 @@ func DefaultConfig() *config.Config {
 		OCMProviderAuthorizerDriver: "json",
 		OCMProviderAuthorizerDrivers: config.OCMProviderAuthorizerDrivers{
 			JSON: config.OCMProviderAuthorizerJSONDriver{
-				Providers:             filepath.Join(defaults.BaseConfigPath(), "ocmproviders.json"),
-				VerifyRequestHostname: true,
+				Providers: filepath.Join(defaults.BaseConfigPath(), "ocmproviders.json"),
 			},
 		},
 		OCMShareProvider: config.OCMShareProvider{
diff --git a/services/ocs/pkg/server/debug/server.go b/services/ocs/pkg/server/debug/server.go
index 99179d7d48b..4a831899dd5 100644
--- a/services/ocs/pkg/server/debug/server.go
+++ b/services/ocs/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,7 +16,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/proxy/pkg/server/debug/server.go b/services/proxy/pkg/server/debug/server.go
index 216135910a6..9d13cdf8ebf 100644
--- a/services/proxy/pkg/server/debug/server.go
+++ b/services/proxy/pkg/server/debug/server.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/ggwhite/go-masker"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -19,7 +20,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	var configDumpFunc http.HandlerFunc = configDump(options.Config)
diff --git a/services/search/pkg/server/debug/server.go b/services/search/pkg/server/debug/server.go
index 6d7bbd4740f..4d4a02c628b 100644
--- a/services/search/pkg/server/debug/server.go
+++ b/services/search/pkg/server/debug/server.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -16,20 +17,20 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("grpc reachability", handlers.NewGRPCCheck(options.Config.GRPC.Addr)),
+			WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr)),
 	)
 
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
 			WithCheck("tika-check", func(ctx context.Context) error {
 				if options.Config.Extractor.Type == "tika" {
-					return handlers.NewTCPCheck(options.Config.Extractor.Tika.TikaURL)(ctx)
+					return checks.NewTCPCheck(options.Config.Extractor.Tika.TikaURL)(ctx)
 				}
 				return nil
 			}).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/settings/pkg/server/debug/server.go b/services/settings/pkg/server/debug/server.go
index 242b1bfd044..6fbab113b11 100644
--- a/services/settings/pkg/server/debug/server.go
+++ b/services/settings/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,8 +16,8 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)).
-			WithCheck("grpc reachability", handlers.NewGRPCCheck(options.Config.GRPC.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)).
+			WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/sse/pkg/server/debug/server.go b/services/sse/pkg/server/debug/server.go
index de871207661..b972acc39fe 100644
--- a/services/sse/pkg/server/debug/server.go
+++ b/services/sse/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,14 +16,14 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/thumbnails/pkg/server/debug/server.go b/services/thumbnails/pkg/server/debug/server.go
index 242b1bfd044..6fbab113b11 100644
--- a/services/thumbnails/pkg/server/debug/server.go
+++ b/services/thumbnails/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,8 +16,8 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)).
-			WithCheck("grpc reachability", handlers.NewGRPCCheck(options.Config.GRPC.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)).
+			WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/userlog/pkg/server/debug/server.go b/services/userlog/pkg/server/debug/server.go
index de871207661..b972acc39fe 100644
--- a/services/userlog/pkg/server/debug/server.go
+++ b/services/userlog/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,14 +16,14 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	readyHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
-			WithInheritedChecksFrom(checkHandler.Conf),
+			WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
+			WithChecks(checkHandler.Checks()),
 	)
 
 	return debug.NewService(
diff --git a/services/web/pkg/server/debug/server.go b/services/web/pkg/server/debug/server.go
index 77810811d17..1206cd78b7b 100644
--- a/services/web/pkg/server/debug/server.go
+++ b/services/web/pkg/server/debug/server.go
@@ -1,10 +1,12 @@
 package debug
 
 import (
+	"net/http"
+
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
-	"net/http"
 )
 
 // Server initializes the debug service and server.
@@ -13,7 +15,7 @@ func Server(opts ...Option) (*http.Server, error) {
 
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
-			WithLogger(options.Logger).WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithLogger(options.Logger).WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/webdav/pkg/server/debug/server.go b/services/webdav/pkg/server/debug/server.go
index 99179d7d48b..4a831899dd5 100644
--- a/services/webdav/pkg/server/debug/server.go
+++ b/services/webdav/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,7 +16,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	return debug.NewService(
diff --git a/services/webfinger/pkg/server/debug/server.go b/services/webfinger/pkg/server/debug/server.go
index 99179d7d48b..4a831899dd5 100644
--- a/services/webfinger/pkg/server/debug/server.go
+++ b/services/webfinger/pkg/server/debug/server.go
@@ -3,6 +3,7 @@ package debug
 import (
 	"net/http"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/checks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
@@ -15,7 +16,7 @@ func Server(opts ...Option) (*http.Server, error) {
 	checkHandler := handlers.NewCheckHandler(
 		handlers.NewCheckHandlerConfiguration().
 			WithLogger(options.Logger).
-			WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
+			WithCheck("web reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
 	)
 
 	return debug.NewService(


Test patch:
diff --git a/ocis-pkg/handlers/checker_test.go b/ocis-pkg/handlers/checker_test.go
index 0c5cadb28d6..794486a2933 100644
--- a/ocis-pkg/handlers/checker_test.go
+++ b/ocis-pkg/handlers/checker_test.go
@@ -1,29 +1,127 @@
 package handlers_test
 
 import (
+	"bytes"
 	"context"
-	"fmt"
+	"errors"
+	"net/http"
+	"net/http/httptest"
+	"slices"
 	"testing"
 
+	"github.com/test-go/testify/require"
+	"github.com/tidwall/gjson"
+
 	"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 )
 
-func TestCheckHandler_AddCheck(t *testing.T) {
-	c := handlers.NewCheckHandlerConfiguration().WithCheck("shared-check", func(ctx context.Context) error { return nil })
+func TestCheckHandlerConfiguration(t *testing.T) {
+	nopCheck := func(_ context.Context) error { return nil }
+	handlerConfiguration := handlers.NewCheckHandlerConfiguration().WithCheck("check-1", nopCheck)
+
+	t.Run("add check", func(t *testing.T) {
+		inheritedHandlerConfiguration := handlerConfiguration.WithCheck("check-2", nopCheck)
+		require.Equal(t, 1, len(handlers.NewCheckHandler(handlerConfiguration).Checks()))
+		require.Equal(t, 2, len(handlers.NewCheckHandler(inheritedHandlerConfiguration).Checks()))
+	})
+
+	t.Run("add checks", func(t *testing.T) {
+		inheritedHandlerConfiguration := handlerConfiguration.WithChecks(map[string]func(ctx context.Context) error{"check-2": nopCheck, "check-3": nopCheck})
+		require.Equal(t, 1, len(handlers.NewCheckHandler(handlerConfiguration).Checks()))
+		require.Equal(t, 3, len(handlers.NewCheckHandler(inheritedHandlerConfiguration).Checks()))
+	})
 
-	t.Run("configured checks are unique once added", func(t *testing.T) {
+	t.Run("checks are unique", func(t *testing.T) {
 		defer func() {
-			if r := recover(); r != nil {
-				t.Errorf("checks should be unique, got %v", r)
+			if r := recover(); r == nil {
+				t.Error("checks should be unique")
 			}
 		}()
 
-		h1 := handlers.NewCheckHandler(c)
-		h1.AddCheck("check-with-same-name", func(ctx context.Context) error { return nil })
+		handlerConfiguration.WithCheck("check-1", nopCheck)
+	})
+}
+
+func TestCheckHandler(t *testing.T) {
+	checkFactory := func(err error) func(ctx context.Context) error {
+		return func(ctx context.Context) error {
+			if err != nil {
+				return err
+			}
+
+			<-ctx.Done()
+			return nil
+		}
+	}
+
+	t.Run("passes with custom status", func(t *testing.T) {
+		rec := httptest.NewRecorder()
+		handler := handlers.NewCheckHandler(
+			handlers.
+				NewCheckHandlerConfiguration().
+				WithStatusSuccess(http.StatusCreated),
+		)
+
+		handler.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
+		require.Equal(t, http.StatusCreated, rec.Code)
+		require.Equal(t, http.StatusText(http.StatusCreated), rec.Body.String())
+	})
+
+	t.Run("is not ok if any check fails", func(t *testing.T) {
+		rec := httptest.NewRecorder()
+		handler := handlers.NewCheckHandler(
+			handlers.
+				NewCheckHandlerConfiguration().
+				WithCheck("check-1", checkFactory(errors.New("failed"))),
+		)
+		handler.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
+		require.Equal(t, http.StatusInternalServerError, rec.Code)
+		require.Equal(t, http.StatusText(http.StatusInternalServerError), rec.Body.String())
+	})
+
+	t.Run("fails with custom status", func(t *testing.T) {
+		rec := httptest.NewRecorder()
+		handler := handlers.NewCheckHandler(
+			handlers.
+				NewCheckHandlerConfiguration().
+				WithCheck("check-1", checkFactory(errors.New("failed"))).
+				WithStatusFailed(http.StatusTeapot),
+		)
+		handler.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
+		require.Equal(t, http.StatusTeapot, rec.Code)
+		require.Equal(t, http.StatusText(http.StatusTeapot), rec.Body.String())
+	})
 
-		h2 := handlers.NewCheckHandler(c)
-		h2.AddCheck("check-with-same-name", func(ctx context.Context) error { return nil })
+	t.Run("exits all other running tests on failure", func(t *testing.T) {
+		var errs []error
+		rec := httptest.NewRecorder()
+		buffer := &bytes.Buffer{}
+		logger := log.Logger{Logger: log.NewLogger().Output(buffer)}
+		handler := handlers.NewCheckHandler(
+			handlers.
+				NewCheckHandlerConfiguration().
+				WithLogger(logger).
+				WithCheck("check-1", func(ctx context.Context) error {
+					err := checkFactory(nil)(ctx)
+					errs = append(errs, err)
+					return err
+				}).
+				WithCheck("check-2", func(ctx context.Context) error {
+					err := checkFactory(errors.New("failed"))(ctx)
+					errs = append(errs, err)
+					return err
+				}).
+				WithCheck("check-3", func(ctx context.Context) error {
+					err := checkFactory(nil)(ctx)
+					errs = append(errs, err)
+					return err
+				}),
+		)
+		handler.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
 
-		fmt.Print(1)
+		require.Equal(t, "'check-2': failed", gjson.Get(buffer.String(), "error").String())
+		require.Equal(t, 1, len(slices.DeleteFunc(errs, func(err error) bool { return err == nil })))
+		require.Equal(t, 2, len(slices.DeleteFunc(errs, func(err error) bool { return err != nil })))
 	})
 }