Skip to content

Commit feee01a

Browse files
authored
chore: improve destgcppubsub validation (#546)
1 parent 0a5d2ba commit feee01a

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

internal/destregistry/providers/destgcppubsub/destgcppubsub.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@ func (d *GCPPubSubDestination) resolveMetadata(ctx context.Context, destination
9393
return nil, nil, err
9494
}
9595

96+
// Validate service_account_json is valid JSON (if not using emulator endpoint)
97+
serviceAccountJSON := destination.Credentials["service_account_json"]
98+
endpoint := destination.Config["endpoint"]
99+
100+
// Only validate JSON if we're not using an emulator endpoint and service_account_json is provided
101+
if endpoint == "" && serviceAccountJSON != "" {
102+
var jsonCheck map[string]interface{}
103+
if err := json.Unmarshal([]byte(serviceAccountJSON), &jsonCheck); err != nil {
104+
return nil, nil, destregistry.NewErrDestinationValidation([]destregistry.ValidationErrorDetail{
105+
{
106+
Field: "credentials.service_account_json",
107+
Type: "format",
108+
},
109+
})
110+
}
111+
}
112+
96113
return &GCPPubSubDestinationConfig{
97114
ProjectID: destination.Config["project_id"],
98115
Topic: destination.Config["topic"],

internal/destregistry/providers/destgcppubsub/destgcppubsub_test.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,42 @@ func TestValidate(t *testing.T) {
164164
credentials: map[string]string{
165165
"service_account_json": "not-valid-json",
166166
},
167-
wantErr: false, // We don't validate JSON structure anymore, Google SDK will handle it
167+
wantErr: true,
168+
errContains: "credentials.service_account_json",
169+
},
170+
{
171+
name: "invalid JSON in service_account_json - but passes with emulator endpoint",
172+
config: map[string]string{
173+
"project_id": "my-project",
174+
"topic": "my-topic",
175+
"endpoint": "http://localhost:8085",
176+
},
177+
credentials: map[string]string{
178+
"service_account_json": "not-valid-json",
179+
},
180+
wantErr: false, // Emulator doesn't require valid JSON
181+
},
182+
{
183+
name: "valid service account JSON with complete structure",
184+
config: map[string]string{
185+
"project_id": "my-project",
186+
"topic": "my-topic",
187+
},
188+
credentials: map[string]string{
189+
"service_account_json": `{
190+
"type": "service_account",
191+
"project_id": "my-project",
192+
"private_key_id": "key123",
193+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n",
194+
"client_email": "[email protected]",
195+
"client_id": "123456789",
196+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
197+
"token_uri": "https://oauth2.googleapis.com/token",
198+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
199+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/my-service%40my-project.iam.gserviceaccount.com"
200+
}`,
201+
},
202+
wantErr: false,
168203
},
169204
{
170205
name: "valid with all optional fields",

spec-sdk-tests/tests/destinations/gcp-pubsub.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,7 @@ describe('GCP Pub/Sub Destinations - Contract Tests (SDK-based validation)', ()
214214
}
215215
});
216216

217-
// TODO: Re-enable this test once the backend validates the contents of the serviceAccountJson.
218-
it.skip('should reject creation with invalid serviceAccountJson', async () => {
217+
it('should reject creation with invalid serviceAccountJson', async () => {
219218
let errorThrown = false;
220219
try {
221220
await client.createDestination({

0 commit comments

Comments
 (0)