diff options
author | Aditya Wasan <adityawasan55@gmail.com> | 2023-12-31 18:25:55 -0500 |
---|---|---|
committer | Harsh Shandilya <me@msfjarvis.dev> | 2024-05-29 18:51:47 +0530 |
commit | c21681747a72a75dfacb60d6f1a60df98d724dfc (patch) | |
tree | 2a7f3c8aaa692f7cffeccb8fd23848a4bfc558a1 /passkeys/src | |
parent | eda8030ad01c4bf097651ce604e2ed5da92bdf13 (diff) |
feat: implement credential provider service for passkeys
Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
Diffstat (limited to 'passkeys/src')
21 files changed, 129 insertions, 267 deletions
diff --git a/passkeys/src/main/AndroidManifest.xml b/passkeys/src/main/AndroidManifest.xml index 7a44af6e..0436b903 100644 --- a/passkeys/src/main/AndroidManifest.xml +++ b/passkeys/src/main/AndroidManifest.xml @@ -1,12 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved. + ~ SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + --> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> - - <application - android:allowBackup="true" - android:icon="@mipmap/ic_launcher" - android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher_round" - android:supportsRtl="true" - android:theme="@style/Theme.APS" /> - + <application> + <service + android:name=".APSCredentialProviderService" + android:enabled="true" + android:exported="true" + android:label="Android Password Store" + android:permission="android.permission.BIND_CREDENTIAL_PROVIDER_SERVICE"> + <intent-filter> + <action android:name="android.service.credentials.CredentialProviderService" /> + </intent-filter> + <meta-data + android:name="android.credentials.provider" + android:resource="@xml/provider"/> + </service> + </application> </manifest>
\ No newline at end of file diff --git a/passkeys/src/main/java/app/passwordstore/passkeys/APSCredentialProviderService.kt b/passkeys/src/main/java/app/passwordstore/passkeys/APSCredentialProviderService.kt new file mode 100644 index 00000000..b9711a40 --- /dev/null +++ b/passkeys/src/main/java/app/passwordstore/passkeys/APSCredentialProviderService.kt @@ -0,0 +1,103 @@ +package app.passwordstore.passkeys + +import android.app.PendingIntent +import android.content.Intent +import android.os.Build +import android.os.CancellationSignal +import android.os.OutcomeReceiver +import androidx.annotation.RequiresApi +import androidx.credentials.exceptions.ClearCredentialException +import androidx.credentials.exceptions.CreateCredentialException +import androidx.credentials.exceptions.CreateCredentialUnknownException +import androidx.credentials.exceptions.GetCredentialException +import androidx.credentials.provider.BeginCreateCredentialRequest +import androidx.credentials.provider.BeginCreateCredentialResponse +import androidx.credentials.provider.BeginCreatePublicKeyCredentialRequest +import androidx.credentials.provider.BeginGetCredentialRequest +import androidx.credentials.provider.BeginGetCredentialResponse +import androidx.credentials.provider.CreateEntry +import androidx.credentials.provider.CredentialProviderService +import androidx.credentials.provider.ProviderClearCredentialStateRequest + +@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) +public class APSCredentialProviderService : CredentialProviderService() { + + override fun onBeginCreateCredentialRequest( + request: BeginCreateCredentialRequest, + cancellationSignal: CancellationSignal, + callback: OutcomeReceiver<BeginCreateCredentialResponse, CreateCredentialException>, + ) { + val response: BeginCreateCredentialResponse? = processCreateCredentialRequest(request) + if (response != null) { + callback.onResult(response) + } else { + callback.onError(CreateCredentialUnknownException()) + } + } + + override fun onBeginGetCredentialRequest( + request: BeginGetCredentialRequest, + cancellationSignal: CancellationSignal, + callback: OutcomeReceiver<BeginGetCredentialResponse, GetCredentialException> + ) {} + + override fun onClearCredentialStateRequest( + request: ProviderClearCredentialStateRequest, + cancellationSignal: CancellationSignal, + callback: OutcomeReceiver<Void?, ClearCredentialException>, + ) {} + + private fun processCreateCredentialRequest( + request: BeginCreateCredentialRequest + ): BeginCreateCredentialResponse? { + return when (request) { + is BeginCreatePublicKeyCredentialRequest -> { + // Request is passkey type + handleCreatePasskeyQuery(request) + } + // Request not supported + else -> null + } + } + + private fun handleCreatePasskeyQuery( + @Suppress("UNUSED_PARAMETER") request: BeginCreatePublicKeyCredentialRequest + ): BeginCreateCredentialResponse { + val createEntries: MutableList<CreateEntry> = mutableListOf() + println(request.requestJson) + createEntries.add( + CreateEntry( + DEFAULT_ACCOUNT_NAME, + createNewPendingIntent(DEFAULT_ACCOUNT_NAME, CREATE_PASSKEY_INTENT_ACTION) + ) + ) + + return BeginCreateCredentialResponse(createEntries) + } + + private fun createNewPendingIntent(accountId: String, action: String): PendingIntent { + val intent = Intent(action).setPackage(packageName) + // Add your local account ID as an extra to the intent, so that when + // user selects this entry, the credential can be saved to this + // account + intent.putExtra(EXTRA_KEY_ACCOUNT_ID, accountId) + + return PendingIntent.getActivity( + applicationContext, + REQUEST_CODE, + intent, + (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT), + ) + } + + internal companion object { + + // These intent actions are specified for corresponding activities + // that are to be invoked through the PendingIntent(s) + const val REQUEST_CODE = 1010101 + const val EXTRA_KEY_ACCOUNT_ID = "EXTRA_KEY_ACCOUNT_ID" + const val DEFAULT_ACCOUNT_NAME = "Default Password Store" + const val CREATE_PASSKEY_INTENT_ACTION = "app.passwordstore.CREATE_PASSKEY" + const val GET_PASSKEY_INTENT_ACTION = "PACKAGE_NAME.GET_PASSKEY" + } +} diff --git a/passkeys/src/main/res/drawable/ic_launcher_background.xml b/passkeys/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 140f8294..00000000 --- a/passkeys/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="108dp" - android:height="108dp" - android:viewportWidth="108" - android:viewportHeight="108"> - <path - android:fillColor="#3DDC84" - android:pathData="M0,0h108v108h-108z" /> - <path - android:fillColor="#00000000" - android:pathData="M9,0L9,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,0L19,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M29,0L29,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M39,0L39,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M49,0L49,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M59,0L59,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M69,0L69,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M79,0L79,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M89,0L89,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M99,0L99,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,9L108,9" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,19L108,19" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,29L108,29" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,39L108,39" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,49L108,49" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,59L108,59" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,69L108,69" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,79L108,79" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,89L108,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,99L108,99" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,29L89,29" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,39L89,39" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,49L89,49" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,59L89,59" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,69L89,69" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,79L89,79" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M29,19L29,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M39,19L39,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M49,19L49,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M59,19L59,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M69,19L69,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M79,19L79,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> -</vector> diff --git a/passkeys/src/main/res/drawable/ic_launcher_foreground.xml b/passkeys/src/main/res/drawable/ic_launcher_foreground.xml deleted file mode 100644 index 5c3bfcd6..00000000 --- a/passkeys/src/main/res/drawable/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:aapt="http://schemas.android.com/aapt" - android:width="108dp" - android:height="108dp" - android:viewportWidth="108" - android:viewportHeight="108"> - <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> - <aapt:attr name="android:fillColor"> - <gradient - android:endX="85.84757" - android:endY="92.4963" - android:startX="42.9492" - android:startY="49.59793" - android:type="linear"> - <item - android:color="#44000000" - android:offset="0.0" /> - <item - android:color="#00000000" - android:offset="1.0" /> - </gradient> - </aapt:attr> - </path> - <path - android:fillColor="#FFFFFF" - android:fillType="nonZero" - android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" - android:strokeWidth="1" - android:strokeColor="#00000000" /> -</vector>
\ No newline at end of file diff --git a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index 5ad9ce15..00000000 --- a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@drawable/ic_launcher_background" /> - <foreground android:drawable="@drawable/ic_launcher_foreground" /> - <monochrome android:drawable="@drawable/ic_launcher_foreground" /> -</adaptive-icon>
\ No newline at end of file diff --git a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 5ad9ce15..00000000 --- a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@drawable/ic_launcher_background" /> - <foreground android:drawable="@drawable/ic_launcher_foreground" /> - <monochrome android:drawable="@drawable/ic_launcher_foreground" /> -</adaptive-icon>
\ No newline at end of file diff --git a/passkeys/src/main/res/mipmap-hdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-hdpi/ic_launcher.webp Binary files differdeleted file mode 100644 index c209e78e..00000000 --- a/passkeys/src/main/res/mipmap-hdpi/ic_launcher.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-hdpi/ic_launcher_round.webp Binary files differdeleted file mode 100644 index b2dfe3d1..00000000 --- a/passkeys/src/main/res/mipmap-hdpi/ic_launcher_round.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-mdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-mdpi/ic_launcher.webp Binary files differdeleted file mode 100644 index 4f0f1d64..00000000 --- a/passkeys/src/main/res/mipmap-mdpi/ic_launcher.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-mdpi/ic_launcher_round.webp Binary files differdeleted file mode 100644 index 62b611da..00000000 --- a/passkeys/src/main/res/mipmap-mdpi/ic_launcher_round.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-xhdpi/ic_launcher.webp Binary files differdeleted file mode 100644 index 948a3070..00000000 --- a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-xhdpi/ic_launcher_round.webp Binary files differdeleted file mode 100644 index 1b9a6956..00000000 --- a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher.webp Binary files differdeleted file mode 100644 index 28d4b77f..00000000 --- a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp Binary files differdeleted file mode 100644 index 9287f508..00000000 --- a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher.webp Binary files differdeleted file mode 100644 index aa7d6427..00000000 --- a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +++ /dev/null diff --git a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp Binary files differdeleted file mode 100644 index 9126ae37..00000000 --- a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +++ /dev/null diff --git a/passkeys/src/main/res/values-night/themes.xml b/passkeys/src/main/res/values-night/themes.xml deleted file mode 100644 index f0a927fb..00000000 --- a/passkeys/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Base application theme. --> - <style name="Theme.APS" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> - <!-- Primary brand color. --> - <item name="colorPrimary">@color/purple_200</item> - <item name="colorPrimaryVariant">@color/purple_700</item> - <item name="colorOnPrimary">@color/black</item> - <!-- Secondary brand color. --> - <item name="colorSecondary">@color/teal_200</item> - <item name="colorSecondaryVariant">@color/teal_200</item> - <item name="colorOnSecondary">@color/black</item> - <!-- Status bar color. --> - <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> - <!-- Customize your theme here. --> - </style> -</resources>
\ No newline at end of file diff --git a/passkeys/src/main/res/values/colors.xml b/passkeys/src/main/res/values/colors.xml deleted file mode 100644 index 09837df6..00000000 --- a/passkeys/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <color name="purple_200">#FFBB86FC</color> - <color name="purple_500">#FF6200EE</color> - <color name="purple_700">#FF3700B3</color> - <color name="teal_200">#FF03DAC5</color> - <color name="teal_700">#FF018786</color> - <color name="black">#FF000000</color> - <color name="white">#FFFFFFFF</color> -</resources>
\ No newline at end of file diff --git a/passkeys/src/main/res/values/strings.xml b/passkeys/src/main/res/values/strings.xml deleted file mode 100644 index 485ed028..00000000 --- a/passkeys/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <string name="app_name">passkeys</string> -</resources>
\ No newline at end of file diff --git a/passkeys/src/main/res/values/themes.xml b/passkeys/src/main/res/values/themes.xml deleted file mode 100644 index 4210ce7d..00000000 --- a/passkeys/src/main/res/values/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Base application theme. --> - <style name="Theme.APS" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> - <!-- Primary brand color. --> - <item name="colorPrimary">@color/purple_500</item> - <item name="colorPrimaryVariant">@color/purple_700</item> - <item name="colorOnPrimary">@color/white</item> - <!-- Secondary brand color. --> - <item name="colorSecondary">@color/teal_200</item> - <item name="colorSecondaryVariant">@color/teal_700</item> - <item name="colorOnSecondary">@color/black</item> - <!-- Status bar color. --> - <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> - <!-- Customize your theme here. --> - </style> -</resources>
\ No newline at end of file diff --git a/passkeys/src/main/res/xml/provider.xml b/passkeys/src/main/res/xml/provider.xml new file mode 100644 index 00000000..99d41c9b --- /dev/null +++ b/passkeys/src/main/res/xml/provider.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<credential-provider xmlns:android="http://schemas.android.com/apk/res/android"> + <capabilities> + <capability name="android.credentials.TYPE_PASSWORD_CREDENTIAL" /> + <capability name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" /> + </capabilities> +</credential-provider>
\ No newline at end of file |