Migration to OAuth 2

Server Migration

OpenSRP supports two types of OAuth 2 setups/configurations

  • Server v2.1+ which uses OpenMRS

  • Server v2.2+ which uses Keycloak

To learn how to deploy your server with OAuth 2 enabled see Single Sign on and Oauth2 support

Once deployed, the OAuth Client ID and Client Secret will be generated in the opensrp.properties

Client Migration

Here are the steps required to migrate your OpenSRP android client to use OAuth 2 for authentication.

  1. In your implementation include the version 2 dependency of client core

implementation('org.smartregister:opensrp-client-core:2.0.6-SNAPSHOT@aar') { transitive = true ...

2. In your project’s build.gradle file, add the following code block after the buildConfigField entries in the defaultConfig block

if (project.rootProject.file("local.properties").exists()) { Properties properties = new Properties() properties.load(project.rootProject.file("local.properties").newDataInputStream()) if (properties != null && properties.containsKey("oauth.client.id")) { buildConfigField "String", "OAUTH_CLIENT_ID", properties["oauth.client.id"] } else { project.logger.error("oauth.client.id variable is not set in your local.properties") buildConfigField "String", "OAUTH_CLIENT_ID", "\"sample_client_id\"" } if (properties != null && properties.containsKey("oauth.client.secret")) { buildConfigField "String", "OAUTH_CLIENT_SECRET", properties["oauth.client.secret"] } else { project.logger.error("oauth.client.secret variable is not set in your local.properties") buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"sample_client_secret\"" } }

 

3. In your project's local.properties file add the following entry. These values are the client id and secret as set up on your OpenSRP server.properties file.

oauth.client.id="your client identifier"
oauth.client.secret="your oauth client secret"

NB: You need to include the quotes for this to work correctly

4. In your application, from the class that inherits DrishtiApplication.java class, remove the following code block. This should now be delegated to super.

public String getPassword() { if (password == null) { String username = getContext().userService().getAllSharedPreferences().fetchRegisteredANM(); password = getContext().userService().getGroupId(username); } return password; }

5. In your application's Configuration class (Class that extends core’s SyncConfiguration), you need to override the following methods

6. In your application(or sample app) , under the path src/main/res/xml/ create a file like this and name it authenticator.xml.

Remember to change the org.smartregister.xxx with the actual package signature of your app

Other updates

Core version 2.0 also includes FHIR dependencies which have functionality that requires a minimum Android O (API 26). To get around this you need to exclude these features from being included at compile time. The steps for this workaround are :

  1. In your project's root build.gradle file, add the following dependency to the build script dependencies

2. In your project’s module build.gradle, add the following plugin

apply plugin: 'org.smartregister.gradle.jarjar'

3. You then need to exclude the ibm fhir dependencies and include those compiled via jarjar. All the dependency updates for your app module’s build.gradle should now be the following.

4. On the same app module’s build.gradle script, under the default config block, add

javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true

If you already have an annotationsProcessorOptions block, set the includeCompileClasspath field totrue

5. Finally on the same app module build.gradle script, add the following lines to exclude duplicate files within the packagingOptions block

 

This is required because client core now contains these dependencies which contain annotation processor and thus need to be added to the annotationProcessor configuration

6. If you find tests are failing with Underlying exception : java.lang.TypeNotPresentException: Type com.ibm.fhir.model.resource.Patient not present try adding:

testImplementation 'com.ibm.fhir:fhir-model:4.2.3'

7. Ensure Guava dependency is included i.e. remove exclude group: 'com.google.guava', module: 'guava' from the client core dependency block.

8. Code refactor

At this point, a few areas of the code base will break due to the major version change in the core library but these should be easy to resolve. Refactor as follows.

a) Domain classes are now part of the plan evaluator dependency which is on client-core.

b) Any references to getPassword() should now return a byte[] as parameter.

c) Most methods in the UserService class are now dependent on the current logged in user, e.g.

d) SmartRegisterQueryBuilder method queryBuilder.SelectInitiateMainTable( is now queryBuilder.selectInitiateMainTable(

e) For any class that extends BaseRegisterActivity from core and invokes method startFormActivity( ,

update the null parameter for your metadata to an empty string