diff --git a/management/server/store/sql_store.go b/management/server/store/sql_store.go index 3ad870ad3..fdb976a00 100644 --- a/management/server/store/sql_store.go +++ b/management/server/store/sql_store.go @@ -2259,7 +2259,7 @@ func (s *SqlStore) getPostureChecks(ctx context.Context, accountID string) ([]*p } func (s *SqlStore) getServices(ctx context.Context, accountID string) ([]*rpservice.Service, error) { - const serviceQuery = `SELECT id, account_id, name, domain, enabled, auth, + const serviceQuery = `SELECT id, account_id, name, domain, enabled, auth, restrictions, meta_created_at, meta_certificate_issued_at, meta_status, proxy_cluster, pass_host_header, rewrite_redirects, session_private_key, session_public_key, mode, listen_port, port_auto_assigned, source, source_peer, terminated, @@ -2278,6 +2278,7 @@ func (s *SqlStore) getServices(ctx context.Context, accountID string) ([]*rpserv services, err := pgx.CollectRows(serviceRows, func(row pgx.CollectableRow) (*rpservice.Service, error) { var s rpservice.Service var auth []byte + var restrictions []byte var accessGroups []byte var createdAt, certIssuedAt sql.NullTime var status, proxyCluster, sessionPrivateKey, sessionPublicKey sql.NullString @@ -2291,6 +2292,7 @@ func (s *SqlStore) getServices(ctx context.Context, accountID string) ([]*rpserv &s.Domain, &s.Enabled, &auth, + &restrictions, &createdAt, &certIssuedAt, &status, @@ -2318,6 +2320,12 @@ func (s *SqlStore) getServices(ctx context.Context, accountID string) ([]*rpserv } } + if len(restrictions) > 0 { + if err := json.Unmarshal(restrictions, &s.Restrictions); err != nil { + return nil, fmt.Errorf("unmarshal restrictions: %w", err) + } + } + if len(accessGroups) > 0 { if err := json.Unmarshal(accessGroups, &s.AccessGroups); err != nil { return nil, fmt.Errorf("unmarshal access_groups: %w", err) diff --git a/management/server/store/sql_store_service_test.go b/management/server/store/sql_store_service_test.go index 34999da4b..af60fc063 100644 --- a/management/server/store/sql_store_service_test.go +++ b/management/server/store/sql_store_service_test.go @@ -44,3 +44,42 @@ func TestSqlStore_GetAccount_PrivateServiceRoundtrip(t *testing.T) { assert.Equal(t, []string{"grp-admins", "grp-ops"}, got.AccessGroups) }) } + +func TestSqlStore_GetAccount_ServiceRestrictionsRoundtrip(t *testing.T) { + if os.Getenv("CI") == "true" && (runtime.GOOS == "darwin" || runtime.GOOS == "windows") { + t.Skip("skip CI tests on darwin and windows") + } + + runTestForAllEngines(t, "", func(t *testing.T, store Store) { + ctx := context.Background() + account := newAccountWithId(ctx, "account_svc_restrictions", "testuser", "") + require.NoError(t, store.SaveAccount(ctx, account)) + + svc := &rpservice.Service{ + ID: "svc-restrictions", + AccountID: account.Id, + Name: "restricted-svc", + Domain: "restricted.example", + Enabled: true, + Mode: rpservice.ModeHTTP, + Restrictions: rpservice.AccessRestrictions{ + AllowedCIDRs: []string{"203.0.113.0/24"}, + AllowedCountries: []string{"US"}, + AllowMatch: "any", + }, + } + require.NoError(t, store.CreateService(ctx, svc)) + + loaded, err := store.GetAccount(ctx, account.Id) + require.NoError(t, err) + require.Len(t, loaded.Services, 1) + + // Restrictions are stored as a JSON blob; confirm the whole struct, + // including allow_match, survives the read path (Postgres pgx path + // included via runTestForAllEngines). + got := loaded.Services[0].Restrictions + assert.Equal(t, []string{"203.0.113.0/24"}, got.AllowedCIDRs) + assert.Equal(t, []string{"US"}, got.AllowedCountries) + assert.Equal(t, "any", got.AllowMatch) + }) +}