From 161c2ffa24725219737d5be9e5b91d279f38c1ed Mon Sep 17 00:00:00 2001 From: Marvin W Date: Thu, 15 Apr 2021 12:06:24 +0200 Subject: [PATCH] Add Credentials Picker Stub --- README.md | 2 +- .../credentials/CredentialPickerConfig.java | 24 ++- .../api/credentials/CredentialRequest.java | 24 ++- .../gms/auth/api/credentials/HintRequest.java | 167 ++++++++++++++++++ .../api/credentials/IdentityProviders.java | 31 ++++ .../src/main/AndroidManifest.xml | 9 + .../microg/gms/ui/CredentialPickerActivity.kt | 38 ++++ 7 files changed, 280 insertions(+), 15 deletions(-) create mode 100644 play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java create mode 100644 play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/CredentialPickerActivity.kt diff --git a/README.md b/README.md index 48d7bca1..ffcefc7b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ microG GmsCore is a FLOSS (Free/Libre Open Source Software) framework to allow a License ------- - Copyright 2013-2020 microG Project Team + Copyright 2013-2021 microG Project Team Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java index 67d66c05..3a82499f 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java @@ -16,21 +16,21 @@ package com.google.android.gms.auth.api.credentials; +import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; +@PublicApi public class CredentialPickerConfig extends AutoSafeParcelable { - @SafeParceled(1000) + @Field(1000) private int versionCode = 1; - @SafeParceled(1) + @Field(1) private boolean showAddAccountButton; - - @SafeParceled(2) + @Field(2) private boolean showCancelButton; - - @SafeParceled(3) + @Field(3) private boolean forNewAccount; private CredentialPickerConfig() { @@ -42,6 +42,10 @@ public class CredentialPickerConfig extends AutoSafeParcelable { this.forNewAccount = forNewAccount; } + /** + * @deprecated It was determined that this method was not useful for developers. + */ + @Deprecated public boolean isForNewAccount() { return forNewAccount; } @@ -54,6 +58,14 @@ public class CredentialPickerConfig extends AutoSafeParcelable { return showCancelButton; } + @Override + public String toString() { + return "CredentialPickerConfig{" + + "showAddAccountButton=" + showAddAccountButton + + ", showCancelButton=" + showCancelButton + + '}'; + } + public class Builder { private boolean showAddAccountButton; private boolean showCancelButton; diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java index 80819c71..253ae355 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java @@ -25,19 +25,16 @@ import org.microg.safeparcel.SafeParceled; */ public class CredentialRequest extends AutoSafeParcelable { - @SafeParceled(1000) + @Field(1000) private int versionCode = 1; - @SafeParceled(1) + @Field(1) private boolean passwordLoginSupported; - - @SafeParceled(2) + @Field(2) private String[] accountTypes; - - @SafeParceled(3) + @Field(3) private CredentialPickerConfig credentialPickerConfig; - - @SafeParceled(4) + @Field(4) private CredentialPickerConfig credentialHintPickerConfig; public CredentialRequest(boolean passwordLoginSupported, String[] accountTypes, CredentialPickerConfig credentialPickerConfig, CredentialPickerConfig credentialHintPickerConfig) { @@ -72,4 +69,15 @@ public class CredentialRequest extends AutoSafeParcelable { } public static final Creator CREATOR = new AutoCreator(CredentialRequest.class); + + public static class Builder { + private boolean passwordLoginSupported; + private String[] accountTypes; + private CredentialPickerConfig credentialPickerConfig; + private CredentialPickerConfig credentialHintPickerConfig; + + public void setAccountTypes(String... accountTypes) { + this.accountTypes = accountTypes.clone(); + } + } } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java new file mode 100644 index 00000000..32341c98 --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java @@ -0,0 +1,167 @@ +/* + * SPDX-FileCopyrightText: 2021, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.auth.api.credentials; + +import org.microg.gms.common.PublicApi; +import org.microg.safeparcel.AutoSafeParcelable; + +import java.util.Arrays; + +/** + * Parameters for requesting the display of the hint picker, via {@link CredentalsApi#getHintPickerIntent()}. + * Instances can be created using {@link HintRequest.Builder}. + */ +@PublicApi +public class HintRequest extends AutoSafeParcelable { + @Field(1000) + private int versionCode = 2; + + @Field(1) + private CredentialPickerConfig hintPickerConfig; + @Field(2) + private boolean emailAddressIdentifierSupported; + @Field(3) + private boolean phoneNumberIdentifierSupported; + @Field(4) + private String[] accountTypes; + @Field(5) + private boolean idTokenRequested = true; + @Field(6) + private String serverClientId; + @Field(7) + private String idTokenNonce; + + private HintRequest() { + } + + public HintRequest(CredentialPickerConfig hintPickerConfig, boolean emailAddressIdentifierSupported, boolean phoneNumberIdentifierSupported, String[] accountTypes, boolean idTokenRequested, String serverClientId, String idTokenNonce) { + this.hintPickerConfig = hintPickerConfig; + this.emailAddressIdentifierSupported = emailAddressIdentifierSupported; + this.phoneNumberIdentifierSupported = phoneNumberIdentifierSupported; + this.accountTypes = accountTypes; + this.idTokenRequested = idTokenRequested; + this.serverClientId = serverClientId; + this.idTokenNonce = idTokenNonce; + } + + public String[] getAccountTypes() { + return accountTypes; + } + + public CredentialPickerConfig getHintPickerConfig() { + return hintPickerConfig; + } + + public String getIdTokenNonce() { + return idTokenNonce; + } + + public String getServerClientId() { + return serverClientId; + } + + public boolean isEmailAddressIdentifierSupported() { + return emailAddressIdentifierSupported; + } + + public boolean isPhoneNumberIdentifierSupported() { + return phoneNumberIdentifierSupported; + } + + public boolean isIdTokenRequested() { + return idTokenRequested; + } + + public static final Creator CREATOR = new AutoCreator<>(HintRequest.class); + + @Override + public String toString() { + return "HintRequest{" + + "hintPickerConfig=" + hintPickerConfig + + ", emailAddressIdentifierSupported=" + emailAddressIdentifierSupported + + ", phoneNumberIdentifierSupported=" + phoneNumberIdentifierSupported + + ", accountTypes=" + Arrays.toString(accountTypes) + + ", idTokenRequested=" + idTokenRequested + + ", serverClientId='" + serverClientId + '\'' + + ", idTokenNonce='" + idTokenNonce + '\'' + + '}'; + } + + public static class Builder { + private CredentialPickerConfig hintPickerConfig; + private boolean emailAddressIdentifierSupported; + private boolean phoneNumberIdentifierSupported; + private String[] accountTypes; + private boolean idTokenRequested = true; + private String serverClientId; + private String idTokenNonce; + + /** + * Builds a {@link HintRequest}. + */ + public HintRequest build() { + return new HintRequest(hintPickerConfig, emailAddressIdentifierSupported, phoneNumberIdentifierSupported, accountTypes, idTokenRequested, serverClientId, idTokenNonce); + } + + /** + * Sets the account types (identity providers) that are accepted by this application. + * It is strongly recommended that the strings listed in {@link IdentityProviders} be used for the most common + * identity providers, and strings representing the login domain of the identity provider be used for any + * others which are not listed. + * + * @param accountTypes The list of account types (identity providers) supported by the app. + * typically in the form of the associated login domain for each identity provider. + */ + public void setAccountTypes(String... accountTypes) { + this.accountTypes = accountTypes.clone(); + } + + /** + * Enables returning {@link Credential} hints where the identifier is an email address, intended for use with a password chosen by the user. + */ + public void setEmailAddressIdentifierSupported(boolean emailAddressIdentifierSupported) { + this.emailAddressIdentifierSupported = emailAddressIdentifierSupported; + } + + /** + * Sets the configuration for the hint picker dialog. + */ + public void setHintPickerConfig(CredentialPickerConfig hintPickerConfig) { + this.hintPickerConfig = hintPickerConfig; + } + + /** + * Specify a nonce value that should be included in any generated ID token for this request. + */ + public void setIdTokenNonce(String idTokenNonce) { + this.idTokenNonce = idTokenNonce; + } + + /** + * Specify whether an ID token should be acquired for hints, if available for the selected credential identifier. + * This is enabled by default; disable this if your app does not use ID tokens as part of authentication to decrease latency in retrieving credentials and credential hints. + */ + public void setIdTokenRequested(boolean idTokenRequested) { + this.idTokenRequested = idTokenRequested; + } + + /** + * Enables returning {@link Credential} hints where the identifier is a phone number, intended for use with a password chosen by the user or SMS verification. + */ + public void setPhoneNumberIdentifierSupported(boolean phoneNumberIdentifierSupported) { + this.phoneNumberIdentifierSupported = phoneNumberIdentifierSupported; + } + + /** + * Specify the server client ID for the backend associated with this app. + * If a Google ID token can be generated for a retrieved credential or hint, and the specified server client ID is correctly configured to be associated with the app, then it will be used as the audience of the generated token. + * If a null value is specified, the default audience will be used for the generated ID token. + */ + public void setServerClientId(String serverClientId) { + this.serverClientId = serverClientId; + } + } +} diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java new file mode 100644 index 00000000..72683c7a --- /dev/null +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2021, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.auth.api.credentials; + +import android.accounts.Account; + +/** + * Identity provider constants for use with {@link CredentialRequest.Builder#setAccountTypes(String...)} + */ +public final class IdentityProviders { + public static final String FACEBOOK = "//www.facebook.com"; + public static final String GOOGLE = "//accounts.google.com"; + public static final String LINKEDIN = "//www.linkedin.com"; + public static final String MICROSOFT = "//login.live.com"; + public static final String PAYPAL = "//www.paypal.com"; + public static final String TWITTER = "//twitter.com"; + public static final String YAHOO = "//login.yahoo.com"; + + /** + * Attempts to translate the account type in the provided account into the string that should be used in the credentials API. + * + * @param account an account on the device. + * @return The identity provider string for use with the Credentials API, or {@code null} if the account type is unknown. + */ + public static String getIdentityProviderForAccount(Account account) { + return null; + } +} diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index 8747be32..c421a66b 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -408,6 +408,15 @@ android:authorities="com.google.android.gms.auth.accounts" android:exported="true" /> + + + + + + + diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/CredentialPickerActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/CredentialPickerActivity.kt new file mode 100644 index 00000000..c5f3849c --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/CredentialPickerActivity.kt @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2021, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.app.Activity +import android.os.Bundle +import android.os.Parcel +import android.os.Parcelable +import android.util.Log +import com.google.android.gms.auth.api.credentials.CredentialRequest +import com.google.android.gms.auth.api.credentials.HintRequest + +fun Parcelable.Creator.createFromBytes(bytes: ByteArray): T { + val parcel = Parcel.obtain() + parcel.unmarshall(bytes, 0, bytes.size) + parcel.setDataPosition(0) + try { + return createFromParcel(parcel) + } finally { + parcel.recycle() + } +} + +class CredentialPickerActivity : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val extras = intent.extras ?: Bundle() + val callingPackage = callingActivity?.packageName?.takeIf { extras.getString("claimedCallingPackage", it) == it } + val logSessionId = extras.getString("logSessionId") + val credentialRequest = extras.getByteArray("credentialRequest")?.let { CredentialRequest.CREATOR.createFromBytes(it) } + val hintRequest = extras.getByteArray("com.google.android.gms.credentials.HintRequest")?.let { HintRequest.CREATOR.createFromBytes(it) } + Log.d("GmsCredentialPicker", "Not implemented. callingPackage=$callingPackage, logSessionId=$logSessionId, credentialsRequest=$credentialRequest, hintRequest=$hintRequest") + finish() + } +}