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  * A request to retrieve the user's saved application password from their password provider.
24  *
25  * @property allowedUserIds a optional set of user ids with which the credentials associated are
26  *   requested; leave as empty if you want to request all the available user credentials
27  * @property typePriorityHint always sets the priority of this entry to
28  *   [CredentialOption.PRIORITY_PASSWORD_OR_SIMILAR], which defines how it appears in the credential
29  *   selector, with less precedence than account ordering but more precedence than last used time;
30  *   see [CredentialOption] for more information
31  */
32 class GetPasswordOption
33 private constructor(
34     val allowedUserIds: Set<String>,
35     isAutoSelectAllowed: Boolean,
36     allowedProviders: Set<ComponentName>,
37     requestData: Bundle,
38     candidateQueryData: Bundle,
39     typePriorityHint: @PriorityHints Int = PRIORITY_PASSWORD_OR_SIMILAR,
40 ) :
41     CredentialOption(
42         type = PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
43         requestData = requestData,
44         candidateQueryData = candidateQueryData,
45         isSystemProviderRequired = false,
46         isAutoSelectAllowed = isAutoSelectAllowed,
47         allowedProviders = allowedProviders,
48         typePriorityHint = typePriorityHint,
49     ) {
50 
51     /**
52      * Constructs a [GetPasswordOption].
53      *
54      * @param allowedUserIds a optional set of user ids with which the credentials associated are
55      *   requested; leave as empty if you want to request all the available user credentials
56      * @param isAutoSelectAllowed false by default, allows auto selecting a password if there is
57      *   only one available
58      * @param allowedProviders a set of provider service [ComponentName] allowed to receive this
59      *   option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app
60      *   does not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level <
61      *   34, this property will not take effect and you should control the allowed provider via
62      *   [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies))
63      */
64     @JvmOverloads
65     constructor(
66         allowedUserIds: Set<String> = emptySet(),
67         isAutoSelectAllowed: Boolean = false,
68         allowedProviders: Set<ComponentName> = emptySet(),
69     ) : this(
70         allowedUserIds = allowedUserIds,
71         isAutoSelectAllowed = isAutoSelectAllowed,
72         allowedProviders = allowedProviders,
73         requestData = toBundle(allowedUserIds),
74         candidateQueryData = toBundle(allowedUserIds)
75     )
76 
77     internal companion object {
78         internal const val BUNDLE_KEY_ALLOWED_USER_IDS =
79             "androidx.credentials.BUNDLE_KEY_ALLOWED_USER_IDS"
80 
81         @JvmStatic
createFromnull82         internal fun createFrom(
83             data: Bundle,
84             allowedProviders: Set<ComponentName>,
85             candidateQueryData: Bundle,
86         ): GetPasswordOption {
87             val allowUserIdList = data.getStringArrayList(BUNDLE_KEY_ALLOWED_USER_IDS)
88             return GetPasswordOption(
89                 allowedUserIds = allowUserIdList?.toSet() ?: emptySet(),
90                 isAutoSelectAllowed = data.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false),
91                 allowedProviders = allowedProviders,
92                 requestData = data,
93                 candidateQueryData = candidateQueryData,
94                 typePriorityHint =
95                     data.getInt(BUNDLE_KEY_TYPE_PRIORITY_VALUE, PRIORITY_PASSWORD_OR_SIMILAR),
96             )
97         }
98 
99         @JvmStatic
toBundlenull100         internal fun toBundle(allowUserIds: Set<String>): Bundle {
101             val bundle = Bundle()
102             bundle.putStringArrayList(BUNDLE_KEY_ALLOWED_USER_IDS, ArrayList(allowUserIds))
103             return bundle
104         }
105     }
106 }
107