Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
210 lines (172 sloc) 12.4 KB

Civic App Connect library documentation

Quickstart

Civic App Connect is an Android library which is used to connect to Civic’s Secure Identity Platform (SIP) and to the Civic Android App. It will enable you to connect to your users by allowing users to give your app access to their data in a safe and secure way from the Civic Android app. In addition the information has been attested and verified.

Your app includes a Connect with Civic button. When the user presses this button, the Civic Android app will open, if it is installed, and provide the user a way to authorise the sharing of their data. Your app information is displayed on the Civic App so that the user can see clearly who will be receiving the data. Once the user presses authorise, they are returned to your app. The library will then be able to retrieve the user data and provide it to your app.

If the Civic App is not installed when the user presses the Connect with Civic button, they will be redirected to the play store to install the Civic Android app.

Register your app

  1. Go to the Civic Integration Portal website and log in or create a new user.
  2. Create a new app providing the information required.
  3. Provide your package name as the Application Id when configuring the app on the website. Make a sure that the ApplicationId corresponds to your Application id or package name that your app uses. If you are unsure what this is look at the BuildConfig.APPLICATION_ID value in your compiled app.
  4. The Civic Integration Portal will provide an AppId. Make a note if this AppId. You will need this info to intialise the library.
  5. The Civic Integration Portal will provide an App Secret. Make a note of this App Secret. You will need this info to intialise the library.

Add the library to build.gradle

Make sure you are using the Jcenter repositories

buildscript {
    repositories {
        jcenter()
    }
}

Add the library dependency to the dependency list of your app

    dependencies {
        implementation "com.civic:civic-connect-library:${civic_connect_library_version}"
    }

The latest version can be found by searching for the library on the bintray/jcenter website.

Add app details to strings

Provide a way for your app to include the AppId and the secret. This can be done as an inclusion to your build file from your CI server buildconfig. One way to do this is to define a

        buildConfigField "String", "APP_ID", "\"your app id goes here\""
        buildConfigField "String", "SECRET", "\"your secret goes here\""

This will allow you to access the APP_ID and SECRET from the code with BuildConfig.APP_ID and BuildConfig.SECRET

Initialise the library

Create a new Application class to initialise the Civic App Connect library or add the initialisation of the library to the onCreate() method of your Application class if it already exists.

class YourApp : Application() {
    override fun onCreate() {
        super.onCreate()
        CivicConnect.initialise(this, BuildConfig.APP_ID, BuildConfig.SECRET)
    }

}

Make sure the application will be used by adding it to the Manifest.xml of the project

<application android:name=".YourApp"/>

The initialisation call is done in the Application class so that it is always set up and ready to use. It is possible to do this call in the activity before you use it the first time if you prefer.

NOTE: if you do not initialise CivicConnect it will throw an exception when you try to use it.

Add CivicConnectViewModel to your Activity

Civic provides a ViewModel class to access the library. Using the view model you will have access to the state of the connection process as well as the user data when it becomes available using LiveData lightweight observers. In addition it is possible to access the library directly without using the ViewModel if your implementation requires it. See the section alternatives for more information.

Add viewmodel

    private lateinit var viewModel: CivicConnectViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState
        viewModel = ViewModelProviders.of(this).get(CivicConnectViewModel::class.java)
        //include rest of onCreate code
      }

Add observers for the state, error messages and UserData. The possible states of the connection process are described by the ConnectState enumerator. The possible error codes are described by the CivicErrorCode enumerator. Each of these enumerators have a description field which describes the item.

private val stateObserver: Observer<ConnectState> = Observer {
     textStatus.text = it?.description
     // use the state to provide feedback for the user
 }

 private val errorObserver: Observer<CivicErrorCode> = Observer {
     textError.text = it?.description
     // show error state
 }

 private val errorMessageObserver: Observer<String> = Observer {
     textError.text = it
     // show the error message
 }

 private val userDataObserver: Observer<UserData> = Observer {
     // it variable contains the UserData
 }

 override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       //get the viewModel from the ViewModelProviders
       viewModel = ViewModelProviders.of(this).get(CivicConnectViewModel::class.java)

       // observe the state of the connection
       viewModel.getConnectState().observe(this, stateObserver)

       // observe errors
       viewModel.getError().observe(this, errorObserver)

       // observe additional error messages - optional
       viewModel.getErrorMessage().observe(this, errorMessageObserver)

       // observe changes in the user data
       viewModel.getUserData().observe(this, userDataObserver)

       // onCreate code
   }

Add a button

Add a button to your activity layout. This button initiates the connection request. You can use the Civic App Connect style to create a button that follows the Civic brand guidelines. In the onClick handler of the button call the connect method on the viewModel. In this example it asks for the basic Civic information. Other VerificationLevels are available. See the Reference documentation on VerificationLevels for more information.

<Button
    android:id="@+id/connectButton"
    style="@style/ButtonCivic"
    android:onClick="connectWithCivic"/>

The onClick is handled by the connectWithCivic() method in the activity

fun connectWithCivic(@Suppress("UNUSED_PARAMETER") view: View) {
        viewModel.connect(this, VerificationLevels.CIVIC_BASIC)
    }

Handle incoming Intent

Make sure the activity can receive the intent from the Civic app by adding the intent information to to the Manifest.xml of the project. Make sure to use your packageName as recorded in the app registration in the first step as the scheme value.

<application>
  <activity
      android:name=".ConnectActivity"
      android:launchMode="singleTask">
      <intent-filter>
          <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />
          <data android:scheme="insert.package.name" android:host="authorise" />
      </intent-filter>
  </activity>
</application>

Then handle the intent in the activity and call the authorize method on the viewModel by adding the following code:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Add other onCreate code here including code to setup the view model
    checkIntent(intent)
}

private fun checkIntent(intent: Intent?) {
     intent?.let {
         if (Intent.ACTION_VIEW == intent.action) {
             // this is a call from the civic app authorising the scope request
             val uri = intent.data
             val uuid = uri?.getQueryParameter("uuid") ?: "no uuid param"
             viewModel.authorise(uuid)
         }
     }
 }

 override fun onNewIntent(intent: Intent?) {
     checkIntent(intent)
     super.onNewIntent(intent)
 }

Access user data

The observer that is placed on the user data will update as soon as the user data is available. The UserData is provided in a UserData class. The UserData class contains a list of data items. An example data item could look like this: DataItem(label="contact.personal.email", value="someemail@example.com", isValid=true, isOwner=true) The UserData also contains a unique userId string.

Fetch Token

If you would prefer to use a token, you can set a flag in the authorise method indicating that you want access to the JWT Token. In this case you can initialise the library with an empty secret as it only needs the secret to decrypt the user data. The library will only fetch the token but will NOT fetch the user data. It will return state TOKEN_AVAILABLE as soon as the token is available. At this point the token data can be retrieved using the CivicConnect.getToken() method. The CivicConnectViewModel also has a token observer to provide the token data. The partner app can now pass the token to a backend to retrieve the data. Please note: The token expires if it is used once, it can not be re-used.

Error handling and state - Fetch user data

Civic App Connect States The happy path state change flow is NONE->FETCHING_SCOPE_REQUEST->WAITING_AUTHORISE at this point the library is waiting for the user to interact with the civic app and authorise the release of the data. Once this is done the states change to WAITING_FOR_TOKEN->FETCHING_USER_DATA->USER_DATA_AVAILABLE. Once the state is USER_DATA_AVAILABLE then the user data is available for consumption by the partner app. If an error occurs along the way the state goes to ERROR, the error code is set and the error message is set. If the reset() method is called the state is reset to NONE.

Error handling and state - Fetch token only

Civic App Connect States Token For the case where only the token is retrieved the the happy path state change flow is NONE->FETCHING_SCOPE_REQUEST->WAITING_AUTHORISE at this point the library is waiting for the user to interact with the civic app and authorise the release of the data. Once this is done the states change to WAITING_FOR_TOKEN->TOKEN_AVAILABLE. Once the state is TOKEN_AVAILABLE then the token is available for consumption by the partner app. The user data will NOT be retrieved. If an error occurs along the way the state goes to ERROR, the error code is set and the error message is set. If the reset() method is called the state is reset to NONE.

Verification levels

The VerificationLevels enum contains all the possible verification levels that can be requested by the app. Civic Basic verification gives the email and mobile number. Anonymous login gives no information besides a unique identifier. All verification levels give the unique identifier. There is an example of the use of the different verification levels in the sample app.

Reset

The connection request can be reset by calling the reset method on the viewModel or the library.

viewModel.reset()

Alternative connect method

If your app architecture does not use view models, the connect process can be triggered directly on the library. If the library is accessed in this way a call back object must be provided to track the connection event and errors. State changes and error events will be reported in a callback. In addition any state, error, error message or user data can be queried. If the library is included in this manner the activity refresh and state handling has to be implemented using the existing architecture of your app.

The calls required to use the library are in order, initialise, connect and then authorize once the user has authorized. The user data can be queried with the getUserData method.

See the reference documentation for the detail on the calls and required parameters.

Sample app

A complete sample implementation showing both integration methods can be found in the sample app. The sample app is in the /sample module.

Reference

Complete library reference