Change the flat request matching logic
Currently the flattened request matching logic
does not support subset checks. We need that to
fully support mdoc element matching.
Bug: 272334103
Test: atest FrameworksServicesTests:com.android.server.credentials.CredentialDescriptionRegistryTest
Change-Id: I7904570146426d33dbf8325c01a825787d1648f0
diff --git a/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java b/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java
index 14c49b3..3b92cc9 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java
@@ -25,17 +25,19 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
/** Contains information on what CredentialProvider has what provisioned Credential. */
public class CredentialDescriptionRegistry {
+ private static final String FLAT_STRING_SPLIT_REGEX = ";";
private static final int MAX_ALLOWED_CREDENTIAL_DESCRIPTIONS = 128;
private static final int MAX_ALLOWED_ENTRIES_PER_PROVIDER = 16;
@GuardedBy("sLock")
@@ -164,14 +166,16 @@
/** Returns package names and entries of a CredentialProviders that can satisfy a given
* {@link CredentialDescription}. */
public Set<FilterResult> getFilteredResultForProvider(String packageName,
- String flatRequestStrings) {
+ String flatRequestString) {
Set<FilterResult> result = new HashSet<>();
if (!mCredentialDescriptions.containsKey(packageName)) {
return result;
}
Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
+ Set<String> unflattenedRequestString = flatStringToSet(flatRequestString);
for (CredentialDescription containedDescription: currentSet) {
- if (flatRequestStrings.equals(containedDescription.getFlattenedRequestString())) {
+ if (checkForMatch(flatStringToSet(containedDescription.getFlattenedRequestString()),
+ unflattenedRequestString)) {
result.add(new FilterResult(packageName,
containedDescription.getFlattenedRequestString(), containedDescription
.getCredentialEntries()));
@@ -182,12 +186,16 @@
/** Returns package names of CredentialProviders that can satisfy a given
* {@link CredentialDescription}. */
- public Set<FilterResult> getMatchingProviders(Set<String> flatRequestString) {
+ public Set<FilterResult> getMatchingProviders(Set<String> flatRequestStrings) {
Set<FilterResult> result = new HashSet<>();
+ Set<Set<String>> unflattenedRequestStrings = flatRequestStrings.stream().map(
+ CredentialDescriptionRegistry::flatStringToSet).collect(Collectors.toSet());
for (String packageName: mCredentialDescriptions.keySet()) {
Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
for (CredentialDescription containedDescription : currentSet) {
- if (flatRequestString.contains(containedDescription.getFlattenedRequestString())) {
+ if (canProviderSatisfyAny(flatStringToSet(containedDescription
+ .getFlattenedRequestString()),
+ unflattenedRequestStrings)) {
result.add(new FilterResult(packageName,
containedDescription.getFlattenedRequestString(), containedDescription
.getCredentialEntries()));
@@ -203,4 +211,24 @@
}
}
+ private static boolean canProviderSatisfyAny(Set<String> registeredUnflattenedStrings,
+ Set<Set<String>> requestedUnflattenedStrings) {
+ for (Set<String> requestedUnflattenedString : requestedUnflattenedStrings) {
+ if (registeredUnflattenedStrings.containsAll(requestedUnflattenedString)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean checkForMatch(Set<String> registeredUnflattenedStrings,
+ Set<String> requestedUnflattenedString) {
+ return registeredUnflattenedStrings.containsAll(requestedUnflattenedString);
+ }
+
+ private static Set<String> flatStringToSet(String flatString) {
+ return new HashSet<>(Arrays
+ .asList(flatString.split(FLAT_STRING_SPLIT_REGEX)));
+ }
+
}
diff --git a/services/tests/servicestests/src/com/android/server/credentials/CredentialDescriptionRegistryTest.java b/services/tests/servicestests/src/com/android/server/credentials/CredentialDescriptionRegistryTest.java
index b7085f1..169210f 100644
--- a/services/tests/servicestests/src/com/android/server/credentials/CredentialDescriptionRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/credentials/CredentialDescriptionRegistryTest.java
@@ -52,8 +52,10 @@
private static final String CALLING_PACKAGE_NAME_2 = "com.credman.app2";
private static final String MDOC_CREDENTIAL_TYPE = "MDOC";
private static final String PASSKEY_CREDENTIAL_TYPE = "PASSKEY";
- private static final String FLATTENED_REQUEST = "FLATTENED_REQ";
- private static final String FLATTENED_REQUEST_2 = "FLATTENED_REQ_2";
+ private static final String FLATTENED_REGISTRY =
+ "FLATTENED_REQ;FLATTENED_REQ123;FLATTENED_REQa";
+ private static final String FLATTENED_REGISTRY_2 = "FLATTENED_REQ_2";
+ private static final String FLATTENED_REQUEST = "FLATTENED_REQ;FLATTENED_REQ123";
private CredentialDescriptionRegistry mCredentialDescriptionRegistry;
private CredentialEntry mEntry;
@@ -104,12 +106,12 @@
@Test
public void testEvictProvider_existingProviders_succeeds() {
final CredentialDescription credentialDescription =
- new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST,
+ new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY,
Collections.emptyList());
final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest =
new RegisterCredentialDescriptionRequest(credentialDescription);
final CredentialDescription credentialDescription2 =
- new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST_2,
+ new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY_2,
Collections.emptyList());
final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 =
new RegisterCredentialDescriptionRequest(credentialDescription2);
@@ -130,12 +132,12 @@
@Test
public void testGetMatchingProviders_existingProviders_succeeds() {
final CredentialDescription credentialDescription =
- new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST,
+ new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY,
Collections.emptyList());
final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest =
new RegisterCredentialDescriptionRequest(credentialDescription);
final CredentialDescription credentialDescription2 =
- new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST,
+ new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY,
Collections.emptyList());
final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 =
new RegisterCredentialDescriptionRequest(credentialDescription2);
@@ -171,11 +173,11 @@
public void testExecuteRegisterRequest_existingProviders_filterSucceeds() {
final CredentialDescription credentialDescription =
new CredentialDescription(MDOC_CREDENTIAL_TYPE,
- FLATTENED_REQUEST,
+ FLATTENED_REGISTRY,
List.of(mEntry, mEntry2));
final CredentialDescription credentialDescription2 =
new CredentialDescription(PASSKEY_CREDENTIAL_TYPE,
- FLATTENED_REQUEST_2,
+ FLATTENED_REGISTRY_2,
List.of(mEntry3));
final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest =
new RegisterCredentialDescriptionRequest(Set.of(credentialDescription,