diff --git a/client/cmd/testutil_test.go b/client/cmd/testutil_test.go index c24965e8d..205327ef5 100644 --- a/client/cmd/testutil_test.go +++ b/client/cmd/testutil_test.go @@ -11,7 +11,7 @@ import ( "go.opentelemetry.io/otel" "google.golang.org/grpc" - "github.com/netbirdio/management-integrations/integrations" + "github.com/netbirdio/netbird/management/server/integrations/integrated_validator/validator" nbcache "github.com/netbirdio/netbird/management/server/cache" @@ -109,7 +109,7 @@ func startManagement(t *testing.T, config *config.Config, testFile string) (*grp t.Fatal(err) } - iv, _ := integrations.NewIntegratedValidator(ctx, peersmanager, settingsManagerMock, eventStore, cacheStore) + iv, _ := validator.NewIntegratedValidator(ctx, peersmanager, settingsManagerMock, eventStore, cacheStore) metrics, err := telemetry.NewDefaultAppMetrics(ctx) require.NoError(t, err) diff --git a/client/internal/engine_test.go b/client/internal/engine_test.go index 834a49a09..289f1906f 100644 --- a/client/internal/engine_test.go +++ b/client/internal/engine_test.go @@ -27,7 +27,7 @@ import ( "github.com/netbirdio/netbird/client/internal/stdnet" "github.com/netbirdio/netbird/management/server/job" - "github.com/netbirdio/management-integrations/integrations" + "github.com/netbirdio/netbird/management/server/integrations/integrated_validator/validator" "github.com/netbirdio/netbird/management/internals/controllers/network_map/controller" "github.com/netbirdio/netbird/management/internals/controllers/network_map/update_channel" @@ -66,8 +66,8 @@ import ( "github.com/netbirdio/netbird/route" mgmt "github.com/netbirdio/netbird/shared/management/client" mgmtProto "github.com/netbirdio/netbird/shared/management/proto" - relayClient "github.com/netbirdio/netbird/shared/relay/client" "github.com/netbirdio/netbird/shared/netiputil" + relayClient "github.com/netbirdio/netbird/shared/relay/client" signal "github.com/netbirdio/netbird/shared/signal/client" "github.com/netbirdio/netbird/shared/signal/proto" signalServer "github.com/netbirdio/netbird/signal/server" @@ -1641,7 +1641,7 @@ func startManagement(t *testing.T, dataDir, testFile string) (*grpc.Server, stri return nil, "", err } - ia, _ := integrations.NewIntegratedValidator(context.Background(), peersManager, nil, eventStore, cacheStore) + ia, _ := validator.NewIntegratedValidator(context.Background(), peersManager, nil, eventStore, cacheStore) metrics, err := telemetry.NewDefaultAppMetrics(context.Background()) require.NoError(t, err) diff --git a/client/server/server_test.go b/client/server/server_test.go index 641cd85fe..66e0fcc4c 100644 --- a/client/server/server_test.go +++ b/client/server/server_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" - "github.com/netbirdio/management-integrations/integrations" + "github.com/netbirdio/netbird/management/server/integrations/integrated_validator/validator" "github.com/netbirdio/netbird/management/internals/controllers/network_map/controller" "github.com/netbirdio/netbird/management/internals/controllers/network_map/update_channel" @@ -315,7 +315,7 @@ func startManagement(t *testing.T, signalAddr string, counter *int) (*grpc.Serve return nil, "", err } - ia, _ := integrations.NewIntegratedValidator(context.Background(), peersManager, settingsManagerMock, eventStore, cacheStore) + ia, _ := validator.NewIntegratedValidator(context.Background(), peersManager, settingsManagerMock, eventStore, cacheStore) metrics, err := telemetry.NewDefaultAppMetrics(context.Background()) require.NoError(t, err) diff --git a/combined/cmd/root.go b/combined/cmd/root.go index db986b4d4..78290388b 100644 --- a/combined/cmd/root.go +++ b/combined/cmd/root.go @@ -332,7 +332,7 @@ func setupServerHooks(servers *serverInstances, cfg *CombinedConfig) { log.Infof("Signal server registered on port %s", cfg.Server.ListenAddress) } - s.SetHandlerFunc(createCombinedHandler(grpcSrv, s.APIHandler(), servers.relaySrv, servers.metricsServer.Meter, cfg)) + s.SetHandlerFunc(createCombinedHandler(grpcSrv, s.APIHandler(), s.IDPHandler(), servers.relaySrv, servers.metricsServer.Meter, cfg)) if servers.relaySrv != nil { log.Infof("Relay WebSocket handler added (path: /relay)") } @@ -521,7 +521,7 @@ func createManagementServer(cfg *CombinedConfig, mgmtConfig *nbconfig.Config) (* } // createCombinedHandler creates an HTTP handler that multiplexes Management, Signal (via wsproxy), and Relay WebSocket traffic -func createCombinedHandler(grpcServer *grpc.Server, httpHandler http.Handler, relaySrv *relayServer.Server, meter metric.Meter, cfg *CombinedConfig) http.Handler { +func createCombinedHandler(grpcServer *grpc.Server, httpHandler http.Handler, idpHandler http.Handler, relaySrv *relayServer.Server, meter metric.Meter, cfg *CombinedConfig) http.Handler { wsProxy := wsproxyserver.New(grpcServer, wsproxyserver.WithOTelMeter(meter)) var relayAcceptFn func(conn listener.Conn) @@ -556,6 +556,10 @@ func createCombinedHandler(grpcServer *grpc.Server, httpHandler http.Handler, re http.Error(w, "Relay service not enabled", http.StatusNotFound) } + // Embedded IdP (Dex) + case idpHandler != nil && strings.HasPrefix(r.URL.Path, "/oauth2"): + idpHandler.ServeHTTP(w, r) + // Management HTTP API (default) default: httpHandler.ServeHTTP(w, r) diff --git a/management/internals/server/boot.go b/management/internals/server/boot.go index 7c655f020..46e475143 100644 --- a/management/internals/server/boot.go +++ b/management/internals/server/boot.go @@ -10,8 +10,10 @@ import ( "slices" "time" + "github.com/gorilla/mux" grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware/v2" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip" + "github.com/rs/cors" "github.com/rs/xid" log "github.com/sirupsen/logrus" "google.golang.org/grpc" @@ -19,7 +21,6 @@ import ( "google.golang.org/grpc/keepalive" cachestore "github.com/eko/gocache/lib/v4/store" - "github.com/netbirdio/management-integrations/integrations" "github.com/netbirdio/netbird/encryption" "github.com/netbirdio/netbird/formatter/hook" @@ -27,16 +28,20 @@ import ( accesslogsmanager "github.com/netbirdio/netbird/management/internals/modules/reverseproxy/accesslogs/manager" nbgrpc "github.com/netbirdio/netbird/management/internals/shared/grpc" "github.com/netbirdio/netbird/management/server/activity" + activitystore "github.com/netbirdio/netbird/management/server/activity/store" nbcache "github.com/netbirdio/netbird/management/server/cache" nbContext "github.com/netbirdio/netbird/management/server/context" nbhttp "github.com/netbirdio/netbird/management/server/http" "github.com/netbirdio/netbird/management/server/http/middleware" + "github.com/netbirdio/netbird/management/server/idp" "github.com/netbirdio/netbird/management/server/store" "github.com/netbirdio/netbird/management/server/telemetry" mgmtProto "github.com/netbirdio/netbird/shared/management/proto" "github.com/netbirdio/netbird/util/crypt" ) +const apiPrefix = "/api" + var ( kaep = keepalive.EnforcementPolicy{ MinTime: 15 * time.Second, @@ -94,12 +99,17 @@ func (s *BaseServer) Store() store.Store { func (s *BaseServer) EventStore() activity.Store { return Create(s, func() activity.Store { - integrationMetrics, err := integrations.InitIntegrationMetrics(context.Background(), s.Metrics()) - if err != nil { - log.Fatalf("failed to initialize integration metrics: %v", err) + var err error + key := s.Config.DataStoreEncryptionKey + if key == "" { + log.Debugf("generate new activity store encryption key") + key, err = crypt.GenerateKey() + if err != nil { + log.Fatalf("failed to generate event store encryption key: %v", err) + } } - eventStore, _, err := integrations.InitEventStore(context.Background(), s.Config.Datadir, s.Config.DataStoreEncryptionKey, integrationMetrics) + eventStore, err := activitystore.NewSqlStore(context.Background(), s.Config.Datadir, key) if err != nil { log.Fatalf("failed to initialize event store: %v", err) } @@ -110,7 +120,7 @@ func (s *BaseServer) EventStore() activity.Store { func (s *BaseServer) APIHandler() http.Handler { return Create(s, func() http.Handler { - httpAPIHandler, err := nbhttp.NewAPIHandler(context.Background(), s.AccountManager(), s.NetworksManager(), s.ResourcesManager(), s.RoutesManager(), s.GroupsManager(), s.GeoLocationManager(), s.AuthManager(), s.Metrics(), s.IntegratedValidator(), s.ProxyController(), s.PermissionsManager(), s.PeersManager(), s.SettingsManager(), s.ZonesManager(), s.RecordsManager(), s.NetworkMapController(), s.IdpManager(), s.ServiceManager(), s.ReverseProxyDomainManager(), s.AccessLogsManager(), s.ReverseProxyGRPCServer(), s.Config.ReverseProxy.TrustedHTTPProxies, s.RateLimiter()) + httpAPIHandler, err := nbhttp.NewAPIHandler(context.Background(), s.Router(), s.AccountManager(), s.NetworksManager(), s.ResourcesManager(), s.RoutesManager(), s.GroupsManager(), s.GeoLocationManager(), s.AuthManager(), s.Metrics(), s.PermissionsManager(), s.SettingsManager(), s.ZonesManager(), s.RecordsManager(), s.NetworkMapController(), s.IdpManager(), s.ServiceManager(), s.ReverseProxyDomainManager(), s.AccessLogsManager(), s.ReverseProxyGRPCServer(), s.Config.ReverseProxy.TrustedHTTPProxies, s.RateLimiter(), s.IsValidChildAccount) if err != nil { log.Fatalf("failed to create API handler: %v", err) } @@ -118,6 +128,22 @@ func (s *BaseServer) APIHandler() http.Handler { }) } +// IDPHandler returns the HTTP handler for the embedded IdP (Dex), or nil if +// the deployment isn't using the embedded variant. +func (s *BaseServer) IDPHandler() http.Handler { + embeddedIdP, ok := s.IdpManager().(*idp.EmbeddedIdPManager) + if !ok || embeddedIdP == nil { + return nil + } + return cors.AllowAll().Handler(embeddedIdP.Handler()) +} + +func (s *BaseServer) Router() *mux.Router { + return Create(s, func() *mux.Router { + return mux.NewRouter().PathPrefix(apiPrefix).Subrouter() + }) +} + func (s *BaseServer) RateLimiter() *middleware.APIRateLimiter { return Create(s, func() *middleware.APIRateLimiter { cfg, enabled := middleware.RateLimiterConfigFromEnv() diff --git a/management/internals/server/controllers.go b/management/internals/server/controllers.go index 794c3ebe0..1b2556809 100644 --- a/management/internals/server/controllers.go +++ b/management/internals/server/controllers.go @@ -19,6 +19,7 @@ import ( "github.com/netbirdio/netbird/management/server" "github.com/netbirdio/netbird/management/server/auth" "github.com/netbirdio/netbird/management/server/integrations/integrated_validator" + "github.com/netbirdio/netbird/management/server/integrations/integrated_validator/validator" "github.com/netbirdio/netbird/management/server/integrations/port_forwarding" "github.com/netbirdio/netbird/management/server/job" nbjwt "github.com/netbirdio/netbird/shared/auth/jwt" @@ -38,7 +39,7 @@ func (s *BaseServer) JobManager() *job.Manager { func (s *BaseServer) IntegratedValidator() integrated_validator.IntegratedValidator { return Create(s, func() integrated_validator.IntegratedValidator { - integratedPeerValidator, err := integrations.NewIntegratedValidator( + integratedPeerValidator, err := validator.NewIntegratedValidator( context.Background(), s.PeersManager(), s.SettingsManager(), diff --git a/management/internals/server/modules.go b/management/internals/server/modules.go index ea94245d5..a70da855a 100644 --- a/management/internals/server/modules.go +++ b/management/internals/server/modules.go @@ -57,13 +57,7 @@ func (s *BaseServer) GeoLocationManager() geolocation.Geolocation { func (s *BaseServer) PermissionsManager() permissions.Manager { return Create(s, func() permissions.Manager { - manager := integrations.InitPermissionsManager(s.Store(), s.Metrics().GetMeter()) - - s.AfterInit(func(s *BaseServer) { - manager.SetAccountManager(s.AccountManager()) - }) - - return manager + return permissions.NewManager(s.Store()) }) } @@ -153,7 +147,6 @@ func (s *BaseServer) IdpManager() idp.Manager { return idpManager } - return nil }) } @@ -235,3 +228,7 @@ func (s *BaseServer) ReverseProxyDomainManager() *manager.Manager { return &m }) } + +func (s *BaseServer) IsValidChildAccount(_ context.Context, _, _, _ string) bool { + return false +} diff --git a/management/internals/server/server.go b/management/internals/server/server.go index 9b8716da1..63d13baab 100644 --- a/management/internals/server/server.go +++ b/management/internals/server/server.go @@ -188,7 +188,7 @@ func (s *BaseServer) Start(ctx context.Context) error { log.WithContext(srvCtx).Infof("running gRPC backward compatibility server: %s", compatListener.Addr().String()) } - rootHandler := s.handlerFunc(srvCtx, s.GRPCServer(), s.APIHandler(), s.Metrics().GetMeter()) + rootHandler := s.handlerFunc(srvCtx, s.GRPCServer(), s.APIHandler(), s.IDPHandler(), s.Metrics().GetMeter()) switch { case s.certManager != nil: // a call to certManager.Listener() always creates a new listener so we do it once @@ -299,7 +299,7 @@ func (s *BaseServer) SetHandlerFunc(handler http.Handler) { log.Tracef("custom handler set successfully") } -func (s *BaseServer) handlerFunc(_ context.Context, gRPCHandler *grpc.Server, httpHandler http.Handler, meter metric.Meter) http.Handler { +func (s *BaseServer) handlerFunc(_ context.Context, gRPCHandler *grpc.Server, httpHandler http.Handler, idpHandler http.Handler, meter metric.Meter) http.Handler { // Check if a custom handler was set (for multiplexing additional services) if customHandler, ok := s.GetContainer("customHandler"); ok { if handler, ok := customHandler.(http.Handler); ok { @@ -318,6 +318,8 @@ func (s *BaseServer) handlerFunc(_ context.Context, gRPCHandler *grpc.Server, ht gRPCHandler.ServeHTTP(writer, request) case request.URL.Path == wsproxy.ProxyPath+wsproxy.ManagementComponent: wsProxy.Handler().ServeHTTP(writer, request) + case idpHandler != nil && strings.HasPrefix(request.URL.Path, "/oauth2"): + idpHandler.ServeHTTP(writer, request) default: httpHandler.ServeHTTP(writer, request) } diff --git a/management/server/http/handler.go b/management/server/http/handler.go index 1e2c710db..0abdb854d 100644 --- a/management/server/http/handler.go +++ b/management/server/http/handler.go @@ -15,15 +15,13 @@ import ( "github.com/netbirdio/netbird/management/server/types" "github.com/netbirdio/netbird/management/internals/modules/reverseproxy/accesslogs" - "github.com/netbirdio/netbird/management/internals/modules/reverseproxy/service" "github.com/netbirdio/netbird/management/internals/modules/reverseproxy/proxytoken" + "github.com/netbirdio/netbird/management/internals/modules/reverseproxy/service" reverseproxymanager "github.com/netbirdio/netbird/management/internals/modules/reverseproxy/service/manager" nbgrpc "github.com/netbirdio/netbird/management/internals/shared/grpc" idpmanager "github.com/netbirdio/netbird/management/server/idp" - "github.com/netbirdio/management-integrations/integrations" - "github.com/netbirdio/netbird/management/internals/controllers/network_map" "github.com/netbirdio/netbird/management/internals/modules/zones" zonesManager "github.com/netbirdio/netbird/management/internals/modules/zones/manager" @@ -32,12 +30,10 @@ import ( "github.com/netbirdio/netbird/management/server/account" "github.com/netbirdio/netbird/management/server/settings" - "github.com/netbirdio/netbird/management/server/integrations/port_forwarding" "github.com/netbirdio/netbird/management/server/permissions" "github.com/netbirdio/netbird/management/server/http/handlers/proxy" - nbpeers "github.com/netbirdio/netbird/management/internals/modules/peers" "github.com/netbirdio/netbird/management/server/auth" "github.com/netbirdio/netbird/management/server/geolocation" nbgroups "github.com/netbirdio/netbird/management/server/groups" @@ -56,17 +52,14 @@ import ( "github.com/netbirdio/netbird/management/server/http/middleware" "github.com/netbirdio/netbird/management/server/http/middleware/bypass" nbinstance "github.com/netbirdio/netbird/management/server/instance" - "github.com/netbirdio/netbird/management/server/integrations/integrated_validator" nbnetworks "github.com/netbirdio/netbird/management/server/networks" "github.com/netbirdio/netbird/management/server/networks/resources" "github.com/netbirdio/netbird/management/server/networks/routers" "github.com/netbirdio/netbird/management/server/telemetry" ) -const apiPrefix = "/api" - // NewAPIHandler creates the Management service HTTP API handler registering all the available endpoints. -func NewAPIHandler(ctx context.Context, accountManager account.Manager, networksManager nbnetworks.Manager, resourceManager resources.Manager, routerManager routers.Manager, groupsManager nbgroups.Manager, LocationManager geolocation.Geolocation, authManager auth.Manager, appMetrics telemetry.AppMetrics, integratedValidator integrated_validator.IntegratedValidator, proxyController port_forwarding.Controller, permissionsManager permissions.Manager, peersManager nbpeers.Manager, settingsManager settings.Manager, zManager zones.Manager, rManager records.Manager, networkMapController network_map.Controller, idpManager idpmanager.Manager, serviceManager service.Manager, reverseProxyDomainManager *manager.Manager, reverseProxyAccessLogsManager accesslogs.Manager, proxyGRPCServer *nbgrpc.ProxyServiceServer, trustedHTTPProxies []netip.Prefix, rateLimiter *middleware.APIRateLimiter) (http.Handler, error) { +func NewAPIHandler(ctx context.Context, router *mux.Router, accountManager account.Manager, networksManager nbnetworks.Manager, resourceManager resources.Manager, routerManager routers.Manager, groupsManager nbgroups.Manager, LocationManager geolocation.Geolocation, authManager auth.Manager, appMetrics telemetry.AppMetrics, permissionsManager permissions.Manager, settingsManager settings.Manager, zManager zones.Manager, rManager records.Manager, networkMapController network_map.Controller, idpManager idpmanager.Manager, serviceManager service.Manager, reverseProxyDomainManager *manager.Manager, reverseProxyAccessLogsManager accesslogs.Manager, proxyGRPCServer *nbgrpc.ProxyServiceServer, trustedHTTPProxies []netip.Prefix, rateLimiter *middleware.APIRateLimiter, isValidChildAccount middleware.IsValidChildAccountFunc) (http.Handler, error) { // Register bypass paths for unauthenticated endpoints if err := bypass.AddBypassPath("/api/instance"); err != nil { @@ -100,25 +93,16 @@ func NewAPIHandler(ctx context.Context, accountManager account.Manager, networks accountManager.GetUserFromUserAuth, rateLimiter, appMetrics.GetMeter(), + isValidChildAccount, ) corsMiddleware := cors.AllowAll() - rootRouter := mux.NewRouter() metricsMiddleware := appMetrics.HTTPMiddleware() - prefix := apiPrefix - router := rootRouter.PathPrefix(prefix).Subrouter() - router.Use(metricsMiddleware.Handler, corsMiddleware.Handler, authMiddleware.Handler) - if _, err := integrations.RegisterHandlers(ctx, prefix, router, accountManager, integratedValidator, appMetrics.GetMeter(), permissionsManager, peersManager, proxyController, settingsManager); err != nil { - return nil, fmt.Errorf("register integrations endpoints: %w", err) - } - - // Check if embedded IdP is enabled for instance manager - embeddedIdP, embeddedIdpEnabled := idpManager.(*idpmanager.EmbeddedIdPManager) - instanceManager, err := nbinstance.NewManager(ctx, accountManager.GetStore(), embeddedIdP) + instanceManager, err := nbinstance.NewManager(ctx, accountManager.GetStore(), idpManager) if err != nil { return nil, fmt.Errorf("failed to create instance manager: %w", err) } @@ -154,10 +138,5 @@ func NewAPIHandler(ctx context.Context, accountManager account.Manager, networks oauthHandler.RegisterEndpoints(router) } - // Mount embedded IdP handler at /oauth2 path if configured - if embeddedIdpEnabled { - rootRouter.PathPrefix("/oauth2").Handler(corsMiddleware.Handler(embeddedIdP.Handler())) - } - - return rootRouter, nil + return router, nil } diff --git a/management/server/http/middleware/auth_middleware.go b/management/server/http/middleware/auth_middleware.go index 6d075d9c2..34df0de23 100644 --- a/management/server/http/middleware/auth_middleware.go +++ b/management/server/http/middleware/auth_middleware.go @@ -11,8 +11,6 @@ import ( log "github.com/sirupsen/logrus" "go.opentelemetry.io/otel/metric" - "github.com/netbirdio/management-integrations/integrations" - serverauth "github.com/netbirdio/netbird/management/server/auth" nbcontext "github.com/netbirdio/netbird/management/server/context" "github.com/netbirdio/netbird/management/server/http/middleware/bypass" @@ -27,6 +25,8 @@ type SyncUserJWTGroupsFunc func(ctx context.Context, userAuth auth.UserAuth) err type GetUserFromUserAuthFunc func(ctx context.Context, userAuth auth.UserAuth) (*types.User, error) +type IsValidChildAccountFunc func(ctx context.Context, userID, accountID, childAccountID string) bool + // AuthMiddleware middleware to verify personal access tokens (PAT) and JWT tokens type AuthMiddleware struct { authManager serverauth.Manager @@ -35,6 +35,7 @@ type AuthMiddleware struct { syncUserJWTGroups SyncUserJWTGroupsFunc rateLimiter *APIRateLimiter patUsageTracker *PATUsageTracker + isValidChildAccount IsValidChildAccountFunc } // NewAuthMiddleware instance constructor @@ -45,6 +46,7 @@ func NewAuthMiddleware( getUserFromUserAuth GetUserFromUserAuthFunc, rateLimiter *APIRateLimiter, meter metric.Meter, + isValidChildAccount IsValidChildAccountFunc, ) *AuthMiddleware { var patUsageTracker *PATUsageTracker if meter != nil { @@ -62,6 +64,7 @@ func NewAuthMiddleware( getUserFromUserAuth: getUserFromUserAuth, rateLimiter: rateLimiter, patUsageTracker: patUsageTracker, + isValidChildAccount: isValidChildAccount, } } @@ -124,7 +127,7 @@ func (m *AuthMiddleware) checkJWTFromRequest(r *http.Request, authHeaderParts [] } if impersonate, ok := r.URL.Query()["account"]; ok && len(impersonate) == 1 { - if integrations.IsValidChildAccount(ctx, userAuth.UserId, userAuth.AccountId, impersonate[0]) { + if m.isValidChildAccount(ctx, userAuth.UserId, userAuth.AccountId, impersonate[0]) { userAuth.AccountId = impersonate[0] userAuth.IsChild = true } @@ -203,7 +206,7 @@ func (m *AuthMiddleware) checkPATFromRequest(r *http.Request, authHeaderParts [] } if impersonate, ok := r.URL.Query()["account"]; ok && len(impersonate) == 1 { - if integrations.IsValidChildAccount(r.Context(), userAuth.UserId, userAuth.AccountId, impersonate[0]) { + if m.isValidChildAccount(r.Context(), userAuth.UserId, userAuth.AccountId, impersonate[0]) { userAuth.AccountId = impersonate[0] userAuth.IsChild = true } diff --git a/management/server/http/middleware/auth_middleware_test.go b/management/server/http/middleware/auth_middleware_test.go index 8f736fbfd..24cf8fce5 100644 --- a/management/server/http/middleware/auth_middleware_test.go +++ b/management/server/http/middleware/auth_middleware_test.go @@ -211,6 +211,7 @@ func TestAuthMiddleware_Handler(t *testing.T) { }, disabledLimiter, nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handlerToTest := authMiddleware.Handler(nextHandler) @@ -270,6 +271,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -322,6 +324,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -365,6 +368,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -409,6 +413,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -473,6 +478,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -532,6 +538,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -587,6 +594,7 @@ func TestAuthMiddleware_RateLimiting(t *testing.T) { }, NewAPIRateLimiter(rateLimitConfig), nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) handler := authMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -687,6 +695,7 @@ func TestAuthMiddleware_Handler_Child(t *testing.T) { }, disabledLimiter, nil, + func(_ context.Context, _, _, _ string) bool { return false }, ) for _, tc := range tt { diff --git a/management/server/http/testing/testing_tools/channel/channel.go b/management/server/http/testing/testing_tools/channel/channel.go index 3c4ea98d0..8da9c7ad4 100644 --- a/management/server/http/testing/testing_tools/channel/channel.go +++ b/management/server/http/testing/testing_tools/channel/channel.go @@ -7,6 +7,7 @@ import ( "time" "github.com/golang-jwt/jwt/v5" + "github.com/gorilla/mux" "github.com/stretchr/testify/assert" "go.opentelemetry.io/otel/metric/noop" @@ -135,7 +136,8 @@ func BuildApiBlackBoxWithDBState(t testing_tools.TB, sqlFile string, expectedPee customZonesManager := zonesManager.NewManager(store, am, permissionsManager, "") zoneRecordsManager := recordsManager.NewManager(store, am, permissionsManager) - apiHandler, err := http2.NewAPIHandler(context.Background(), am, networksManager, resourcesManager, routersManager, groupsManager, geoMock, authManagerMock, metrics, validatorMock, proxyController, permissionsManager, peersManager, settingsManager, customZonesManager, zoneRecordsManager, networkMapController, nil, serviceManager, nil, nil, nil, nil, nil) + apiRouter := mux.NewRouter().PathPrefix("/api").Subrouter() + apiHandler, err := http2.NewAPIHandler(context.Background(), apiRouter, am, networksManager, resourcesManager, routersManager, groupsManager, geoMock, authManagerMock, metrics, permissionsManager, settingsManager, customZonesManager, zoneRecordsManager, networkMapController, nil, serviceManager, nil, nil, nil, nil, nil, nil) if err != nil { t.Fatalf("Failed to create API handler: %v", err) } @@ -264,7 +266,8 @@ func BuildApiBlackBoxWithDBStateAndPeerChannel(t testing_tools.TB, sqlFile strin customZonesManager := zonesManager.NewManager(store, am, permissionsManager, "") zoneRecordsManager := recordsManager.NewManager(store, am, permissionsManager) - apiHandler, err := http2.NewAPIHandler(context.Background(), am, networksManager, resourcesManager, routersManager, groupsManager, geoMock, authManagerMock, metrics, validatorMock, proxyController, permissionsManager, peersManager, settingsManager, customZonesManager, zoneRecordsManager, networkMapController, nil, serviceManager, nil, nil, nil, nil, nil) + apiRouter := mux.NewRouter().PathPrefix("/api").Subrouter() + apiHandler, err := http2.NewAPIHandler(context.Background(), apiRouter, am, networksManager, resourcesManager, routersManager, groupsManager, geoMock, authManagerMock, metrics, permissionsManager, settingsManager, customZonesManager, zoneRecordsManager, networkMapController, nil, serviceManager, nil, nil, nil, nil, nil, nil) if err != nil { t.Fatalf("Failed to create API handler: %v", err) } diff --git a/management/server/integrations/integrated_validator/validator/validator.go b/management/server/integrations/integrated_validator/validator/validator.go new file mode 100644 index 000000000..db1d34373 --- /dev/null +++ b/management/server/integrations/integrated_validator/validator/validator.go @@ -0,0 +1,62 @@ +package validator + +import ( + "context" + + cachestore "github.com/eko/gocache/lib/v4/store" + + "github.com/netbirdio/netbird/management/internals/modules/peers" + "github.com/netbirdio/netbird/management/server/activity" + nbpeer "github.com/netbirdio/netbird/management/server/peer" + "github.com/netbirdio/netbird/management/server/settings" + "github.com/netbirdio/netbird/management/server/types" + "github.com/netbirdio/netbird/shared/management/proto" +) + +type IntegratedValidatorImpl struct{} + +func NewIntegratedValidator(_ context.Context, _ peers.Manager, _ settings.Manager, _ activity.Store, _ cachestore.StoreInterface) (*IntegratedValidatorImpl, error) { + return &IntegratedValidatorImpl{}, nil +} + +func (v *IntegratedValidatorImpl) ValidateExtraSettings(context.Context, *types.ExtraSettings, *types.ExtraSettings, string, string) error { + return nil +} + +func (v *IntegratedValidatorImpl) ValidatePeer(_ context.Context, update *nbpeer.Peer, _ *nbpeer.Peer, _ string, _ string, _ string, _ []string, _ *types.ExtraSettings) (*nbpeer.Peer, bool, error) { + return update, false, nil +} + +func (v *IntegratedValidatorImpl) PreparePeer(_ context.Context, _ string, peer *nbpeer.Peer, _ []string, _ *types.ExtraSettings, _ bool) *nbpeer.Peer { + return peer.Copy() +} + +func (v *IntegratedValidatorImpl) IsNotValidPeer(_ context.Context, _ string, _ *nbpeer.Peer, _ []string, _ *types.ExtraSettings) (bool, bool, error) { + return false, false, nil +} + +func (v *IntegratedValidatorImpl) GetValidatedPeers(_ context.Context, _ string, _ []*types.Group, peers []*nbpeer.Peer, _ *types.ExtraSettings) (map[string]struct{}, error) { + validatedPeers := make(map[string]struct{}) + for _, p := range peers { + validatedPeers[p.ID] = struct{}{} + } + return validatedPeers, nil +} + +func (v *IntegratedValidatorImpl) GetInvalidPeers(_ context.Context, _ string, _ *types.ExtraSettings) (map[string]string, error) { + return make(map[string]string), nil +} + +func (v *IntegratedValidatorImpl) PeerDeleted(_ context.Context, _, _ string, _ *types.ExtraSettings) error { + return nil +} + +func (v *IntegratedValidatorImpl) SetPeerInvalidationListener(_ func(accountID string, peerIDs []string)) { +} + +func (v *IntegratedValidatorImpl) Stop(_ context.Context) { +} + +func (v *IntegratedValidatorImpl) ValidateFlowResponse(_ context.Context, _ string, flowResponse *proto.PKCEAuthorizationFlow) *proto.PKCEAuthorizationFlow { + return flowResponse +} diff --git a/shared/management/client/client_test.go b/shared/management/client/client_test.go index a8e8172dc..be2c009ad 100644 --- a/shared/management/client/client_test.go +++ b/shared/management/client/client_test.go @@ -17,7 +17,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/netbirdio/management-integrations/integrations" + "github.com/netbirdio/netbird/management/server/integrations/integrated_validator/validator" ephemeral_manager "github.com/netbirdio/netbird/management/internals/modules/peers/ephemeral/manager" "github.com/netbirdio/netbird/management/internals/controllers/network_map/controller" @@ -103,7 +103,7 @@ func startManagement(t *testing.T) (*grpc.Server, net.Listener) { t.Fatal(err) } - ia, _ := integrations.NewIntegratedValidator(ctx, peersManger, settingsManagerMock, eventStore, cacheStore) + ia, _ := validator.NewIntegratedValidator(ctx, peersManger, settingsManagerMock, eventStore, cacheStore) metrics, err := telemetry.NewDefaultAppMetrics(ctx) require.NoError(t, err)