Skip to content

Commit

Permalink
Merge pull request #305 from radarlabs/track-verified-encrypted
Browse files Browse the repository at this point in the history
add trackVerifiedToken()
  • Loading branch information
nickpatrick authored Aug 22, 2023
2 parents fa8e3fb + 9b330ae commit 7450e87
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 6 deletions.
2 changes: 1 addition & 1 deletion sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ apply plugin: "org.jetbrains.dokka"
apply plugin: 'io.radar.mvnpublish'

ext {
radarVersion = '3.8.6'
radarVersion = '3.8.7'
}

String buildNumber = ".${System.currentTimeMillis()}"
Expand Down
104 changes: 102 additions & 2 deletions sdk/src/main/java/io/radar/sdk/Radar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import io.radar.sdk.util.RadarSimpleLogBuffer
import io.radar.sdk.util.RadarSimpleReplayBuffer
import org.json.JSONObject
import java.util.*
import io.radar.sdk.RadarActivityLifecycleCallbacks

/**
* The main class used to interact with the Radar SDK.
Expand Down Expand Up @@ -84,6 +83,24 @@ object Radar {

}

/**
* Called when a track request with token callback succeeds, fails, or times out.
*/
interface RadarTrackTokenCallback {

/**
* Called when a track request with token callback succeeds, fails, or times out. Receives the request status and, if successful, a JSON Web Token (JWT) containing an array of the events generated and the user. Verify the JWT server-side using your secret key.
*
* @param[status] RadarStatus The request status.
* @param[token] String? If successful, a JSON Web Token (JWT).
*/
fun onComplete(
status: RadarStatus,
token: String? = null
)

}

/**
* Called when a trip update succeeds, fails, or times out.
*/
Expand Down Expand Up @@ -780,6 +797,7 @@ object Radar {
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
handler.post {
callback?.onComplete(status, location, events, user)
Expand Down Expand Up @@ -873,6 +891,7 @@ object Radar {
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
handler.post {
callback?.onComplete(status, location, events, user)
Expand Down Expand Up @@ -904,6 +923,8 @@ object Radar {
* Note that you must configure SSL pinning before calling this method.
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[callback] An optional callback.
*/
@JvmStatic
fun trackVerified(callback: RadarTrackCallback? = null) {
Expand Down Expand Up @@ -931,14 +952,15 @@ object Radar {
}

verificationManager.getIntegrityToken(config.googlePlayProjectNumber, config.nonce) { integrityToken, integrityException ->
apiClient.track(location, RadarState.getStopped(context), RadarActivityLifecycleCallbacks.foreground, RadarLocationSource.FOREGROUND_LOCATION, false, null, true, integrityToken, integrityException, object : RadarApiClient.RadarTrackApiCallback {
apiClient.track(location, RadarState.getStopped(context), RadarActivityLifecycleCallbacks.foreground, RadarLocationSource.FOREGROUND_LOCATION, false, null, true, integrityToken, integrityException, false, callback = object : RadarApiClient.RadarTrackApiCallback {
override fun onComplete(
status: RadarStatus,
res: JSONObject?,
events: Array<RadarEvent>?,
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
handler.post {
callback?.onComplete(status, location, events, user)
Expand All @@ -958,6 +980,8 @@ object Radar {
* Note that you must configure SSL pinning before calling this method.
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[block] A block callback.
*/
@JvmStatic
fun trackVerified(block: (status: RadarStatus, location: Location?, events: Array<RadarEvent>?, user: RadarUser?) -> Unit) {
Expand All @@ -968,6 +992,81 @@ object Radar {
})
}

/**
* Tracks the user's location with device integrity information for location verification use cases. Returns a JSON Web Token (JWT). Verify the JWT server-side using your secret key.
*
* Note that you must configure SSL pinning before calling this method.
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[callback] An optional callback.
*/
@JvmStatic
fun trackVerifiedToken(callback: RadarTrackTokenCallback? = null) {
if (!initialized) {
callback?.onComplete(RadarStatus.ERROR_PUBLISHABLE_KEY)

return
}

if (!this::verificationManager.isInitialized) {
this.verificationManager = RadarVerificationManager(this.context, this.logger)
}

val usage = "verify"
apiClient.getConfig(usage, true, object : RadarApiClient.RadarGetConfigApiCallback {
override fun onComplete(config: RadarConfig) {
locationManager.getLocation(RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH, RadarLocationSource.FOREGROUND_LOCATION, object : RadarLocationCallback {
override fun onComplete(status: RadarStatus, location: Location?, stopped: Boolean) {
if (status != RadarStatus.SUCCESS || location == null) {
handler.post {
callback?.onComplete(status)
}

return
}

verificationManager.getIntegrityToken(config.googlePlayProjectNumber, config.nonce) { integrityToken, integrityException ->
apiClient.track(location, RadarState.getStopped(context), RadarActivityLifecycleCallbacks.foreground, RadarLocationSource.FOREGROUND_LOCATION, false, null, true, integrityToken, integrityException, true, object : RadarApiClient.RadarTrackApiCallback {
override fun onComplete(
status: RadarStatus,
res: JSONObject?,
events: Array<RadarEvent>?,
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
handler.post {
callback?.onComplete(status, token)
}
}
})
}
}
})
}
})
}

/**
* Tracks the user's location with device integrity information for location verification use cases. Returns a JSON Web Token (JWT). Verify the JWT server-side using your secret key.
*
* Note that you must configure SSL pinning before calling this method.
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[block] A block callback.
*/
@JvmStatic
fun trackVerifiedToken(block: (status: RadarStatus, token: String?) -> Unit) {
trackVerifiedToken(object : RadarTrackTokenCallback {
override fun onComplete(status: RadarStatus, token: String?) {
block(status, token)
}
})
}

/**
* Starts tracking the user's location in the background.
*
Expand Down Expand Up @@ -1059,6 +1158,7 @@ object Radar {
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
handler.post {
callback?.onComplete(status, location, events, user)
Expand Down
13 changes: 11 additions & 2 deletions sdk/src/main/java/io/radar/sdk/RadarApiClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ internal class RadarApiClient(
events: Array<RadarEvent>? = null,
user: RadarUser? = null,
nearbyGeofences: Array<RadarGeofence>? = null,
config: RadarConfig? = null
config: RadarConfig? = null,
token: String? = null
)
}

Expand Down Expand Up @@ -170,7 +171,7 @@ internal class RadarApiClient(
)
}

internal fun track(location: Location, stopped: Boolean, foreground: Boolean, source: RadarLocationSource, replayed: Boolean, beacons: Array<RadarBeacon>?, verified: Boolean = false, integrityToken: String? = null, integrityException: String? = null, callback: RadarTrackApiCallback? = null) {
internal fun track(location: Location, stopped: Boolean, foreground: Boolean, source: RadarLocationSource, replayed: Boolean, beacons: Array<RadarBeacon>?, verified: Boolean = false, integrityToken: String? = null, integrityException: String? = null, encrypted: Boolean? = false, callback: RadarTrackApiCallback? = null) {
val publishableKey = RadarSettings.getPublishableKey(context)
if (publishableKey == null) {
callback?.onComplete(RadarStatus.ERROR_PUBLISHABLE_KEY)
Expand Down Expand Up @@ -272,6 +273,7 @@ internal class RadarApiClient(
params.putOpt("integrityToken", integrityToken)
params.putOpt("integrityException", integrityException)
params.putOpt("sharing", RadarUtils.isScreenSharing(context))
params.putOpt("encrypted", encrypted)
}
params.putOpt("appId", context.packageName)
} catch (e: JSONException) {
Expand Down Expand Up @@ -342,6 +344,13 @@ internal class RadarApiClient(
val nearbyGeofences = res.optJSONArray("nearbyGeofences")?.let { nearbyGeofencesArr ->
RadarGeofence.fromJson(nearbyGeofencesArr)
}
val token = res.optString("token")

if (encrypted == true) {
callback?.onComplete(status, res, null, null, null, null, token)

return
}

if (user != null) {
val inGeofences = user.geofences != null && user.geofences.isNotEmpty()
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/main/java/io/radar/sdk/RadarLocationManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,8 @@ internal class RadarLocationManager(
events: Array<RadarEvent>?,
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?
config: RadarConfig?,
token: String?
) {
locationManager.replaceSyncedGeofences(nearbyGeofences)

Expand Down

0 comments on commit 7450e87

Please sign in to comment.