Merge "Define converter methods to parse the app requests."
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