1 /* 2 * Copyright 2022 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.content.ComponentName 20 import android.os.Bundle 21 22 /** 23 * Allows extending custom versions of GetCredentialOptions for unique use cases. 24 * 25 * If you get a [GetCustomCredentialOption] instead of a type-safe option class such as 26 * [GetPasswordOption], [GetPublicKeyCredentialOption], etc., then you should check if you have any 27 * other library at interest that supports this custom [type] of credential option, and if so use 28 * its parsing utilities to resolve to a type-safe class within that library. 29 * 30 * Note: The Bundle keys for [requestData] and [candidateQueryData] should not be in the form of 31 * `androidx.credentials.*` as they are reserved for internal use by this androidx library. 32 * 33 * The [typePriorityHint] bit helps decide where the credential will be displayed on the selector. 34 * It is used with more importance than signals like 'last recently used' but with less importance 35 * than other signals, such as the ordering of displayed accounts. It is expected to be one of the 36 * defined `CredentialOption.PRIORITY_*` constants. By default, [GetCustomCredentialOption] will 37 * have [CredentialOption.PRIORITY_DEFAULT], [GetPasswordOption] will have 38 * [CredentialOption.PRIORITY_PASSWORD_OR_SIMILAR] and [GetPublicKeyCredentialOption] will have 39 * [CredentialOption.PRIORITY_PASSKEY_OR_SIMILAR]. It is expected that [GetCustomCredentialOption] 40 * types will remain unchanged unless strong reasons arise and cannot ever have 41 * [CredentialOption.PRIORITY_PASSKEY_OR_SIMILAR]. Given passkeys prevent many security threats that 42 * other credentials do not, we enforce that nothing is shown higher than passkey types in order to 43 * provide end users with the safest credentials first. See the spec 44 * [here](https://w3c.github.io/webauthn/) for more information on passkeys. 45 * 46 * @property type the credential type determined by the credential-type-specific subclass (e.g. the 47 * type for [GetPasswordOption] is [PasswordCredential.TYPE_PASSWORD_CREDENTIAL] and for 48 * [GetPublicKeyCredentialOption] is [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL]) 49 * @property requestData the request data in the [Bundle] format 50 * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to 51 * the provider during the initial candidate query stage, which will not contain sensitive user 52 * information 53 * @property isSystemProviderRequired true if must only be fulfilled by a system provider and false 54 * otherwise 55 * @property isAutoSelectAllowed whether a credential entry will be automatically chosen if it is 56 * the only one available option 57 * @property allowedProviders a set of provider service [ComponentName] allowed to receive this 58 * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app does 59 * not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 34, this 60 * property will not take effect and you should control the allowed provider via 61 * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies)) 62 * @property typePriorityHint sets the priority of this entry, which defines how it appears in the 63 * credential selector amongst the signals used to order the entries, set to 64 * [CredentialOption.PRIORITY_DEFAULT] by default; see [CredentialOption] for more information 65 */ 66 open class GetCustomCredentialOption 67 internal constructor( 68 requestData: Bundle, 69 type: String, 70 candidateQueryData: Bundle, 71 isSystemProviderRequired: Boolean, 72 isAutoSelectAllowed: Boolean = false, 73 allowedProviders: Set<ComponentName> = emptySet(), 74 typePriorityHint: @PriorityHints Int = PRIORITY_DEFAULT 75 ) : 76 CredentialOption( 77 type = type, 78 requestData = requestData, 79 candidateQueryData = candidateQueryData, 80 isSystemProviderRequired = isSystemProviderRequired, 81 isAutoSelectAllowed = isAutoSelectAllowed, 82 allowedProviders = allowedProviders, 83 typePriorityHint = typePriorityHint, 84 ) { 85 86 init { <lambda>null87 require(type.isNotEmpty()) { "type should not be empty" } <lambda>null88 require(typePriorityHint != CredentialOption.PRIORITY_PASSKEY_OR_SIMILAR) { 89 "Custom types should not have passkey level priority." 90 } 91 } 92 93 /** 94 * Allows extending custom versions of GetCredentialOptions for unique use cases. 95 * 96 * If you get a [GetCustomCredentialOption] instead of a type-safe option class such as 97 * [GetPasswordOption], [GetPublicKeyCredentialOption], etc., then you should check if you have 98 * any other library at interest that supports this custom [type] of credential option, and if 99 * so use its parsing utilities to resolve to a type-safe class within that library. 100 * 101 * Note: The Bundle keys for [requestData] and [candidateQueryData] should not be in the form of 102 * `androidx.credentials.*` as they are reserved for internal use by this androidx library. 103 * 104 * @param type the credential type determined by the credential-type-specific subclass generated 105 * for custom use cases 106 * @param requestData the request data in the [Bundle] format, generated for custom use cases 107 * (note: bundle keys in the form of `androidx.credentials.*` and `android.credentials.*` are 108 * reserved for internal library usage) 109 * @param candidateQueryData the partial request data in the [Bundle] format that will be sent 110 * to the provider during the initial candidate query stage, which should not contain 111 * sensitive user information (note: bundle keys in the form of `androidx.credentials.*` and 112 * `android.credentials.*` are reserved for internal library usage) 113 * @param isSystemProviderRequired true if must only be fulfilled by a system provider and false 114 * otherwise 115 * @param isAutoSelectAllowed defines if a credential entry will be automatically chosen if it 116 * is the only one available option, false by default 117 * @param allowedProviders a set of provider service [ComponentName] allowed to receive this 118 * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app 119 * does not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 120 * 34, this property will not take effect and you should control the allowed provider via 121 * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies)) 122 * @throws IllegalArgumentException If [type] is empty 123 * @throws NullPointerException If [requestData] or [type] is null 124 */ 125 @JvmOverloads 126 constructor( 127 type: String, 128 requestData: Bundle, 129 candidateQueryData: Bundle, 130 isSystemProviderRequired: Boolean, 131 isAutoSelectAllowed: Boolean = false, 132 allowedProviders: Set<ComponentName> = emptySet(), 133 ) : this( 134 requestData, 135 type, 136 candidateQueryData, 137 isSystemProviderRequired, 138 isAutoSelectAllowed, 139 allowedProviders 140 ) 141 142 /** 143 * Allows extending custom versions of GetCredentialOptions for unique use cases. 144 * 145 * If you get a [GetCustomCredentialOption] instead of a type-safe option class such as 146 * [GetPasswordOption], [GetPublicKeyCredentialOption], etc., then you should check if you have 147 * any other library at interest that supports this custom [type] of credential option, and if 148 * so use its parsing utilities to resolve to a type-safe class within that library. 149 * 150 * Note: The Bundle keys for [requestData] and [candidateQueryData] should not be in the form of 151 * `androidx.credentials.*` as they are reserved for internal use by this androidx library. 152 * 153 * The [typePriorityHint] bit helps decide where the credential will be displayed on the 154 * selector. It is expected that [GetCustomCredentialOption] types will remain unchanged unless 155 * strong reasons arise and cannot ever have [CredentialOption.PRIORITY_PASSKEY_OR_SIMILAR]. 156 * Given passkeys prevent many security threats that other credentials do not, we enforce that 157 * nothing is shown higher than passkey types in order to provide end users with the safest 158 * credentials first. See the spec [here](https://w3c.github.io/webauthn/) for more information 159 * on passkeys. 160 * 161 * @param type the credential type determined by the credential-type-specific subclass generated 162 * for custom use cases 163 * @param requestData the request data in the [Bundle] format, generated for custom use cases 164 * (note: bundle keys in the form of `androidx.credentials.*` and `android.credentials.*` are 165 * reserved for internal library usage) 166 * @param candidateQueryData the partial request data in the [Bundle] format that will be sent 167 * to the provider during the initial candidate query stage, which should not contain 168 * sensitive user information (note: bundle keys in the form of `androidx.credentials.*` and 169 * `android.credentials.*` are reserved for internal library usage) 170 * @param isSystemProviderRequired true if must only be fulfilled by a system provider and false 171 * otherwise 172 * @param isAutoSelectAllowed defines if a credential entry will be automatically chosen if it 173 * is the only one available option, false by default 174 * @param allowedProviders a set of provider service [ComponentName] allowed to receive this 175 * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app 176 * does not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 177 * 34, this property will not take effect and you should control the allowed provider via 178 * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies)) 179 * @param typePriorityHint sets the priority of this entry, which defines how it appears in the 180 * credential selector, with less precedence than account ordering but more precedence than 181 * last used time; see [CredentialOption] and [CredentialOption] for more information 182 * @throws IllegalArgumentException If [type] is empty 183 * @throws NullPointerException If [requestData] or [type] is null 184 */ 185 constructor( 186 type: String, 187 requestData: Bundle, 188 candidateQueryData: Bundle, 189 isSystemProviderRequired: Boolean, 190 isAutoSelectAllowed: Boolean = false, 191 allowedProviders: Set<ComponentName> = emptySet(), 192 typePriorityHint: @PriorityHints Int = PRIORITY_DEFAULT, 193 ) : this( 194 requestData, 195 type, 196 candidateQueryData, 197 isSystemProviderRequired, 198 isAutoSelectAllowed, 199 allowedProviders, 200 typePriorityHint 201 ) 202 } 203