Skip to content

Commit

Permalink
Merge pull request #12 from wultra/develop
Browse files Browse the repository at this point in the history
Release  1.1.0
  • Loading branch information
kober32 authored May 19, 2020
2 parents 7de5eab + 783a0ce commit 77d9eab
Show file tree
Hide file tree
Showing 12 changed files with 509 additions and 167 deletions.
111 changes: 92 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,24 @@

## Introduction

With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk#docucheck-keep-link). It communicates with the "Mobile Token REST API" and "Mobile Push Registration API." Individual endpoints are described in the [PowerAuth Webflow documentation](https://developers.wultra.com/docs/2019.11/powerauth-webflow/).
With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk). It communicates with the "Mobile Token REST API" and "Mobile Push Registration API". Individual endpoints are described in the [PowerAuth Webflow documentation](https://github.com/wultra/powerauth-webflow/).

To understand the Wultra Mobile Token SDK purpose on a business level better, you can visit our own [Mobile Token application](https://www.wultra.com/mobile-token#docucheck-keep-link). We use Wultra Mobile Token SDK in our mobile token application as well.
To understand the Wultra Mobile Token SDK purpose on a business level better, you can visit our own [Mobile Token application](https://www.wultra.com/mobile-token). We use Wultra Mobile Token SDK in our mobile token application as well.

Wultra Mobile Token SDK library does precisely this:

- Registers an existing PowerAuth activation to receive push notifications.
- Retrieves the list of operations that are pending for approval for a given user.
- Approves or rejects operations with PowerAuth transaction signing.

_Note: We also provide an [iOS version of this library](https://github.com/wultra/mtoken-sdk-ios#docucheck-keep-link)_
_Note: We also provide an [iOS version of this library](https://github.com/wultra/mtoken-sdk-ios)_

## Installation

### Requirements

- `minSdkVersion 16` (Android 4.1 Jelly Bean)
- [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk#docucheck-keep-link) needs to be available in your project.
- [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk) needs to be available in your project.

### Gradle

Expand All @@ -46,7 +46,7 @@ To use **WMT** in your Android app, add this dependency:
implementation "com.wultra.android.mtokensdk:wultra-mtoken-sdk:1.0.0"
```

Note that this documentation is using version `1.0.0` as an example. You can find the latest version at [github's release](https://github.com/wultra/mtoken-sdk-android/releases#docucheck-keep-link) page.
Note that this documentation is using version `1.0.0` as an example. You can find the latest version at [github's release](https://github.com/wultra/mtoken-sdk-android/releases) page.

Also, make sure you have `mavenLocal()` repository among the project repositories and the version you are linking available in your local Maven repository.

Expand All @@ -63,7 +63,7 @@ This part of the SDK communicates with [Mobile Token API endpoints](https://gith

#### Factory Extension With SSL Validation Strategy

Convenience factory method that will return a new instance. A new `OkHttpClient` will be created based on chosen `SSLValidationStrategy` in the last parameter.
Convenience factory method that will return a new instance. A new [`OkHttpClient`](https://square.github.io/okhttp/) will be created based on chosen `SSLValidationStrategy` in the last parameter.

```kotlin
fun PowerAuthSDK.createOperationsService(appContext: Context, baseURL: String, strategy: SSLValidationStrategy): IOperationsService
Expand All @@ -78,23 +78,23 @@ fun PowerAuthSDK.createOperationsService(appContext: Context, baseURL: String, s

#### Factory Extension With OkHttpClient

Convenience factory method that will return a new instance with provided `OkHttpClient` that you can configure on your own.
Convenience factory method that will return a new instance with provided [`OkHttpClient`](https://square.github.io/okhttp/) that you can configure on your own.

```kotlin
fun PowerAuthSDK.createOperationsService(appContext: Context, baseURL: String, httpClient: OkHttpClient): IOperationsService
```

- `appContext` - application context
- `baseURL`- address, where your operations server can be reached
- `httpClient` - `OkHttpClient` instance used for API requests
- `httpClient` - [`OkHttpClient`](https://square.github.io/okhttp/) instance used for API requests

#### Retrieve the Pending Operations

To fetch the list with pending operations, implement the `IOperationsService` API, you can call:

```kotlin
operationsService.getOperations(object : IGetOperationListener {
override fun onSuccess(operations: List<Operation>) {
override fun onSuccess(operations: List<UserOperation>) {
// render operations
}
override fun onError(error: ApiError) {
Expand All @@ -105,6 +105,8 @@ operationsService.getOperations(object : IGetOperationListener {

After you retrieve the pending operations, you can render them in the UI, for example, as a list of items with a detail of operation shown after a tap.

*Note: Language of the UI data inside the operation depends on the configuration of the `IOperationsService.acceptLanguage`.*

#### Start Periodic Polling

Mobile token API is highly asynchronous - to simplify the work for you, we added a convenience operation list polling feature:
Expand All @@ -123,7 +125,7 @@ Approve or reject a given operation, simply hook these actions to the approve or
```kotlin

// Approve operation with password
fun approve(operation: Operation, password: String) {
fun approve(operation: UserOperation, password: String) {

val auth = PowerAuthAuthentication()
auth.usePossession = true
Expand All @@ -142,7 +144,7 @@ fun approve(operation: Operation, password: String) {
}

// Reject operation with some reason
fun reject(operation: Operation, reason: RejectionReason) {
fun reject(operation: UserOperation, reason: RejectionReason) {
operationsService.rejectOperation(operation, reason, object : IRejectOperationListener {
override fun onSuccess() {
// show success UI
Expand Down Expand Up @@ -192,7 +194,7 @@ fun approveQROperation(operation: QROperation, password: String): String {
All available methods and attributes of `IOperationsService` API are:

- `listener` - Listener object that receives info about operation loading.
- `acceptLanguage` - Language settings, that will be sent along with each request. The server will return properly localized content based on this value.
- `acceptLanguage` - Language settings, that will be sent along with each request. The server will return properly localized content based on this value. Value follows standard RFC [Accept-Language](https://tools.ietf.org/html/rfc7231#section-5.3.5)
- `getLastOperationsResult()` - Cached last operations result.
- `isLoadingOperations()` - Indicates if the service is loading operations.
- `getOperations(listener: IGetOperationListener?)` - Retrieves pending operations from the server.
Expand All @@ -201,11 +203,11 @@ All available methods and attributes of `IOperationsService` API are:
- `startPollingOperations(pollingInterval: Long)` - Starts periodic operation polling.
- `pollingInterval` - How often should operations be refreshed.
- `stopPollingOperations()` - Stops periodic operation polling.
- `authorizeOperation(operation: Operation, authentication: PowerAuthAuthentication, listener: IAcceptOperationListener)` - Authorize provided operation.
- `authorizeOperation(operation: UserOperation, authentication: PowerAuthAuthentication, listener: IAcceptOperationListener)` - Authorize provided operation.
- `operation` - Operation to approve, retrieved from `getOperations` call.
- `authentication` - PowerAuth authentication object for operation signing.
- `listener` - Called when authorization request finishes.
- `rejectOperation(operation: Operation, reason: RejectionReason, listener: IRejectOperationListener)` - Reject provided operation.
- `rejectOperation(operation: UserOperation, reason: RejectionReason, listener: IRejectOperationListener)` - Reject provided operation.
- `operation` - Operation to reject, retrieved from `getOperations` call.
- `reason` - Rejection reason.
- `listener` - Called when rejection request finishes.
Expand All @@ -216,7 +218,78 @@ All available methods and attributes of `IOperationsService` API are:
- `biometry` - Biometry data retrieved from `powerAuthSDK.authenticateUsingBiometry` call.
- `offlineOperation` - Offline operation retrieved via `processOfflineQrPayload` method.

For more details on the API, visit [`IOperationsService` code documentation](https://github.com/wultra/mtoken-sdk-android/blob/master/library/src/main/java/com/wultra/android/mtokensdk/operation/IOperationsService.kt).
For more details on the API, visit [`IOperationsService` code documentation](https://github.com/wultra/mtoken-sdk-android/blob/develop/library/src/main/java/com/wultra/android/mtokensdk/operation/IOperationsService.kt#docucheck-keep-link).

#### UserOperations

Operations objects retrieved through the online API (like `getOperations` method in `IOperationsService`) are called "user operations".

Under this abstract name, you can imagine for example "Login operation", which is a request for signing in to the online account in a web browser on another device. **In general, it can be any operation that can be either approved or rejected by the user.**

Visually, the operation should be displayed as an info page with all the attributes (rows) of such operation, where the user can decide if he wants to approve or reject it.

Definition of the `UserOperations`:

```kotlin
class UserOperation {

// Unique operation identifier
val id: String

// System name of the operation.
//
// This property lets you adjust the UI for various operation types.
// For example, the "login" operation may display a specialized interface with
// an icon or an illustration, instead of an empty list of attributes,
// "payment" operation can include a special icon that denotes payments, etc.
val name: String

// Actual data that will be signed.
val data: String

// Date and time when the operation was created.
val created: ZonedDateTime

// Date and time when the operation will expire.
val expires: ZonedDateTime

// Data that should be presented to the user.
val formData: FormData

// Allowed signature types.
//
// This hints if the operation needs a 2nd factor or can be approved simply by
// tapping an approve button. If the operation requires 2FA, this value also hints if
// the user may use the biometry, or if a password is required.
val allowedSignatureType: AllowedSignatureType
}
```

Definition of `FormData`:

```kotlin
class FormData {

/// Title of the operation
val title: String

/// Message for the user
val message: String

/// Other attributes.
///
/// Each attribute presents one line in the UI. Attributes are differentiated by type property
/// and specific classes such as NoteAttribute or AmountAttribute.
val attributes: List<Attribute>
}
```

Attributes types:
- `AMOUNT` like "100.00 CZK"
- `KEY_VALUE` any key value pair
- `NOTE` just like keyValue, emphasizing that the value is a note or message
- `HEADING` single highlighted text, written in a larger font, used as a section heading
- `PARTY_INFO` providing structured information about third party data (for example known eshop)

### Push Messages

Expand All @@ -226,7 +299,7 @@ To register PowerAuth enabled application to receive push notifications, use one

#### Extension Factory With SSL Validation Strategy

This factory method will create its own `OkHttpClient` instance based on the chosen SSL validation strategy.
This factory method will create its own [`OkHttpClient`](https://square.github.io/okhttp/) instance based on the chosen SSL validation strategy.

```kotlin
fun PowerAuthSDK.createPushService(appContext: Context, baseURL: String, strategy: SSLValidationStrategy): IPushService
Expand All @@ -246,7 +319,7 @@ fun PowerAuthSDK.createPushService(appContext: Context, baseURL: String, httpCli
```
- `appContext` - application context
- `baseURL` - address, where your operations server can be reached
- `httpClient` - `OkHttpClient` instance used for API requests
- `httpClient` - [`OkHttpClient`](https://square.github.io/okhttp/) instance used for API requests

#### Registering to Push Notifications

Expand Down Expand Up @@ -282,11 +355,11 @@ All available methods of the `IPushService` API are:
- `fcmToken` - Firebase Cloud Messaging token.
- `listener` - Called request finishes

For more details on the API, visit [`IPushService` code documentation](https://github.com/wultra/mtoken-sdk-android/blob/master/library/src/main/java/com/wultra/android/mtokensdk/push/IPushService.kt).
For more details on the API, visit [`IPushService` code documentation](https://github.com/wultra/mtoken-sdk-android/blob/develop/library/src/main/java/com/wultra/android/mtokensdk/push/IPushService.kt#docucheck-keep-link).

### Error Handling

All methods that communicate with server APIs return an [`ApiError`](https://github.com/wultra/mtoken-sdk-android/blob/master/library/src/main/java/com/wultra/android/mtokensdk/api/general/ApiError.kt) instance in case of an error.
All methods that communicate with server APIs return an [`ApiError`](https://github.com/wultra/mtoken-sdk-android/blob/develop/library/src/main/java/com/wultra/android/mtokensdk/api/general/ApiError.kt#docucheck-keep-link) instance in case of an error.
Every API error contains an original exception that was thrown, and a convenience error property for known API error states (for example, if the operation is already canceled during approval).

## License
Expand Down
2 changes: 1 addition & 1 deletion library/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
# and limitations under the License.
#

VERSION_NAME=1.0.1
VERSION_NAME=1.1.0
GROUP_ID=com.wultra.android.mtokensdk
ARTIFACT_ID=wultra-mtoken-sdk
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,20 @@ internal class AttributeTypeAdapter : TypeAdapter<Attribute>() {
val type = attrMap["type"]
val id = attrMap["id"]
val label = attrMap["label"]

val labelObject = if(id != null && label != null) {
Attribute.Label(id, label)
} else {
null
}

when (type) {
"AMOUNT" -> return AmountAttribute(id, label, BigDecimal(attrMap["amount"]), attrMap["currency"], attrMap["amountFormatted"], attrMap["currencyFormatted"])
"KEY_VALUE" -> return KeyValueAttribute(id, label, attrMap["value"])
"NOTE" -> return NoteAttribute(id, label, attrMap["note"])
"HEADING" -> return HeadingAttribute(id, label)
"AMOUNT" -> return AmountAttribute(BigDecimal(attrMap["amount"]), attrMap["currency"], attrMap["amountFormatted"], attrMap["currencyFormatted"], labelObject)
"KEY_VALUE" -> return KeyValueAttribute(attrMap["value"], labelObject)
"NOTE" -> return NoteAttribute(attrMap["note"], labelObject)
"HEADING" -> return HeadingAttribute(labelObject)
"PARTY_INFO" -> {
return PartyInfoAttribute(id, label, PartyInfo(partyInfoMap))
return PartyInfoAttribute(PartyInfoAttribute.PartyInfo(partyInfoMap), labelObject)
}
}
return null
Expand Down

This file was deleted.

Loading

0 comments on commit 77d9eab

Please sign in to comment.