Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality for scanning pre-login QR codes from the SEP UI #147

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ dependencies {
implementation "org.radarbase:radar-android-weather:$radar_commons_android_version"
implementation "org.radarbase:radar-android-audio:$radar_commons_android_version"
implementation "org.radarbase:radar-android-faros:$radar_commons_android_version"
implementation "org.radarbase:radar-android-login-oauth2:$radar_commons_android_version"
implementation "org.radarbase:radar-android-polar:$radar_commons_android_version"
implementation "org.radarbase:radar-android-google-sleep:$radar_commons_android_version"
implementation "org.radarbase:radar-android-google-activity:$radar_commons_android_version"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/radarcns/detail/AuthServiceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package org.radarcns.detail
import org.radarbase.android.auth.AppAuthState
import org.radarbase.android.auth.AuthService
import org.radarbase.android.auth.LoginManager
import org.radarbase.android.auth.oauth2.OAuth2LoginManager
import org.radarbase.android.auth.portal.ManagementPortalLoginManager

class AuthServiceImpl : AuthService() {
override fun createLoginManagers(appAuth: AppAuthState): List<LoginManager> = listOf(
ManagementPortalLoginManager(this, appAuth),
OAuth2LoginManager(this, appAuth)
)

override fun showLoginNotification() = Unit
Expand Down
77 changes: 66 additions & 11 deletions app/src/main/java/org/radarcns/detail/LoginActivityImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.json.JSONObject
import org.radarbase.android.RadarApplication.Companion.radarConfig
import org.radarbase.android.RadarConfiguration.Companion.BASE_URL_KEY
import org.radarbase.android.auth.*
import org.radarbase.android.auth.oauth2.OAuth2LoginManager
import org.radarbase.android.auth.portal.ManagementPortalLoginManager
import org.radarbase.android.util.Boast
import org.radarbase.android.util.NetworkConnectedReceiver
Expand All @@ -61,7 +62,8 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne

private lateinit var binding: ActivityLoginBinding

private lateinit var qrCodeScanner: QrCodeScanner
private lateinit var mpQrCodeScanner: QrCodeScanner
private lateinit var sepQrCodeScanner: QrCodeScanner
private lateinit var dialog: Dialog

private lateinit var mainHandler: Handler
Expand All @@ -76,13 +78,18 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne

networkReceiver = NetworkConnectedReceiver(this, this)
didCreate = true
qrCodeScanner = QrCodeScanner(this) { value ->
mpQrCodeScanner = QrCodeScanner(this) { value ->
value?.takeTrimmedIfNotEmpty()
?.also { parseQrCode(it) }
?.also { parseMpQrCode(it) }
}
sepQrCodeScanner = QrCodeScanner(this) { value ->
value?.takeTrimmedIfNotEmpty()
?.also { parseSepQrCode(it) }
}

with(binding) {
scanButton.setOnClickListener { v -> scan(v) }
mpScanButton.setOnClickListener { v -> scanQrFromMP(v) }
sepScanButton.setOnClickListener { scanQrFromSEP() }
enterCredentialsButton.setOnClickListener { v -> enterCredentials(v) }
loader.visibility = View.GONE
}
Expand All @@ -102,7 +109,7 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne
networkReceiver.run { unregister() }
}

private fun parseQrCode(qrCode: String) {
private fun parseMpQrCode(qrCode: String) {
onProcessing()
logger.info("Read tokenUrl: {}", qrCode)

Expand Down Expand Up @@ -142,6 +149,33 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne
}
}

private fun parseSepQrCode(qrData: String) {
onProcessing()
logger.debug("Processing data from QR code {}", qrData)

if (qrData.isEmpty()) {
loginFailed(null, QrException("QR code is empty. Please retry"))
logger.error("QR code is empty. Please retry")
return
}

applyOAuthManager { binder, oAuthManager, authState ->
if (qrData.startsWith('{')) {
try {
oAuthManager.parsePreLoginQr(authState, qrData)
} catch (ex: Exception) {
loginFailed(oAuthManager, ex)
return@applyOAuthManager
}
} else {
// QR code should have data in JSON format if scanning from SEP UI
loginFailed(oAuthManager, QrException("QR code doesn't contains the data in JSON format"))
return@applyOAuthManager
}
binder.update(oAuthManager)
}
}

private fun applyMpManager(callback: (AuthService.AuthServiceBinder, ManagementPortalLoginManager, AppAuthState) -> Unit) {
authConnection.applyBinder {
val manager = managers.find { it is ManagementPortalLoginManager }
Expand All @@ -152,6 +186,16 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne
}
}

private fun applyOAuthManager(callback: (AuthService.AuthServiceBinder, OAuth2LoginManager, AppAuthState) -> Unit) {
authConnection.applyBinder {
val oauthManager = managers.find { it is OAuth2LoginManager }
as? OAuth2LoginManager ?: return@applyBinder
applyState {
callback(this@applyBinder, oauthManager, this)
}
}
}

private fun onProcessing() {
setLoader(true)
}
Expand All @@ -171,20 +215,29 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne

private fun checkNetworkConnection() = with(binding) {
if (networkIsConnected) {
scanButton.isEnabled = true
mpScanButton.isEnabled = true
sepScanButton.isEnabled = true
enterCredentialsButton.isEnabled = true
messageText.text = ""
} else {
scanButton.isEnabled = false
mpScanButton.isEnabled = false
sepScanButton.isEnabled = false
enterCredentialsButton.isEnabled = false
messageText.setText(R.string.no_connection)
}
}

private fun scan(@Suppress("UNUSED_PARAMETER") view: View) {
private fun scanQrFromMP(@Suppress("UNUSED_PARAMETER") view: View) {
if (canLogin) {
canLogin = false
mpQrCodeScanner.start()
}
}

private fun scanQrFromSEP() {
if (canLogin) {
canLogin = false
qrCodeScanner.start()
sepQrCodeScanner.start()
}
}

Expand Down Expand Up @@ -330,11 +383,13 @@ class LoginActivityImpl : LoginActivity(), NetworkConnectedReceiver.NetworkConne

private fun setLoader(show: Boolean) = with(binding) {
if (show) {
scanButton.visibility = View.GONE
mpScanButton.visibility = View.GONE
sepScanButton.visibility = View.GONE
enterCredentialsButton.visibility = View.GONE
loader.visibility = View.VISIBLE
} else {
scanButton.visibility = View.VISIBLE
mpScanButton.visibility = View.VISIBLE
sepScanButton.visibility = View.VISIBLE
enterCredentialsButton.visibility = View.VISIBLE
loader.visibility = View.GONE
}
Expand Down
36 changes: 32 additions & 4 deletions app/src/main/res/layout/activity_login.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,25 @@
android:padding="@dimen/size_medium">

<TextView
android:id="@+id/mp_login_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/size_xlarge"
android:text="@string/login_title"
android:text="@string/mp_login_title"
style="@style/TextAppearance.MaterialComponents.Headline6" />

<TextView
android:id="@+id/input_user_id"
android:id="@+id/mp_login_info"
style="@style/TextAppearance.MaterialComponents.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/size_small"
android:gravity="center"
android:text="@string/login_description"
android:text="@string/mp_login_description"
android:textAlignment="center" />

<com.google.android.material.button.MaterialButton
android:id="@+id/scan_button"
android:id="@+id/mp_scan_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/size_xxlarge"
Expand All @@ -76,6 +77,33 @@
android:paddingHorizontal="@dimen/size_xxlarge"
android:layout_marginTop="@dimen/size_small"
android:text="@string/enter_credentials" />

<TextView
android:id="@+id/sep_login_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/size_xlarge"
android:text="@string/sep_login_title"
style="@style/TextAppearance.MaterialComponents.Headline6" />

<TextView
android:id="@+id/sep_login_info"
style="@style/TextAppearance.MaterialComponents.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/size_small"
android:gravity="center"
android:text="@string/sep_login_description"
android:textAlignment="center" />

<com.google.android.material.button.MaterialButton
android:id="@+id/sep_scan_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/size_xxlarge"
android:layout_marginTop="@dimen/size_medium"
android:text="@string/scan_qr_button" />

<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/loader"
android:layout_width="wrap_content"
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,10 @@
<string name="start_downloading">Download and Install</string>
<string name="update_question" />
<string name="error_in_package_name">Error in package name!</string>
<string name="login_description">Log in to pRMT App with the QR Code or Token provided to you.</string>
<string name="login_title">Login</string>
<string name="mp_login_description">Log in to pRMT App with the QR Code or Token provided to you by Management Portal.</string>
<string name="sep_login_description">Log in to pRMT App with the QR Code provided to you by Self Enrolment Portal.</string>
<string name="mp_login_title">Login With Management Portal</string>
<string name="sep_login_title">Login With SEP-UI</string>
<string name="title_activity_item_detail_host">ItemDetailHostActivity</string>
<string name="title_item_list">Items</string>
<string name="title_item_detail">Item Detail</string>
Expand Down
Loading