Add experimental WebAuthn support for Nightly only

When testing out WebAuthn support with the privileged API,
we need our app to be signed by an allowed signing key.

We're seeing our tests fail with this error when testing locally:

```
  [FidoApiImpl] updateTransaction is called for stop
  [FidoApiImpl] finishSecurityKeyRequestController should not be called when SecurityKeyRequestController is null.
```

Our theory is that if we try this code on our signed APK, we should see
it work.
upstream-sync
Jonathan Almeida 3 years ago committed by Jonathan Almeida
parent f8ea4c5ca1
commit 6dfd7ef757

@ -56,4 +56,9 @@ object FeatureFlags {
* Enabled showing site permission indicators in the toolbars.
*/
val permissionIndicatorsToolbar = Config.channel.isNightlyOrDebug
/**
* Enables experimental WebAuthn support. This implementation should never reach release!
*/
val webAuthFeature = Config.channel.isNightlyOrDebug
}

@ -173,6 +173,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler,
private var fullScreenMediaSessionFeature =
ViewBoundFeatureWrapper<MediaSessionFullscreenFeature>()
private val searchFeature = ViewBoundFeatureWrapper<SearchFeature>()
private val webAuthnFeature = ViewBoundFeatureWrapper<WebAuthnFeature>()
private var pipFeature: PictureInPictureFeature? = null
var customTabSessionId: String? = null
@ -639,6 +640,17 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler,
view = view
)
if (FeatureFlags.webAuthFeature) {
webAuthnFeature.set(
feature = WebAuthnFeature(
engine = requireComponents.core.engine,
activity = requireActivity()
),
owner = this,
view = view
)
}
context.settings().setSitePermissionSettingListener(viewLifecycleOwner) {
// If the user connects to WIFI while on the BrowserFragment, this will update the
// SitePermissionsRules (specifically autoplay) accordingly
@ -1024,7 +1036,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler,
* Forwards activity results to the prompt feature.
*/
final override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
promptsFeature.withFeature { it.onActivityResult(requestCode, resultCode, data) }
listOf(
promptsFeature,
webAuthnFeature
).any { it.onActivityResult(requestCode, resultCode, data) }
}
/**

@ -0,0 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.browser
import android.app.Activity
import android.content.Intent
import android.content.IntentSender
import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.activity.ActivityDelegate
import mozilla.components.support.base.feature.ActivityResultHandler
import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.base.log.logger.Logger
/**
* This implementation of the WebAuthnFeature is only for testing in a nightly signed build.
*
* This should always be behind the [FeatureFlags.webAuthFeature] nightly flag.
*/
class WebAuthnFeature(
private val engine: Engine,
private val activity: Activity
) : LifecycleAwareFeature, ActivityResultHandler {
val logger = Logger("WebAuthnFeature")
var requestCode = ACTIVITY_REQUEST_CODE
var resultCallback: ((Intent?) -> Unit)? = null
private val delegate = object : ActivityDelegate {
override fun startIntentSenderForResult(intent: IntentSender, onResult: (Intent?) -> Unit) {
val code = requestCode++
logger.info("Received activity delegate request with code: $code intent: $intent")
activity.startIntentSenderForResult(intent, code, null, 0, 0, 0)
resultCallback = onResult
}
}
override fun start() {
logger.info("Feature started.")
engine.registerActivityDelegate(delegate)
}
override fun stop() {
logger.info("Feature stopped.")
engine.unregisterActivityDelegate()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
logger.info("Received activity result with code: $requestCode\ndata: $data")
if (this.requestCode == requestCode) {
logger.info("Invoking callback!")
resultCallback?.invoke(data)
return true
}
return false
}
companion object {
const val ACTIVITY_REQUEST_CODE = 1337
}
}
Loading…
Cancel
Save