1515 */
1616package io .cdap .plugin .salesforce .plugin ;
1717
18+ import com .google .common .base .Strings ;
1819import com .sforce .ws .ConnectionException ;
1920import io .cdap .cdap .api .annotation .Description ;
2021import io .cdap .cdap .api .annotation .Macro ;
2425import io .cdap .plugin .salesforce .SalesforceConnectionUtil ;
2526import io .cdap .plugin .salesforce .SalesforceConstants ;
2627import io .cdap .plugin .salesforce .authenticator .AuthenticatorCredentials ;
28+ import io .cdap .plugin .salesforce .authenticator .AuthenticatorCredentials .GrantType ;
2729
2830import javax .annotation .Nullable ;
2931
3234 */
3335public class SalesforceConnectorBaseConfig extends PluginConfig {
3436
37+ @ Name (SalesforceConstants .PROPERTY_AUTHENTICATION_GRANT_TYPE )
38+ @ Description ("Salesforce authentication grant type: basic or client credentials" )
39+ @ Nullable
40+ @ Macro
41+ protected String authenticationGrantType ;
42+
3543 @ Nullable
3644 @ Name (SalesforceConstants .PROPERTY_PROXY_URL )
3745 @ Description ("Proxy URL. Must contain a protocol, address and port." )
@@ -118,7 +126,8 @@ public SalesforceConnectorBaseConfig(@Nullable String consumerKey,
118126 @ Nullable Long initialRetryDuration ,
119127 @ Nullable Long maxRetryDuration ,
120128 @ Nullable Integer maxRetryCount ,
121- @ Nullable Boolean retryOnBackendError ) {
129+ @ Nullable Boolean retryOnBackendError ,
130+ @ Nullable String authenticationGrantType ) {
122131 this .consumerKey = consumerKey ;
123132 this .consumerSecret = consumerSecret ;
124133 this .username = username ;
@@ -132,6 +141,16 @@ public SalesforceConnectorBaseConfig(@Nullable String consumerKey,
132141 this .maxRetryDuration = maxRetryDuration ;
133142 this .retryOnBackendError = retryOnBackendError ;
134143 this .maxRetryCount = maxRetryCount ;
144+ this .authenticationGrantType = authenticationGrantType ;
145+ }
146+
147+ public GrantType getAuthenticationGrantType () {
148+ if (!Strings .isNullOrEmpty (authenticationGrantType ) &&
149+ authenticationGrantType .equals (GrantType .CLIENT_CREDENTIALS .getType ())) {
150+ return GrantType .CLIENT_CREDENTIALS ;
151+ }
152+ // Default auth, handles null case when upgrading pipeline
153+ return SalesforceConstants .DEFAULT_GRANT_TYPE ;
135154 }
136155
137156 @ Nullable
@@ -232,4 +251,55 @@ public String getProxyUrl() {
232251 return proxyUrl ;
233252 }
234253
254+ /**
255+ * Validates that required authentication fields are present based on the selected OAuth grant type.
256+ * For PASSWORD grant type: consumerKey, consumerSecret, username, password, and loginUrl are required.
257+ * For CLIENT_CREDENTIALS grant type: consumerKey, consumerSecret, and loginUrl are required.
258+ *
259+ * @param collector the failure collector to report validation errors
260+ */
261+ public void validateAuthenticationFields (FailureCollector collector ) {
262+ if (containsMacro (SalesforceConstants .PROPERTY_AUTHENTICATION_GRANT_TYPE )) {
263+ return ;
264+ }
265+
266+ GrantType grantType = getAuthenticationGrantType ();
267+
268+ // Fields required for all grant types
269+ if (!containsMacro (SalesforceConstants .PROPERTY_CONSUMER_KEY ) && Strings .isNullOrEmpty (consumerKey )) {
270+ collector .addFailure ("Consumer Key is required for authentication." ,
271+ "Please provide the Consumer Key from your Salesforce connected app." )
272+ .withConfigProperty (SalesforceConstants .PROPERTY_CONSUMER_KEY );
273+ }
274+ if (!containsMacro (SalesforceConstants .PROPERTY_CONSUMER_SECRET ) && Strings .isNullOrEmpty (consumerSecret )) {
275+ collector .addFailure ("Consumer Secret is required for authentication." ,
276+ "Please provide the Consumer Secret from your Salesforce connected app." )
277+ .withConfigProperty (SalesforceConstants .PROPERTY_CONSUMER_SECRET );
278+ }
279+ if (!containsMacro (SalesforceConstants .PROPERTY_LOGIN_URL ) && Strings .isNullOrEmpty (loginUrl )) {
280+ collector .addFailure ("Login URL is required for authentication." ,
281+ "Please provide the Salesforce login URL." )
282+ .withConfigProperty (SalesforceConstants .PROPERTY_LOGIN_URL );
283+ }
284+
285+ // Fields required only for PASSWORD grant type
286+ if (grantType == GrantType .PASSWORD ) {
287+ if (!containsMacro (SalesforceConstants .PROPERTY_USERNAME ) && Strings .isNullOrEmpty (username )) {
288+ collector .addFailure ("Username is required for password grant type authentication." ,
289+ "Please provide the Salesforce username." )
290+ .withConfigProperty (SalesforceConstants .PROPERTY_USERNAME );
291+ }
292+ if (!containsMacro (SalesforceConstants .PROPERTY_PASSWORD ) && Strings .isNullOrEmpty (password )) {
293+ collector .addFailure ("Password is required for password grant type authentication." ,
294+ "Please provide the Salesforce password." )
295+ .withConfigProperty (SalesforceConstants .PROPERTY_PASSWORD );
296+ }
297+ if (!containsMacro (SalesforceConstants .PROPERTY_SECURITY_TOKEN ) && Strings .isNullOrEmpty (securityToken )) {
298+ collector .addFailure ("Security Token is required for password grant type authentication." ,
299+ "Please provide the Salesforce security token." )
300+ .withConfigProperty (SalesforceConstants .PROPERTY_SECURITY_TOKEN );
301+ }
302+ }
303+ }
304+
235305}
0 commit comments