1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.credentials
18 
19 import android.os.Bundle
20 import androidx.credentials.exceptions.NoCredentialException
21 import androidx.credentials.internal.RequestValidationHelper
22 
23 /**
24  * A request to get the restore credential from the restore credential provider.
25  *
26  * @property requestJson the request in JSON format in the standard webauthn web json
27  *   (https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
28  *
29  * Note that the userVerification field of the requestJson will always be overridden to
30  * `discouraged` to support passive authentication during restore flow.
31  *
32  * [GetRestoreCredentialOption] cannot be requested with other credential options because of
33  * conflicting user experience. When requesting restore credential, only a single
34  * [GetRestoreCredentialOption] must be supplied.
35  *
36  * @throws IllegalArgumentException if the requestJson is an invalid Json that does not follow the
37  *   standard webauthn web json format
38  * @throws NoCredentialException if no viable restore credential is found
39  * @throws IllegalArgumentException if the option is mixed with another [CredentialOption]
40  */
41 class GetRestoreCredentialOption(val requestJson: String) :
42     CredentialOption(
43         type = RestoreCredential.TYPE_RESTORE_CREDENTIAL,
44         requestData = toRequestDataBundle(requestJson),
45         candidateQueryData = Bundle(),
46         isSystemProviderRequired = false,
47         isAutoSelectAllowed = false,
48         allowedProviders = emptySet(),
49         typePriorityHint = PRIORITY_DEFAULT,
50     ) {
51 
52     init {
<lambda>null53         require(RequestValidationHelper.isValidJSON(requestJson)) {
54             "requestJson must not be empty, and must be a valid JSON"
55         }
56     }
57 
58     private companion object {
59         private const val BUNDLE_KEY_GET_RESTORE_CREDENTIAL_REQUEST =
60             "androidx.credentials.BUNDLE_KEY_GET_RESTORE_CREDENTIAL_REQUEST"
61 
toRequestDataBundlenull62         private fun toRequestDataBundle(requestJson: String): Bundle {
63             val bundle = Bundle()
64             bundle.putString(BUNDLE_KEY_GET_RESTORE_CREDENTIAL_REQUEST, requestJson)
65             return bundle
66         }
67     }
68 }
69