Rebar Android Data in Transit

Monkton, Inc. 2019

Part of Rebar's compliance with NIAP and other associated security profiles is adherence to the API Boundary for Data in Transit (DIT). DIT compliance for the app is achieved by leveraging Rebar's network interfaces.

Rebar's implementation of TLS is completely transparent to users when making Web Service calls. Rebar provides a set of classes we call "Wrappers" that wrap Web Service calls over TLS. To invoke Wrappers, we leverage the App Model paradigm available in Android. Models have replaced Loaders for performing background and long running tasks.

Web Service Configuration

Rebar's io.monkton.rebar.wrapper.RestfulWrapper relies on interacting with the Rebar ESB. The Rebar ESB acts as a secure proxy to backend web services within your system, leveraging authentication mechanisms like JWT.

The ESB allows you to define web service connections to backend systems. Those hooks can be accessed within your app with the RestfulWrapper class by simply calling the Web API methods.

The RestfulWrapper class provides common functionality like post, put, and get you'd expect for HTTP calls.

Leveraging RestfulWrapper

RestfulWrapper encapsulates all the functionality necessary to make secure HTTPS calls over TLS using NIAP compliant algorithms. The implementation ensures that simple calls are necessary to invoke server API methods.

The RestfulWrapper is intended to be used with the Rebar's API Endpoint for APIs.

With the API Endpoints, all that needs to be specified as the URL value is the Usable API Path from the Endpoint screen.

class RebarAppWrapper : RestfulWrapper() {	

	/**
		Perform a server GET
	*/
	func myGet(): ServiceResult {
		return get("api/demoapp/my-get-method", nil);
	}
	
	/**
		Perform a server PUT
	*/	
    fun myPut(context: Context): ServiceResult {
        return put(context, "api/demoapp/my-put-method", RestfulWrapper.MIME_TYPE_JSON, null, null)
    }
	
	/**
		Perform a server POST
	*/
	func myCreate(email: String!, password: String?, fullName: String?) {
		val credentials = JSONObject()
				
        return put(context, "api/demoapp/add-some-account", RestfulWrapper.MIME_TYPE_JSON, null, credentials)
	}
	
}

Models

Models are the new way in Android to invoke resources in an MVC manner, which can be very helpful for calling and invoking Web Services. Rebar itself provides a root model class for Wrappers, the io.monkton.rebar.models.JsonViewModel class.

This class has core functionality to perform JSON based services.

For example, this SyncModel class exposes a sync method:

class SyncModel : JsonViewModel() {

    /**
     * Instantiates our wrapper class when necessary
     */
    override fun instantiateWrapper() {
        this.httpWrapper = SyncWrapper()
    }

    /**
     * Performs the user login
     */
    fun sync() {
        // Calls the sync method in the wrapper 
        // with 'execute' which performs the operation off the main thread
        this.execute {
            (this.httpWrapper as SyncWrapper).sync()
        }
    }

}

Thus when we add this Model to an Activity, in this case our MainActivity class, we see that it can be invoked rather easily with data being returned to the finishLoading method


class MainActivity : AuthenticatedActivity() {

    // Our model for performing sync activities
    var appModel: SyncModel? = null

    /**
     * The button that will perform our syncing action
     */
    val syncButton: Button
        get() { return this.findViewById<Button>(R.id.rebar_sync) as Button }

    /**
     * Configures the view and lifecycle. We use models to perform background activities.
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Configure the view
        setContentView(R.layout.activity_main)

        // Grab the reference to the app model we will use in this activity
        this.appModel = ViewModelProviders.of(this).get(SyncModel::class.java)

        // Listen for the current response to change from our HTTP request
        this.appModel!!.requestResponse.observe(this, Observer {
            data ->
            this.finishLoading(data)
        })

        // When the user taps the button - using the Rebar Extension for tapped
        syncButton.tapped {
            this.sync()
        }

    }

    /**
     * Performs the syncing operation
     */
    fun sync() {
        // Sync with our model. sync will automatically push the request 
        // off the main thread when we execute it. 
        this.appModel!!.sync()
    }

    @SuppressWarnings("unused")
    private fun finishLoading(result: JsonDataResult?) {
    
        // If this isn't run on the UI thread, bad things will happen
        this.runOnUiThread {

            // Can we process this request?
            if (result!!.wasSuccess && !result.hadError()) {
                // Continue with login
            }

        }

    }

}

While Wrappers can be invoked directly, doing so within the Model framework ensures that Wrappers live past activities being created and destroyed.

Last Updated: February 04, 2019