Skip to content

Commit

Permalink
Unify logging config between Stripe and Stripe 3DS2
Browse files Browse the repository at this point in the history
Use the value for `enableLogging` passed in the `Stripe` constructor
to determine whether to enable logging in the Stripe 3DS2 SDK.
  • Loading branch information
mshafrir-stripe committed Oct 7, 2019
1 parent 98f4cb5 commit e2e14b9
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 41 deletions.
16 changes: 0 additions & 16 deletions stripe/src/main/java/com/stripe/android/PaymentAuthConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,10 @@ public static final class Stripe3ds2Config {

final int timeout;
@NonNull final Stripe3ds2UiCustomization uiCustomization;
final boolean enableLogging;

private Stripe3ds2Config(@NonNull Builder builder) {
timeout = checkValidTimeout(builder.mTimeout);
uiCustomization = Objects.requireNonNull(builder.mUiCustomization);
enableLogging = builder.mEnableLogging;
}

private int checkValidTimeout(int timeout) {
Expand All @@ -93,7 +91,6 @@ public static final class Builder implements ObjectBuilder<Stripe3ds2Config> {
private int mTimeout = DEFAULT_TIMEOUT;
private Stripe3ds2UiCustomization mUiCustomization =
new Stripe3ds2UiCustomization.Builder().build();
private boolean mEnableLogging = false;

@NonNull
public Builder setTimeout(@IntRange(from = 5, to = 99) int timeout) {
Expand All @@ -107,19 +104,6 @@ public Builder setUiCustomization(@NonNull Stripe3ds2UiCustomization uiCustomiza
return this;
}

/**
* Enable logging in the Stripe 3DS2 SDK; disabled by default.
* It is recommended to disable logging in production.
*
* <p>Logs can be accessed from the command line using
* <code>adb logcat -s Stripe3ds2</code>.</p>
*/
@NonNull
public Builder setEnableLogging(boolean enableLogging) {
this.mEnableLogging = enableLogging;
return this;
}

@NonNull
public Stripe3ds2Config build() {
return new Stripe3ds2Config(this);
Expand Down
13 changes: 9 additions & 4 deletions stripe/src/main/java/com/stripe/android/PaymentController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ import java.util.concurrent.TimeUnit
internal open class PaymentController @VisibleForTesting constructor(
context: Context,
private val stripeRepository: StripeRepository,
enableLogging: Boolean = false,
private val messageVersionRegistry: MessageVersionRegistry =
MessageVersionRegistry(),
private val config: PaymentAuthConfig =
PaymentAuthConfig.get(),
private val threeDs2Service: StripeThreeDs2Service =
StripeThreeDs2ServiceImpl(context, StripeSSLSocketFactory(),
config.stripe3ds2Config.enableLogging),
StripeThreeDs2ServiceImpl(context, StripeSSLSocketFactory(), enableLogging),
private val analyticsRequestExecutor: FireAndForgetRequestExecutor =
StripeFireAndForgetRequestExecutor(),
private val analyticsDataFactory: AnalyticsDataFactory =
Expand Down Expand Up @@ -765,9 +765,14 @@ internal open class PaymentController @VisibleForTesting constructor(
.start(PaymentRelayStarter.Data.create(exception))
}

@JvmOverloads
@JvmStatic
fun create(context: Context, stripeRepository: StripeRepository): PaymentController {
return PaymentController(context.applicationContext, stripeRepository)
fun create(
context: Context,
stripeRepository: StripeRepository,
enableLogging: Boolean = false
): PaymentController {
return PaymentController(context.applicationContext, stripeRepository, enableLogging)
}
}
}
11 changes: 8 additions & 3 deletions stripe/src/main/java/com/stripe/android/Stripe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class Stripe internal constructor(
* @param context Activity or application context
* @param publishableKey the client's publishable key
* @param stripeAccountId optional, the Stripe Connect account id to attach to [Stripe API requests](https://stripe.com/docs/connect/authentication#authentication-via-the-stripe-account-header)
* @param enableLogging enable logging in the Stripe and Stripe 3DS2 SDKs; disabled by default.
* It is recommended to disable logging in production. Logs can be accessed from the command line using
* `adb logcat -s StripeSdk`
*/
@JvmOverloads
constructor(
Expand All @@ -75,19 +78,21 @@ class Stripe internal constructor(
),
StripeNetworkUtils(context.applicationContext),
ApiKeyValidator.get().requireValid(publishableKey),
stripeAccountId
stripeAccountId,
enableLogging
)

private constructor(
context: Context,
stripeRepository: StripeRepository,
stripeNetworkUtils: StripeNetworkUtils,
publishableKey: String,
stripeAccountId: String?
stripeAccountId: String?,
enableLogging: Boolean
) : this(
stripeRepository,
stripeNetworkUtils,
PaymentController.create(context.applicationContext, stripeRepository),
PaymentController.create(context.applicationContext, stripeRepository, enableLogging),
publishableKey,
stripeAccountId
)
Expand Down
38 changes: 20 additions & 18 deletions stripe/src/test/java/com/stripe/android/PaymentControllerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class PaymentControllerTest {
controller = PaymentController(
ApplicationProvider.getApplicationContext<Context>(),
FakeStripeRepository(),
false,
MessageVersionRegistry(),
CONFIG,
threeDs2Service,
Expand All @@ -116,7 +117,9 @@ class PaymentControllerTest {
@Throws(CertificateException::class)
fun handleNextAction_withMastercardAnd3ds2_shouldStart3ds2ChallengeFlow() {
val paymentIntent = PaymentIntentFixtures.PI_REQUIRES_MASTERCARD_3DS2
val dsPublicKey = Stripe3ds2Fingerprint.create(paymentIntent.stripeSdkData!!)
val dsPublicKey = Stripe3ds2Fingerprint.create(
requireNotNull(paymentIntent.stripeSdkData)
)
.directoryServerEncryption
.directoryServerPublicKey
`when`(threeDs2Service.createTransaction(
Expand Down Expand Up @@ -145,7 +148,7 @@ class PaymentControllerTest {

verify<FireAndForgetRequestExecutor>(fireAndForgetRequestExecutor)
.executeAsync(apiRequestArgumentCaptor.capture())
val analyticsParams = apiRequestArgumentCaptor.firstValue.params!!
val analyticsParams = requireNotNull(apiRequestArgumentCaptor.firstValue.params)
assertEquals("stripe_android.3ds2_fingerprint",
analyticsParams[AnalyticsDataFactory.FIELD_EVENT])
assertEquals(PaymentIntentFixtures.PI_REQUIRES_MASTERCARD_3DS2.id,
Expand Down Expand Up @@ -196,7 +199,7 @@ class PaymentControllerTest {
verify<FireAndForgetRequestExecutor>(fireAndForgetRequestExecutor)
.executeAsync(apiRequestArgumentCaptor.capture())
assertEquals("stripe_android.3ds1_sdk",
apiRequestArgumentCaptor.firstValue.params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(apiRequestArgumentCaptor.firstValue.params)[AnalyticsDataFactory.FIELD_EVENT])
}

@Test
Expand All @@ -216,7 +219,7 @@ class PaymentControllerTest {

verify<FireAndForgetRequestExecutor>(fireAndForgetRequestExecutor)
.executeAsync(apiRequestArgumentCaptor.capture())
val analyticsParams = apiRequestArgumentCaptor.firstValue.params!!
val analyticsParams = requireNotNull(apiRequestArgumentCaptor.firstValue.params)
assertEquals("stripe_android.url_redirect_next_action",
analyticsParams[AnalyticsDataFactory.FIELD_EVENT])
assertEquals("pi_1EZlvVCRMbs6FrXfKpq2xMmy",
Expand Down Expand Up @@ -276,9 +279,9 @@ class PaymentControllerTest {
val analyticsRequests = apiRequestArgumentCaptor.allValues

assertEquals("stripe_android.3ds2_challenge_flow_completed",
analyticsRequests[0].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[0].params)[AnalyticsDataFactory.FIELD_EVENT])

val analyticsParamsSecond = analyticsRequests[1].params!!
val analyticsParamsSecond = requireNotNull(analyticsRequests[1].params)
assertEquals("stripe_android.3ds2_challenge_flow_presented",
analyticsParamsSecond[AnalyticsDataFactory.FIELD_EVENT])
assertEquals("oob",
Expand All @@ -298,10 +301,10 @@ class PaymentControllerTest {
val analyticsRequests = apiRequestArgumentCaptor.allValues

assertEquals("stripe_android.3ds2_challenge_flow_timed_out",
analyticsRequests[0].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[0].params)[AnalyticsDataFactory.FIELD_EVENT])

assertEquals("stripe_android.3ds2_challenge_flow_presented",
analyticsRequests[1].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[1].params)[AnalyticsDataFactory.FIELD_EVENT])
}

@Test
Expand All @@ -318,10 +321,10 @@ class PaymentControllerTest {
val analyticsRequests = apiRequestArgumentCaptor.allValues

assertEquals("stripe_android.3ds2_challenge_flow_canceled",
analyticsRequests[0].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[0].params)[AnalyticsDataFactory.FIELD_EVENT])

assertEquals("stripe_android.3ds2_challenge_flow_presented",
analyticsRequests[1].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[1].params)[AnalyticsDataFactory.FIELD_EVENT])
}

@Test
Expand All @@ -342,7 +345,7 @@ class PaymentControllerTest {
.executeAsync(apiRequestArgumentCaptor.capture())
val analyticsRequests = apiRequestArgumentCaptor.allValues

val analyticsParamsFirst = analyticsRequests[0].params!!
val analyticsParamsFirst = requireNotNull(analyticsRequests[0].params)
assertEquals("stripe_android.3ds2_challenge_flow_errored",
analyticsParamsFirst[AnalyticsDataFactory.FIELD_EVENT])

Expand All @@ -353,7 +356,7 @@ class PaymentControllerTest {
assertEquals("Resource not found", errorData["error_message"])

assertEquals("stripe_android.3ds2_challenge_flow_presented",
analyticsRequests[1].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[1].params)[AnalyticsDataFactory.FIELD_EVENT])
}

@Test
Expand All @@ -380,7 +383,7 @@ class PaymentControllerTest {
.executeAsync(apiRequestArgumentCaptor.capture())
val analyticsRequests = apiRequestArgumentCaptor.allValues

val analyticsParamsFirst = analyticsRequests[0].params!!
val analyticsParamsFirst = requireNotNull(analyticsRequests[0].params)
assertEquals("stripe_android.3ds2_challenge_flow_errored",
analyticsParamsFirst[AnalyticsDataFactory.FIELD_EVENT])

Expand All @@ -390,7 +393,7 @@ class PaymentControllerTest {
assertEquals("201", errorData["error_code"])

assertEquals("stripe_android.3ds2_challenge_flow_presented",
analyticsRequests[1].params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequests[1].params)[AnalyticsDataFactory.FIELD_EVENT])
}

@Test
Expand Down Expand Up @@ -488,7 +491,7 @@ class PaymentControllerTest {

verify(fireAndForgetRequestExecutor).executeAsync(apiRequestArgumentCaptor.capture())
val analyticsRequest = apiRequestArgumentCaptor.firstValue
val analyticsParams = analyticsRequest.params!!
val analyticsParams = requireNotNull(analyticsRequest.params)
assertEquals("stripe_android.3ds2_frictionless_flow",
analyticsParams[AnalyticsDataFactory.FIELD_EVENT])
assertEquals("pi_1ExkUeAWhjPjYwPiXph9ouXa",
Expand Down Expand Up @@ -516,7 +519,7 @@ class PaymentControllerTest {
verify(fireAndForgetRequestExecutor).executeAsync(apiRequestArgumentCaptor.capture())
val analyticsRequest = apiRequestArgumentCaptor.firstValue
assertEquals("stripe_android.3ds2_fallback",
analyticsRequest.params!![AnalyticsDataFactory.FIELD_EVENT])
requireNotNull(analyticsRequest.params)[AnalyticsDataFactory.FIELD_EVENT])
}

@Test
Expand All @@ -529,12 +532,11 @@ class PaymentControllerTest {
)
authCallback.onSuccess(Stripe3ds2AuthResultFixtures.ERROR)
verify(paymentRelayStarter).start(relayStarterDataArgumentCaptor.capture())
val exception = relayStarterDataArgumentCaptor.firstValue.exception!!
assertEquals("Error encountered during 3DS2 authentication request. " +
"Code: 302, Detail: null, " +
"Description: Data could not be decrypted by the receiving system due to " +
"technical or other reason., Component: D",
exception.message)
relayStarterDataArgumentCaptor.firstValue.exception?.message)
}

private class FakeStripeRepository : AbsFakeStripeRepository() {
Expand Down

0 comments on commit e2e14b9

Please sign in to comment.