Define converter methods to parse the app requests.
Provides conversion between the framework requests and the jetpack requests. Note that these classes technically should be defined in the jetpack library but are temporarily left util we are able to ship the jetpack code into the framework. Bug: 255688485 Test: local deployment Change-Id: I31ae459bb1578ee41492de1a2b0523f9ed72cee2
This commit is contained in:
@@ -36,7 +36,8 @@ public final class Credential implements Parcelable {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull public static final String TYPE_PASSWORD = "android.credentials.TYPE_PASSWORD";
|
||||
@NonNull public static final String TYPE_PASSWORD_CREDENTIAL =
|
||||
"android.credentials.TYPE_PASSWORD_CREDENTIAL";
|
||||
|
||||
/**
|
||||
* The credential type.
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.android.credentialmanager.createflow.CreateScreenState
|
||||
import com.android.credentialmanager.createflow.RequestDisplayInfo
|
||||
import com.android.credentialmanager.getflow.GetCredentialUiState
|
||||
import com.android.credentialmanager.getflow.GetScreenState
|
||||
import com.android.credentialmanager.jetpack.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
|
||||
import com.android.credentialmanager.jetpack.provider.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
|
||||
|
||||
// Consider repo per screen, similar to view model?
|
||||
class CredentialManagerRepo(
|
||||
|
||||
@@ -39,8 +39,8 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.android.credentialmanager.R
|
||||
import com.android.credentialmanager.jetpack.CredentialEntryUi.Companion.TYPE_PASSWORD_CREDENTIAL
|
||||
import com.android.credentialmanager.jetpack.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
|
||||
import com.android.credentialmanager.jetpack.provider.CredentialEntryUi.Companion.TYPE_PASSWORD_CREDENTIAL
|
||||
import com.android.credentialmanager.jetpack.provider.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
|
||||
import com.android.credentialmanager.ui.theme.Grey100
|
||||
import com.android.credentialmanager.ui.theme.Shapes
|
||||
import com.android.credentialmanager.ui.theme.Typography
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.credentials.Credential
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* Base request class for registering a credential.
|
||||
*
|
||||
* @property type the credential type
|
||||
* @property data the request data in the [Bundle] format
|
||||
* @property requireSystemProvider true if must only be fulfilled by a system provider and false
|
||||
* otherwise
|
||||
*/
|
||||
open class CreateCredentialRequest(
|
||||
val type: String,
|
||||
val data: Bundle,
|
||||
val requireSystemProvider: Boolean,
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFrom(from: android.credentials.CreateCredentialRequest): CreateCredentialRequest {
|
||||
return try {
|
||||
when (from.type) {
|
||||
Credential.TYPE_PASSWORD_CREDENTIAL ->
|
||||
CreatePasswordRequest.createFrom(from.data)
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
|
||||
CreatePublicKeyCredentialBaseRequest.createFrom(from.data)
|
||||
else ->
|
||||
CreateCredentialRequest(from.type, from.data, from.requireSystemProvider())
|
||||
}
|
||||
} catch (e: FrameworkClassParsingException) {
|
||||
CreateCredentialRequest(from.type, from.data, from.requireSystemProvider())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.credentials.Credential
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* A request to save the user password credential with their password provider.
|
||||
*
|
||||
* @property id the user id associated with the password
|
||||
* @property password the password
|
||||
* @throws NullPointerException If [id] is null
|
||||
* @throws NullPointerException If [password] is null
|
||||
* @throws IllegalArgumentException If [password] is empty
|
||||
*/
|
||||
class CreatePasswordRequest constructor(
|
||||
val id: String,
|
||||
val password: String,
|
||||
) : CreateCredentialRequest(
|
||||
Credential.TYPE_PASSWORD_CREDENTIAL,
|
||||
toBundle(id, password),
|
||||
false,
|
||||
) {
|
||||
|
||||
init {
|
||||
require(password.isNotEmpty()) { "password should not be empty" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
|
||||
const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
|
||||
|
||||
@JvmStatic
|
||||
internal fun toBundle(id: String, password: String): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BUNDLE_KEY_ID, id)
|
||||
bundle.putString(BUNDLE_KEY_PASSWORD, password)
|
||||
return bundle
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): CreatePasswordRequest {
|
||||
try {
|
||||
val id = data.getString(BUNDLE_KEY_ID)
|
||||
val password = data.getString(BUNDLE_KEY_PASSWORD)
|
||||
return CreatePasswordRequest(id!!, password!!)
|
||||
} catch (e: Exception) {
|
||||
throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* Base request class for registering a public key credential.
|
||||
*
|
||||
* @property requestJson The request in JSON format
|
||||
* @throws NullPointerException If [requestJson] is null. This is handled by the Kotlin runtime
|
||||
* @throws IllegalArgumentException If [requestJson] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
abstract class CreatePublicKeyCredentialBaseRequest constructor(
|
||||
val requestJson: String,
|
||||
type: String,
|
||||
data: Bundle,
|
||||
requireSystemProvider: Boolean,
|
||||
) : CreateCredentialRequest(type, data, requireSystemProvider) {
|
||||
|
||||
init {
|
||||
require(requestJson.isNotEmpty()) { "request json must not be empty" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
|
||||
const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): CreatePublicKeyCredentialBaseRequest {
|
||||
return when (data.getString(BUNDLE_KEY_SUBTYPE)) {
|
||||
CreatePublicKeyCredentialRequest
|
||||
.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST ->
|
||||
CreatePublicKeyCredentialRequestPrivileged.createFrom(data)
|
||||
CreatePublicKeyCredentialRequestPrivileged
|
||||
.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED ->
|
||||
CreatePublicKeyCredentialRequestPrivileged.createFrom(data)
|
||||
else -> throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* A request to register a passkey from the user's public key credential provider.
|
||||
*
|
||||
* @property requestJson the request in JSON format
|
||||
* @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
|
||||
* true by default
|
||||
* @throws NullPointerException If [requestJson] or [allowHybrid] is null. This is handled by the
|
||||
* Kotlin runtime
|
||||
* @throws IllegalArgumentException If [requestJson] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class CreatePublicKeyCredentialRequest @JvmOverloads constructor(
|
||||
requestJson: String,
|
||||
@get:JvmName("allowHybrid")
|
||||
val allowHybrid: Boolean = true
|
||||
) : CreatePublicKeyCredentialBaseRequest(
|
||||
requestJson,
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
|
||||
toBundle(requestJson, allowHybrid),
|
||||
false,
|
||||
) {
|
||||
companion object {
|
||||
const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
|
||||
const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST =
|
||||
"androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST"
|
||||
|
||||
@JvmStatic
|
||||
internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BUNDLE_KEY_SUBTYPE,
|
||||
BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
|
||||
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
|
||||
bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
|
||||
return bundle
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): CreatePublicKeyCredentialRequest {
|
||||
try {
|
||||
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
|
||||
val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
|
||||
return CreatePublicKeyCredentialRequest(requestJson!!, (allowHybrid!!) as Boolean)
|
||||
} catch (e: Exception) {
|
||||
throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* A privileged request to register a passkey from the user’s public key credential provider, where
|
||||
* the caller can modify the rp. Only callers with privileged permission, e.g. user’s default
|
||||
* brower, caBLE, can use this.
|
||||
*
|
||||
* @property requestJson the privileged request in JSON format
|
||||
* @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
|
||||
* true by default
|
||||
* @property rp the expected true RP ID which will override the one in the [requestJson]
|
||||
* @property clientDataHash a hash that is used to verify the [rp] Identity
|
||||
* @throws NullPointerException If any of [allowHybrid], [requestJson], [rp], or [clientDataHash] is
|
||||
* null. This is handled by the Kotlin runtime
|
||||
* @throws IllegalArgumentException If any of [requestJson], [rp], or [clientDataHash] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class CreatePublicKeyCredentialRequestPrivileged @JvmOverloads constructor(
|
||||
requestJson: String,
|
||||
val rp: String,
|
||||
val clientDataHash: String,
|
||||
@get:JvmName("allowHybrid")
|
||||
val allowHybrid: Boolean = true
|
||||
) : CreatePublicKeyCredentialBaseRequest(
|
||||
requestJson,
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
|
||||
toBundle(requestJson, rp, clientDataHash, allowHybrid),
|
||||
false,
|
||||
) {
|
||||
|
||||
init {
|
||||
require(rp.isNotEmpty()) { "rp must not be empty" }
|
||||
require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
|
||||
}
|
||||
|
||||
/** A builder for [CreatePublicKeyCredentialRequestPrivileged]. */
|
||||
class Builder(var requestJson: String, var rp: String, var clientDataHash: String) {
|
||||
|
||||
private var allowHybrid: Boolean = true
|
||||
|
||||
/**
|
||||
* Sets the privileged request in JSON format.
|
||||
*/
|
||||
fun setRequestJson(requestJson: String): Builder {
|
||||
this.requestJson = requestJson
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether hybrid credentials are allowed to fulfill this request, true by default.
|
||||
*/
|
||||
fun setAllowHybrid(allowHybrid: Boolean): Builder {
|
||||
this.allowHybrid = allowHybrid
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the expected true RP ID which will override the one in the [requestJson].
|
||||
*/
|
||||
fun setRp(rp: String): Builder {
|
||||
this.rp = rp
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a hash that is used to verify the [rp] Identity.
|
||||
*/
|
||||
fun setClientDataHash(clientDataHash: String): Builder {
|
||||
this.clientDataHash = clientDataHash
|
||||
return this
|
||||
}
|
||||
|
||||
/** Builds a [CreatePublicKeyCredentialRequestPrivileged]. */
|
||||
fun build(): CreatePublicKeyCredentialRequestPrivileged {
|
||||
return CreatePublicKeyCredentialRequestPrivileged(this.requestJson,
|
||||
this.rp, this.clientDataHash, this.allowHybrid)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
|
||||
const val BUNDLE_KEY_CLIENT_DATA_HASH =
|
||||
"androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
|
||||
const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
|
||||
const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED =
|
||||
"androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_" +
|
||||
"PRIVILEGED"
|
||||
|
||||
@JvmStatic
|
||||
internal fun toBundle(
|
||||
requestJson: String,
|
||||
rp: String,
|
||||
clientDataHash: String,
|
||||
allowHybrid: Boolean
|
||||
): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BUNDLE_KEY_SUBTYPE,
|
||||
BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED)
|
||||
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
|
||||
bundle.putString(BUNDLE_KEY_RP, rp)
|
||||
bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
|
||||
bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
|
||||
return bundle
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): CreatePublicKeyCredentialRequestPrivileged {
|
||||
try {
|
||||
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
|
||||
val rp = data.getString(BUNDLE_KEY_RP)
|
||||
val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
|
||||
val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
|
||||
return CreatePublicKeyCredentialRequestPrivileged(
|
||||
requestJson!!,
|
||||
rp!!,
|
||||
clientDataHash!!,
|
||||
(allowHybrid!!) as Boolean,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* Base class for a credential with which the user consented to authenticate to the app.
|
||||
*
|
||||
* @property type the credential type
|
||||
* @property data the credential data in the [Bundle] format.
|
||||
*/
|
||||
open class Credential(val type: String, val data: Bundle)
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
/**
|
||||
* Internal exception used to indicate a parsing error while converting from a framework type to
|
||||
* a jetpack type.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
internal class FrameworkClassParsingException : Exception()
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.credentials.Credential
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* Base request class for getting a registered credential.
|
||||
*
|
||||
* @property type the credential type
|
||||
* @property data the request data in the [Bundle] format
|
||||
* @property requireSystemProvider true if must only be fulfilled by a system provider and false
|
||||
* otherwise
|
||||
*/
|
||||
open class GetCredentialOption(
|
||||
val type: String,
|
||||
val data: Bundle,
|
||||
val requireSystemProvider: Boolean,
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFrom(from: android.credentials.GetCredentialOption): GetCredentialOption {
|
||||
return try {
|
||||
when (from.type) {
|
||||
Credential.TYPE_PASSWORD_CREDENTIAL ->
|
||||
GetPasswordOption.createFrom(from.data)
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
|
||||
GetPublicKeyCredentialBaseOption.createFrom(from.data)
|
||||
else ->
|
||||
GetCredentialOption(from.type, from.data, from.requireSystemProvider())
|
||||
}
|
||||
} catch (e: FrameworkClassParsingException) {
|
||||
GetCredentialOption(from.type, from.data, from.requireSystemProvider())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
/**
|
||||
* Encapsulates a request to get a user credential.
|
||||
*
|
||||
* @property getCredentialOptions the list of [GetCredentialOption] from which the user can choose
|
||||
* one to authenticate to the app
|
||||
* @throws IllegalArgumentException If [getCredentialOptions] is empty
|
||||
*/
|
||||
class GetCredentialRequest constructor(
|
||||
val getCredentialOptions: List<GetCredentialOption>,
|
||||
) {
|
||||
|
||||
init {
|
||||
require(getCredentialOptions.isNotEmpty()) { "credentialRequests should not be empty" }
|
||||
}
|
||||
|
||||
/** A builder for [GetCredentialRequest]. */
|
||||
class Builder {
|
||||
private var getCredentialOptions: MutableList<GetCredentialOption> = mutableListOf()
|
||||
|
||||
/** Adds a specific type of [GetCredentialOption]. */
|
||||
fun addGetCredentialOption(getCredentialOption: GetCredentialOption): Builder {
|
||||
getCredentialOptions.add(getCredentialOption)
|
||||
return this
|
||||
}
|
||||
|
||||
/** Sets the list of [GetCredentialOption]. */
|
||||
fun setGetCredentialOptions(getCredentialOptions: List<GetCredentialOption>): Builder {
|
||||
this.getCredentialOptions = getCredentialOptions.toMutableList()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a [GetCredentialRequest].
|
||||
*
|
||||
* @throws IllegalArgumentException If [getCredentialOptions] is empty
|
||||
*/
|
||||
fun build(): GetCredentialRequest {
|
||||
return GetCredentialRequest(getCredentialOptions.toList())
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFrom(from: android.credentials.GetCredentialRequest): GetCredentialRequest {
|
||||
return GetCredentialRequest(
|
||||
from.getCredentialOptions.map {GetCredentialOption.createFrom(it)}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.credentials.Credential
|
||||
import android.os.Bundle
|
||||
|
||||
/** A request to retrieve the user's saved application password from their password provider. */
|
||||
class GetPasswordOption : GetCredentialOption(
|
||||
Credential.TYPE_PASSWORD_CREDENTIAL,
|
||||
Bundle(),
|
||||
false,
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): GetPasswordOption {
|
||||
return GetPasswordOption()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* Base request class for getting a registered public key credential.
|
||||
*
|
||||
* @property requestJson the request in JSON format
|
||||
* @throws NullPointerException If [requestJson] is null - auto handled by the
|
||||
* Kotlin runtime
|
||||
* @throws IllegalArgumentException If [requestJson] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
abstract class GetPublicKeyCredentialBaseOption constructor(
|
||||
val requestJson: String,
|
||||
type: String,
|
||||
data: Bundle,
|
||||
requireSystemProvider: Boolean,
|
||||
) : GetCredentialOption(type, data, requireSystemProvider) {
|
||||
|
||||
init {
|
||||
require(requestJson.isNotEmpty()) { "request json must not be empty" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
|
||||
const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): GetPublicKeyCredentialBaseOption {
|
||||
return when (data.getString(BUNDLE_KEY_SUBTYPE)) {
|
||||
GetPublicKeyCredentialOption
|
||||
.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION ->
|
||||
GetPublicKeyCredentialOption.createFrom(data)
|
||||
GetPublicKeyCredentialOptionPrivileged
|
||||
.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED ->
|
||||
GetPublicKeyCredentialOptionPrivileged.createFrom(data)
|
||||
else -> throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* A request to get passkeys from the user's public key credential provider.
|
||||
*
|
||||
* @property requestJson the request in JSON format
|
||||
* @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
|
||||
* true by default
|
||||
* @throws NullPointerException If [requestJson] or [allowHybrid] is null. It is handled by the
|
||||
* Kotlin runtime
|
||||
* @throws IllegalArgumentException If [requestJson] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class GetPublicKeyCredentialOption @JvmOverloads constructor(
|
||||
requestJson: String,
|
||||
@get:JvmName("allowHybrid")
|
||||
val allowHybrid: Boolean = true,
|
||||
) : GetPublicKeyCredentialBaseOption(
|
||||
requestJson,
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
|
||||
toBundle(requestJson, allowHybrid),
|
||||
false
|
||||
) {
|
||||
companion object {
|
||||
const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
|
||||
const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION =
|
||||
"androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION"
|
||||
|
||||
@JvmStatic
|
||||
internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
|
||||
bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
|
||||
return bundle
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): GetPublicKeyCredentialOption {
|
||||
try {
|
||||
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
|
||||
val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
|
||||
return GetPublicKeyCredentialOption(requestJson!!, (allowHybrid!!) as Boolean)
|
||||
} catch (e: Exception) {
|
||||
throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* A privileged request to get passkeys from the user's public key credential provider. The caller
|
||||
* can modify the RP. Only callers with privileged permission (e.g. user's public browser or caBLE)
|
||||
* can use this.
|
||||
*
|
||||
* @property requestJson the privileged request in JSON format
|
||||
* @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
|
||||
* true by default
|
||||
* @property rp the expected true RP ID which will override the one in the [requestJson]
|
||||
* @property clientDataHash a hash that is used to verify the [rp] Identity
|
||||
* @throws NullPointerException If any of [allowHybrid], [requestJson], [rp], or [clientDataHash]
|
||||
* is null. This is handled by the Kotlin runtime
|
||||
* @throws IllegalArgumentException If any of [requestJson], [rp], or [clientDataHash] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class GetPublicKeyCredentialOptionPrivileged @JvmOverloads constructor(
|
||||
requestJson: String,
|
||||
val rp: String,
|
||||
val clientDataHash: String,
|
||||
@get:JvmName("allowHybrid")
|
||||
val allowHybrid: Boolean = true
|
||||
) : GetPublicKeyCredentialBaseOption(
|
||||
requestJson,
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
|
||||
toBundle(requestJson, rp, clientDataHash, allowHybrid),
|
||||
false,
|
||||
) {
|
||||
|
||||
init {
|
||||
require(rp.isNotEmpty()) { "rp must not be empty" }
|
||||
require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
|
||||
}
|
||||
|
||||
/** A builder for [GetPublicKeyCredentialOptionPrivileged]. */
|
||||
class Builder(var requestJson: String, var rp: String, var clientDataHash: String) {
|
||||
|
||||
private var allowHybrid: Boolean = true
|
||||
|
||||
/**
|
||||
* Sets the privileged request in JSON format.
|
||||
*/
|
||||
fun setRequestJson(requestJson: String): Builder {
|
||||
this.requestJson = requestJson
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether hybrid credentials are allowed to fulfill this request, true by default.
|
||||
*/
|
||||
fun setAllowHybrid(allowHybrid: Boolean): Builder {
|
||||
this.allowHybrid = allowHybrid
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the expected true RP ID which will override the one in the [requestJson].
|
||||
*/
|
||||
fun setRp(rp: String): Builder {
|
||||
this.rp = rp
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a hash that is used to verify the [rp] Identity.
|
||||
*/
|
||||
fun setClientDataHash(clientDataHash: String): Builder {
|
||||
this.clientDataHash = clientDataHash
|
||||
return this
|
||||
}
|
||||
|
||||
/** Builds a [GetPublicKeyCredentialOptionPrivileged]. */
|
||||
fun build(): GetPublicKeyCredentialOptionPrivileged {
|
||||
return GetPublicKeyCredentialOptionPrivileged(this.requestJson,
|
||||
this.rp, this.clientDataHash, this.allowHybrid)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
|
||||
const val BUNDLE_KEY_CLIENT_DATA_HASH =
|
||||
"androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
|
||||
const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
|
||||
const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED =
|
||||
"androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION" +
|
||||
"_PRIVILEGED"
|
||||
|
||||
@JvmStatic
|
||||
internal fun toBundle(
|
||||
requestJson: String,
|
||||
rp: String,
|
||||
clientDataHash: String,
|
||||
allowHybrid: Boolean
|
||||
): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
|
||||
bundle.putString(BUNDLE_KEY_RP, rp)
|
||||
bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
|
||||
bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
|
||||
return bundle
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createFrom(data: Bundle): GetPublicKeyCredentialOptionPrivileged {
|
||||
try {
|
||||
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
|
||||
val rp = data.getString(BUNDLE_KEY_RP)
|
||||
val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
|
||||
val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
|
||||
return GetPublicKeyCredentialOptionPrivileged(
|
||||
requestJson!!,
|
||||
rp!!,
|
||||
clientDataHash!!,
|
||||
(allowHybrid!!) as Boolean,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
throw FrameworkClassParsingException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack.developer
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* Represents the user's passkey credential granted by the user for app sign-in.
|
||||
*
|
||||
* @property authenticationResponseJson the public key credential authentication response in
|
||||
* JSON format that follows the standard webauthn json format shown at
|
||||
* [this w3c link](https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson)
|
||||
* @throws NullPointerException If [authenticationResponseJson] is null. This is handled by the
|
||||
* kotlin runtime
|
||||
* @throws IllegalArgumentException If [authenticationResponseJson] is empty
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class PublicKeyCredential constructor(
|
||||
val authenticationResponseJson: String
|
||||
) : Credential(
|
||||
TYPE_PUBLIC_KEY_CREDENTIAL,
|
||||
toBundle(authenticationResponseJson)
|
||||
) {
|
||||
|
||||
init {
|
||||
require(authenticationResponseJson.isNotEmpty()) {
|
||||
"authentication response JSON must not be empty" }
|
||||
}
|
||||
companion object {
|
||||
/** The type value for public key credential related operations. */
|
||||
const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
|
||||
"androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
|
||||
const val BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON =
|
||||
"androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"
|
||||
|
||||
@JvmStatic
|
||||
internal fun toBundle(authenticationResponseJson: String): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON, authenticationResponseJson)
|
||||
return bundle
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
package com.android.credentialmanager.jetpack.provider
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
package com.android.credentialmanager.jetpack.provider
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.graphics.drawable.Icon
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
package com.android.credentialmanager.jetpack.provider
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
package com.android.credentialmanager.jetpack.provider
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
package com.android.credentialmanager.jetpack.provider
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
Reference in New Issue
Block a user