android: Update auth URLs to follow convention; Fix JNI callback method signatures (#1870)

This commit is contained in:
Jamil
2023-08-09 06:47:25 -05:00
committed by GitHub
parent dbc572a8ef
commit 01906ba507
11 changed files with 51 additions and 60 deletions

View File

@@ -7,14 +7,14 @@ require 'sinatra'
set :bind, '0.0.0.0'
set :port, 4568
get '/auth' do
get '/:slug/sign_in' do
csrfToken = params['client_csrf_token']
dest = params['dest']
ERB.new("<h1>Auth page</h1><a href=\"/redirect?client_csrf_token=#{csrfToken}&dest=#{dest}\">Proceed</a>").result(binding)
ERB.new("<h1>Auth page</h1><a href=\"/redirect?client_csrf_token=#{csrfToken}\">Proceed</a>")
.result(binding)
end
get '/redirect' do
dest = params['dest']
dest = 'https://app.firez.one/handle_client_auth_callback'
csrfToken = params['client_csrf_token']
authToken = File.read(File.join(__dir__, 'data', 'jwt'))
redirect "#{dest}?client_csrf_token=#{csrfToken}&client_auth_token=#{authToken}"

View File

@@ -46,27 +46,14 @@
android:exported="true"
android:launchMode="singleTop">
<!-- Using deeplink until applinks is setup -->
<!--<intent-filter android:label="AppLink">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="firezone.dev" android:pathPrefix="/auth" />
</intent-filter>-->
<intent-filter
android:label="@string/app_name"
android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="${hostName}" />
<data android:scheme="https" android:host="${hostName}" />
</intent-filter>
</activity>
@@ -78,16 +65,15 @@
<action android:name="android.net.VpnService" />
</intent-filter>
</service>
<!-- Causes cli builds to fail with lint error "Error: This class should provide a default constructor (a public constructor with no arguments"
<receiver
android:name=".features.session.backend.BootShutdownReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
-->
<receiver
android:name="dev.firezone.android.features.session.backend.BootShutdownReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -42,10 +42,4 @@ object AppModule {
internal fun provideSessionManager(
sharedPreferences: SharedPreferences
): SessionManager = SessionManager(sharedPreferences)
@Provides
internal fun provideBroadcastReceiver(
@MainImmediateDispatcher coroutineDispatcher: CoroutineDispatcher,
sessionManager: SessionManager,
): BootShutdownReceiver = BootShutdownReceiver(coroutineDispatcher, sessionManager)
}

View File

@@ -2,6 +2,7 @@ package dev.firezone.android.features.applink.presentation
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import dagger.hilt.android.AndroidEntryPoint
@@ -27,6 +28,7 @@ class AppLinkHandlerActivity : AppCompatActivity(R.layout.activity_app_link_hand
when (action) {
is AppLinkViewAction.AuthFlowComplete -> {
// Continue with onboarding
Log.d("AppLinkHandlerActivity", "AuthFlowComplete")
}
is AppLinkViewAction.ShowError -> showError()
else -> {}

View File

@@ -1,6 +1,7 @@
package dev.firezone.android.features.applink.presentation
import android.content.Intent
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@@ -24,7 +25,7 @@ internal class AppLinkViewModel @Inject constructor(
fun parseAppLink(intent: Intent) {
viewModelScope.launch {
when (intent.data?.lastPathSegment) {
"callback" -> {
"handle_client_auth_callback" -> {
intent.data?.getQueryParameter("client_csrf_token")?.let { csrfToken ->
if (validateCsrfTokenUseCase(csrfToken).firstOrNull() == true) {
val jwtToken = intent.data?.getQueryParameter("client_auth_token") ?: ""
@@ -34,7 +35,9 @@ internal class AppLinkViewModel @Inject constructor(
}
}
}
else -> {}
else -> {
Log.d("AppLink", "Unknown path segment: ${intent.data?.lastPathSegment}")
}
}
}
}

View File

@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import java.util.Base64
import javax.inject.Inject
import kotlin.random.Random
import java.security.SecureRandom
internal class AuthRepositoryImpl @Inject constructor(
private val coroutineDispatcher: CoroutineDispatcher,
@@ -16,11 +16,10 @@ internal class AuthRepositoryImpl @Inject constructor(
) : AuthRepository {
override fun generateCsrfToken(): Flow<String> = flow {
val str = (1..CSRF_LENGTH)
.map { Random.nextInt(0, chars.size).let { chars[it] } }
.joinToString("")
val encodedStr: String = Base64.getEncoder().encodeToString(str.toByteArray())
val random = SecureRandom.getInstanceStrong()
val bytes = ByteArray(CSRF_LENGTH)
random.nextBytes(bytes)
val encodedStr: String = Base64.getEncoder().encodeToString(bytes)
sharedPreferences
.edit()
@@ -33,6 +32,5 @@ internal class AuthRepositoryImpl @Inject constructor(
companion object {
private const val CSRF_KEY = "csrf"
private const val CSRF_LENGTH = 24
private val chars : List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
}
}

View File

@@ -32,7 +32,7 @@ internal class AuthViewModel @Inject constructor(
actionMutableLiveData.postValue(
AuthViewAction.LaunchAuthFlow(
url = "${config.portalUrl}/auth?client_csrf_token=$token&dest=https://${BuildConfig.AUTH_DEST}/callback"
url = "${config.portalUrl}/sign_in?client_csrf_token=$token&client_platform=android"
)
)
}

View File

@@ -1,21 +1,22 @@
package dev.firezone.android.features.session.backend
import android.content.BroadcastReceiver
import android.util.Log
import android.content.Context
import android.content.Intent
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
internal class BootShutdownReceiver @Inject constructor(
private val coroutineDispatcher: CoroutineDispatcher,
private val sessionManager: SessionManager
) : BroadcastReceiver() {
internal class BootShutdownReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
sessionManager.connect()
Log.d("BootShutdownReceiver", "Boot completed. Attempting to connect.")
// TODO: Retrieve the session manager from the application context.
//sessionManager.connect()
} else if (Intent.ACTION_SHUTDOWN == intent.action) {
sessionManager.disconnect()
Log.d("BootShutdownReceiver", "Shutting down. Attempting to disconnect.")
// TODO: Retrieve the session manager from the application context.
// sessionManager.disconnect()
}
}
}

View File

@@ -2,6 +2,7 @@ package dev.firezone.android.features.session.presentation
import android.os.Bundle
import android.view.View
import android.util.Log
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
@@ -22,7 +23,7 @@ internal class SessionFragment : Fragment(R.layout.fragment_session) {
setupButtonListeners()
setupActionObservers()
Log.d("SessionViewModel", "Starting session...")
viewModel.startSession()
}

View File

@@ -40,7 +40,7 @@ internal class WebViewViewModel @Inject constructor(
.collect {
actionMutableLiveData.postValue(
WebViewViewAction.FillPortalUrl(
url = "${it.portalUrl}/auth"
url = "${it.portalUrl}/sign_in"
)
)
}

View File

@@ -125,7 +125,7 @@ impl Callbacks for CallbackHandler {
&mut env,
&self.callback_handler,
"onSetInterfaceConfig",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
&[
JValue::from(&tunnel_address_v4),
JValue::from(&tunnel_address_v6),
@@ -138,7 +138,13 @@ impl Callbacks for CallbackHandler {
fn on_tunnel_ready(&self) -> Result<(), Self::Error> {
self.env(|mut env| {
call_method(&mut env, &self.callback_handler, "onTunnelReady", "()", &[])
call_method(
&mut env,
&self.callback_handler,
"onTunnelReady",
"()Z",
&[],
)
})
}
@@ -154,7 +160,7 @@ impl Callbacks for CallbackHandler {
&mut env,
&self.callback_handler,
"onAddRoute",
"(Ljava/lang/String;)",
"(Ljava/lang/String;)V",
&[JValue::from(&route)],
)
})
@@ -172,7 +178,7 @@ impl Callbacks for CallbackHandler {
&mut env,
&self.callback_handler,
"onRemoveRoute",
"(Ljava/lang/String;)",
"(Ljava/lang/String;)V",
&[JValue::from(&route)],
)
})
@@ -193,7 +199,7 @@ impl Callbacks for CallbackHandler {
&mut env,
&self.callback_handler,
"onUpdateResources",
"(Ljava/lang/String;)",
"(Ljava/lang/String;)V",
&[JValue::from(&resource_list)],
)
})
@@ -211,7 +217,7 @@ impl Callbacks for CallbackHandler {
&mut env,
&self.callback_handler,
"onDisconnect",
"(Ljava/lang/String;)",
"(Ljava/lang/String;)Z",
&[JValue::from(&error)],
)
})
@@ -229,7 +235,7 @@ impl Callbacks for CallbackHandler {
&mut env,
&self.callback_handler,
"onError",
"(Ljava/lang/String;)",
"(Ljava/lang/String;)Z",
&[JValue::from(&error)],
)
})