-
Notifications
You must be signed in to change notification settings - Fork 3
[PLUGIN-1741] SuccessFactors - OAuth2 Implementation #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PLUGIN-1741] SuccessFactors - OAuth2 Implementation #34
Conversation
ed6fb11 to
6989161
Compare
itsankit-google
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase the changes, resolve the conflicts and ensure build is green.
| @@ -0,0 +1,391 @@ | |||
| /* | |||
| * Copyright © 2022 Cask Data, Inc. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please update year in the license.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Year update to 2025
pom.xml
Outdated
| <dependency> | ||
| <groupId>org.apache.httpcomponents</groupId> | ||
| <artifactId>httpclient</artifactId> | ||
| <version>${httpclient.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.opensaml</groupId> | ||
| <artifactId>xmltooling</artifactId> | ||
| <version>1.4.4</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.opensaml</groupId> | ||
| <artifactId>openws</artifactId> | ||
| <version>1.5.4</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.opensaml</groupId> | ||
| <artifactId>opensaml</artifactId> | ||
| <version>2.6.4</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>commons-codec</groupId> | ||
| <artifactId>commons-codec</artifactId> | ||
| <version>1.10</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>xml-security</groupId> | ||
| <artifactId>xmlsec</artifactId> | ||
| <version>1.3.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>commons-collections</groupId> | ||
| <artifactId>commons-collections</artifactId> | ||
| <version>3.2.2</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>commons-lang</groupId> | ||
| <artifactId>commons-lang</artifactId> | ||
| <version>2.1</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>commons-logging</groupId> | ||
| <artifactId>commons-logging</artifactId> | ||
| <version>1.1</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.velocity</groupId> | ||
| <artifactId>velocity</artifactId> | ||
| <version>1.5</version> | ||
| <type>pom</type> | ||
| </dependency> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are the versions of these dependencies decided?
Is the same code being used somewhere in any other existing plugin?
Please add comments for every dependency where it is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only need opensaml for which we are using 2.6.4 as this is the latest version on oss.sonatype.
I have removed all the other dependencies.
| "property": "authType", | ||
| "operator": "equal to", | ||
| "value": "basicAuth" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
authType will be null in existing pipelines since it is a newly added config.
We should default to basicAuth when authType is also null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "equal to" with will "null" ?
Can you provide reference to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use filter as we do for Connection widget in other plugins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
{
"name": "basicAuth",
"condition": {
"expression": "authType == 'basicAuth' || authType == 'null'"
},
"show": [
{
"name": "username",
"type": "property"
},
{
"name": "password",
"type": "property"
}
]
}| tokenURL, clientId, privateKey, userId, samlUsername, assertionToken, | ||
| companyId, authType, assertionTokenType, filterOption, selectOption, | ||
| expandOption, additionalQueryParameters, paginationType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation looks off here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed !
| if (config.getConnection().getAuthType().equals(SuccessFactorsConnectorConfig.BASIC_AUTH)) { | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsPluginConfig.UNAME); | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsPluginConfig.PASSWORD); | ||
| } else { | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsConnectorConfig.COMPANY_ID); | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsConnectorConfig.CLIENT_ID); | ||
| if (config.getConnection().getAssertionTokenType().equals(SuccessFactorsConnectorConfig.ENTER_TOKEN)) { | ||
| failureCollector.addFailure(errMsg, null). | ||
| withConfigProperty(SuccessFactorsConnectorConfig.ASSERTION_TOKEN); | ||
| } else { | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsConnectorConfig.PRIVATE_KEY); | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsConnectorConfig.USER_ID); | ||
| failureCollector.addFailure(errMsg, null).withConfigProperty(SuccessFactorsConnectorConfig.TOKEN_URL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constants should always be used first in java to avoid NPE in equals condition.
For example,
if (SuccessFactorsConnectorConfig.BASIC_AUTH.equals(config.getConnection().getAuthType())) {....}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, reversed all equal checks to have constant first to avoid NPE.
| this.authType = authType; | ||
| return this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
authType will be null for existing pipelines.
It should default to BASIC_AUTH in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated !
- Default to basic auth if authType is not set for backward compatibility
this.authType = Strings.isNullOrEmpty(authType) ? SuccessFactorsConnectorConfig.BASIC_AUTH : authType;
itsankit-google
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also add unit tests for newly added configs for oauth2.
| if (SuccessFactorsUtil.isNullOrEmpty(getPassword()) && !containsMacro(PASSWORD)) { | ||
| String errMsg = ResourceConstants.ERR_MISSING_PARAM_PREFIX.getMsgForKey(SAP_SUCCESSFACTORS_PASSWORD); | ||
| failureCollector.addFailure(errMsg, COMMON_ACTION).withConfigProperty(PASSWORD); | ||
| if (BASIC_AUTH.equals(this.getAuthType())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: getAuthType()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated !
| String errMsg = ResourceConstants.ERR_MISSING_PARAM_PREFIX.getMsgForKey(SAP_SUCCESSFACTORS_PASSWORD); | ||
| failureCollector.addFailure(errMsg, COMMON_ACTION).withConfigProperty(PASSWORD); | ||
| if (BASIC_AUTH.equals(this.getAuthType())) { | ||
| if (Strings.isNullOrEmpty(getUsername()) && !containsMacro(UNAME)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check containsMacro() first for all configs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authentication Type is not macro
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment was all other configs which are macro to change the order of conditions, for example:
if (!containsMacro(UNAME) && Strings.isNullOrEmpty(getUsername()))
.........
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, i misunderstood the request !
| import io.cdap.plugin.successfactors.source.input.SuccessFactorsPartitionBuilder; | ||
| import io.cdap.plugin.successfactors.source.service.SuccessFactorsService; | ||
| import io.cdap.plugin.successfactors.source.transport.SuccessFactorsTransporter; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove empty line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed !
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove empty line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed !
src/main/java/io/cdap/plugin/successfactors/source/service/SuccessFactorsService.java
Show resolved
Hide resolved
| .handle(RetryableException.class) | ||
| .withBackoff(Duration.ofSeconds(initialRetryDuration), | ||
| Duration.ofSeconds(maxRetryDuration), retryMultiplier) | ||
| .withMaxRetries(maxRetryCount) | ||
| .onRetry(event -> LOG.debug("Retrying SapTransportCall. Retry count: {}", event.getAttemptCount())) | ||
| .onSuccess(event -> LOG.debug("SapTransportCall executed successfully.")) | ||
| .onRetriesExceeded(event -> LOG.error("Retry limit reached for SapTransportCall.")) | ||
| .build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revert unintended changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted !
| return baseURL; | ||
| } | ||
|
|
||
| public void validateBasicCredentials(FailureCollector failureCollector) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should be renamed to validateAuthCredentials
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done !
| import org.apache.hadoop.mapreduce.Job; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revert unintended change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor comments otherwise LGTM. Please squash commits before merge.
Would be good to also run existing e2e tests once succesfuly before merge.
| import io.cdap.plugin.successfactors.source.metadata.TestSuccessFactorsUtil; | ||
| import io.cdap.plugin.successfactors.source.service.SuccessFactorsService; | ||
| import io.cdap.plugin.successfactors.source.transport.SuccessFactorsTransporter; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove empty line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated !
a7772ea to
f545134
Compare
f545134 to
6e7d151
Compare
SuccessFactors OAuth2 Feature Implemenataion
Jira : PLUGIN-1741
Description
Succfactors currently uses basic auth where are user can enter username and password for auth. This PR adds a new option to let user use OAuth for auth.
What is assertion token and auth token ?
UI Field
SuccessFactors-batchsource.jsonSuccessFactors-connector.jsonNew Fields added
Docs
SuccessFactors-batchsource.mdSuccessFactors-connector.mdCode change
SuccessFactorsAccessToken.javaResourceConstants.javaSuccessFactorsConnectorConfig.javaSuccessFactorsSource.javaSuccessFactorsPluginConfig.javaSuccessFactorsService.javaSuccessFactorsTransporter.javaUnit Tests
SuccessFactorsConnectorTest.javaSuccessFactorsSourceTest.javaSuccessFactorsPluginConfigTest.javaSuccessFactorsInputFormatTest.javaSuccessFactorsSchemaGeneratorTest.javaRuntimeFunctionalForAssociatedEntityTest.javaRuntimeFunctionalTest.javaSuccessFactorsTransporterTest.javaSuccessFactorsUrlContainerTest.javaSanity Tests