1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.cts.packagemanager.verify.domain.device.standalone
18 
19 import android.Manifest.permission.DOMAIN_VERIFICATION_AGENT
20 import android.content.UriRelativeFilter
21 import android.content.UriRelativeFilterGroup
22 import android.content.pm.Flags
23 import android.os.PatternMatcher
24 import android.platform.test.annotations.RequiresFlagsEnabled
25 import android.platform.test.flag.junit.CheckFlagsRule
26 import android.platform.test.flag.junit.DeviceFlagsValueProvider
27 import com.android.cts.packagemanager.verify.domain.android.DomainUtils.DECLARING_PKG_1_COMPONENT
28 import com.android.cts.packagemanager.verify.domain.android.DomainVerificationIntentTestBase
29 import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DECLARING_PKG_NAME_1
30 import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DOMAIN_1
31 import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DOMAIN_7
32 import com.google.common.truth.Truth.assertThat
33 import org.junit.After
34 import org.junit.Assert
35 import org.junit.Before
36 import org.junit.Rule
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 import org.junit.runners.Parameterized
40 
41 @RunWith(Parameterized::class)
42 class DomainVerificationFilterGroupTests : DomainVerificationIntentTestBase(DOMAIN_1) {
43     @JvmField
44     @Rule
45     val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
46 
47     val path = "/path"
48     val queryStr = "query=str"
49     val uri1 = "$DOMAIN_1$path?$queryStr"
50     val uri7 = "$DOMAIN_7$path?$queryStr"
51     val wildcard = "*"
52     val wildcardDomain1 = wildcard + DOMAIN_1.substring(DOMAIN_1.indexOf("."))
53     val wildcardDomain7 = wildcard + DOMAIN_7.substring(DOMAIN_7.indexOf("."))
54     val groupsMap: MutableMap<String, List<UriRelativeFilterGroup>> = mutableMapOf()
<lambda>null55     val blockGroup = UriRelativeFilterGroup(UriRelativeFilterGroup.ACTION_BLOCK).apply {
56         this.addUriRelativeFilter(
57             UriRelativeFilter(UriRelativeFilter.QUERY, PatternMatcher.PATTERN_LITERAL, queryStr)
58         )
59     }
<lambda>null60     val allowGroup = UriRelativeFilterGroup(UriRelativeFilterGroup.ACTION_ALLOW).apply {
61         this.addUriRelativeFilter(
62             UriRelativeFilter(UriRelativeFilter.PATH, PatternMatcher.PATTERN_LITERAL, path)
63         )
64     }
65     val emptyGroupsMap: Map<String, List<UriRelativeFilterGroup>> = mapOf(
66         DOMAIN_1 to emptyList(),
67         DOMAIN_7 to emptyList(),
68         wildcardDomain1 to emptyList(),
69         wildcardDomain7 to emptyList(),
70     )
71 
72     @Before
73     @After
clearGroupsnull74     fun clearGroups() {
75         groupsMap.clear()
76         instrumentation.uiAutomation.adoptShellPermissionIdentity(DOMAIN_VERIFICATION_AGENT)
77         try {
78             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, emptyGroupsMap)
79             val map = manager.getUriRelativeFilterGroups(
80                 DECLARING_PKG_NAME_1,
81                 listOf(DOMAIN_1, DOMAIN_7)
82             )
83             assertThat(map).isEmpty()
84         } finally {
85             instrumentation.uiAutomation.dropShellPermissionIdentity()
86         }
87     }
88 
89     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
90     @Test
resolveWithUriRelativeFilterGroups_domainNotVerifiednull91     fun resolveWithUriRelativeFilterGroups_domainNotVerified() {
92         setAppLinks(DECLARING_PKG_NAME_1, false, DOMAIN_1, DOMAIN_7)
93         assertResolvesTo(browsers, uri1)
94         assertResolvesTo(browsers, uri7)
95 
96         Assert.assertThrows(SecurityException::class.java) {
97             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, emptyGroupsMap)
98         }
99 
100         instrumentation.uiAutomation.adoptShellPermissionIdentity(DOMAIN_VERIFICATION_AGENT)
101         try {
102             groupsMap.put(DOMAIN_7, listOf(allowGroup))
103             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
104             val map = manager.getUriRelativeFilterGroups(DECLARING_PKG_NAME_1, listOf(DOMAIN_7))
105             assertThat(map).containsExactlyEntriesIn(groupsMap).inOrder()
106             assertResolvesTo(browsers, uri1)
107             assertResolvesTo(browsers, uri7)
108         } finally {
109             instrumentation.uiAutomation.dropShellPermissionIdentity()
110         }
111     }
112 
113     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
114     @Test
resolveWithUriRelativeFilterGroups_wildcardDomainsnull115     fun resolveWithUriRelativeFilterGroups_wildcardDomains() {
116         setAppLinks(DECLARING_PKG_NAME_1, true, DOMAIN_1, DOMAIN_7)
117         assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri1)
118         assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri7)
119 
120         instrumentation.uiAutomation.adoptShellPermissionIdentity(DOMAIN_VERIFICATION_AGENT)
121         try {
122             groupsMap.put(wildcardDomain1, listOf(blockGroup, allowGroup))
123             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
124             assertThat(
125                 manager.getUriRelativeFilterGroups(
126                     DECLARING_PKG_NAME_1,
127                     listOf(wildcardDomain1)
128                 )
129             ).containsExactlyEntriesIn(groupsMap)
130             assertResolvesTo(browsers, uri1)
131             assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri7)
132 
133             groupsMap.put(wildcardDomain7, listOf(blockGroup, allowGroup))
134             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
135             assertThat(
136                 manager.getUriRelativeFilterGroups(
137                     DECLARING_PKG_NAME_1,
138                     listOf(wildcardDomain1, wildcardDomain7)
139                 )
140             ).containsExactlyEntriesIn(groupsMap)
141             assertResolvesTo(browsers, uri1)
142             assertResolvesTo(browsers, uri7)
143 
144             groupsMap.put(DOMAIN_1, listOf(allowGroup, blockGroup))
145             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
146             assertThat(
147                 manager.getUriRelativeFilterGroups(
148                     DECLARING_PKG_NAME_1,
149                     listOf(wildcardDomain1, wildcardDomain7, DOMAIN_1)
150                 )
151             ).containsExactlyEntriesIn(groupsMap)
152             assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri1)
153             assertResolvesTo(browsers, uri7)
154 
155             groupsMap.put(DOMAIN_7, listOf(allowGroup, blockGroup))
156             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
157             assertThat(
158                 manager.getUriRelativeFilterGroups(
159                     DECLARING_PKG_NAME_1,
160                     listOf(wildcardDomain1, wildcardDomain7, DOMAIN_1, DOMAIN_7)
161                 )
162             ).containsExactlyEntriesIn(groupsMap)
163             assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri1)
164             assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri7)
165 
166             assertThat(
167                 manager.getUriRelativeFilterGroups(
168                     DECLARING_PKG_NAME_1,
169                     listOf(
170                         wildcardDomain1,
171                         wildcardDomain7,
172                         DOMAIN_1,
173                         DOMAIN_7,
174                         "non.existent.domain"
175                     )
176                 )
177             ).containsExactlyEntriesIn(groupsMap)
178         } finally {
179             instrumentation.uiAutomation.dropShellPermissionIdentity()
180         }
181     }
182 
183     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
184     @Test
setUriRelativeFilterGroup_rejectBadDomainsnull185     fun setUriRelativeFilterGroup_rejectBadDomains() {
186         instrumentation.uiAutomation.adoptShellPermissionIdentity(DOMAIN_VERIFICATION_AGENT)
187         try {
188             val longLabel = "a".repeat(64)
189             val badDomains =
190                 listOf(
191                     "",
192                     ".",
193                     "some..domain",
194                     "...",
195                     "*",
196                     "*.",
197                     "some.$longLabel.domain",
198                     "a".repeat(127) + "." + "b".repeat(127),
199                     "abcd",
200                     "a.b.*.d.e"
201                 )
202             for (domain in badDomains) {
203                 groupsMap.put(domain, listOf(allowGroup))
204                 manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
205                 assertThat(
206                     manager.getUriRelativeFilterGroups(
207                         DECLARING_PKG_NAME_1,
208                         listOf(domain)
209                     )
210                 ).isEmpty()
211             }
212         } finally {
213             instrumentation.uiAutomation.dropShellPermissionIdentity()
214         }
215     }
216 
217     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
218     @Test
resolveWithUriRelativeFilterGroups_domainVerifiednull219     fun resolveWithUriRelativeFilterGroups_domainVerified() {
220         assertResolveFilterGroups(DOMAIN_1, uri1, uri7)
221     }
222 
223     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
224     @Test
resolveWithUriRelativeFilterGroups_domainVerifiedWithIntentGroupsnull225     fun resolveWithUriRelativeFilterGroups_domainVerifiedWithIntentGroups() {
226         assertResolveFilterGroups(DOMAIN_7, uri7, uri1)
227     }
228 
assertResolveFilterGroupsnull229     private fun assertResolveFilterGroups(domain: String, targetUri: String, controlUri: String) {
230         setAppLinks(DECLARING_PKG_NAME_1, true, DOMAIN_1, DOMAIN_7)
231         assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri1)
232         assertResolvesTo(DECLARING_PKG_1_COMPONENT, uri7)
233 
234         instrumentation.uiAutomation.adoptShellPermissionIdentity(DOMAIN_VERIFICATION_AGENT)
235         try {
236             groupsMap.put(domain, listOf(allowGroup, blockGroup))
237             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
238             assertThat(manager.getUriRelativeFilterGroups(DECLARING_PKG_NAME_1, listOf(domain)))
239                 .containsExactlyEntriesIn(groupsMap).inOrder()
240             assertResolvesTo(DECLARING_PKG_1_COMPONENT, controlUri)
241             assertResolvesTo(DECLARING_PKG_1_COMPONENT, targetUri)
242 
243             groupsMap.put(domain, listOf(blockGroup, allowGroup))
244             manager.setUriRelativeFilterGroups(DECLARING_PKG_NAME_1, groupsMap)
245             assertThat(manager.getUriRelativeFilterGroups(DECLARING_PKG_NAME_1, listOf(domain)))
246                 .containsExactlyEntriesIn(groupsMap).inOrder()
247             assertResolvesTo(browsers, targetUri)
248             assertResolvesTo(DECLARING_PKG_1_COMPONENT, controlUri)
249         } finally {
250             instrumentation.uiAutomation.dropShellPermissionIdentity()
251         }
252     }
253 }
254