mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
android: Update auth URLs to follow convention; Fix JNI callback method signatures (#1870)
This commit is contained in:
@@ -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}"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 -> {}
|
||||
|
||||
@@ -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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ internal class WebViewViewModel @Inject constructor(
|
||||
.collect {
|
||||
actionMutableLiveData.postValue(
|
||||
WebViewViewAction.FillPortalUrl(
|
||||
url = "${it.portalUrl}/auth"
|
||||
url = "${it.portalUrl}/sign_in"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)],
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user