• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.adservices.tests.permissions;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertThrows;
22 
23 import android.adservices.adselection.AdSelectionConfig;
24 import android.adservices.adselection.AdSelectionConfigFixture;
25 import android.adservices.adselection.AddAdSelectionOverrideRequest;
26 import android.adservices.adselection.RemoveAdSelectionOverrideRequest;
27 import android.adservices.adselection.ReportImpressionRequest;
28 import android.adservices.clients.adselection.AdSelectionClient;
29 import android.adservices.clients.adselection.TestAdSelectionClient;
30 import android.adservices.clients.customaudience.AdvertisingCustomAudienceClient;
31 import android.adservices.clients.customaudience.TestAdvertisingCustomAudienceClient;
32 import android.adservices.clients.topics.AdvertisingTopicsClient;
33 import android.adservices.common.AdSelectionSignals;
34 import android.adservices.common.AdTechIdentifier;
35 import android.adservices.customaudience.AddCustomAudienceOverrideRequest;
36 import android.adservices.customaudience.CustomAudience;
37 import android.adservices.customaudience.RemoveCustomAudienceOverrideRequest;
38 import android.content.Context;
39 import android.net.Uri;
40 
41 import androidx.test.core.app.ApplicationProvider;
42 import androidx.test.ext.junit.runners.AndroidJUnit4;
43 
44 import com.android.adservices.common.CompatAdServicesTestUtils;
45 import com.android.compatibility.common.util.ShellUtils;
46 import com.android.modules.utils.build.SdkLevel;
47 
48 import org.junit.After;
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 
53 import java.util.concurrent.ExecutionException;
54 import java.util.concurrent.Executor;
55 import java.util.concurrent.Executors;
56 
57 /** In the manifest file, no API permissions are declared for this test. */
58 @RunWith(AndroidJUnit4.class)
59 // TODO: Add tests for measurement (b/238194122).
60 public class PermissionsNoPermTest {
61     private static final Executor CALLBACK_EXECUTOR = Executors.newCachedThreadPool();
62     private static final Context sContext = ApplicationProvider.getApplicationContext();
63     private static final String CALLER_NOT_AUTHORIZED =
64             "java.lang.SecurityException: Caller is not authorized to call this API. "
65                     + "Permission was not requested.";
66 
67     private String mPreviousAppAllowList;
68 
69     @Before
setup()70     public void setup() {
71         if (!SdkLevel.isAtLeastT()) {
72             overridePpapiAppAllowList();
73             CompatAdServicesTestUtils.setFlags();
74         }
75     }
76 
77     @After
tearDown()78     public void tearDown() throws Exception {
79         if (!SdkLevel.isAtLeastT()) {
80             setPpapiAppAllowList(mPreviousAppAllowList);
81             CompatAdServicesTestUtils.resetFlagsToDefault();
82         }
83     }
84 
setPpapiAppAllowList(String allowList)85     private void setPpapiAppAllowList(String allowList) {
86         ShellUtils.runShellCommand(
87                 "device_config put adservices ppapi_app_allow_list " + allowList);
88     }
89 
overridePpapiAppAllowList()90     private void overridePpapiAppAllowList() {
91         mPreviousAppAllowList =
92                 ShellUtils.runShellCommand("device_config get adservices ppapi_app_allow_list");
93         setPpapiAppAllowList(mPreviousAppAllowList + "," + sContext.getPackageName());
94     }
95 
96     @Test
testNoPerm_topics()97     public void testNoPerm_topics() {
98         AdvertisingTopicsClient advertisingTopicsClient1 =
99                 new AdvertisingTopicsClient.Builder()
100                         .setContext(sContext)
101                         .setSdkName("sdk1")
102                         .setExecutor(CALLBACK_EXECUTOR)
103                         .build();
104 
105         ExecutionException exception =
106                 assertThrows(
107                         ExecutionException.class, () -> advertisingTopicsClient1.getTopics().get());
108         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
109     }
110 
111     @Test
testPermissionNotRequested_fledgeJoinCustomAudience()112     public void testPermissionNotRequested_fledgeJoinCustomAudience() {
113         AdvertisingCustomAudienceClient customAudienceClient =
114                 new AdvertisingCustomAudienceClient.Builder()
115                         .setContext(sContext)
116                         .setExecutor(CALLBACK_EXECUTOR)
117                         .build();
118 
119         CustomAudience customAudience =
120                 new CustomAudience.Builder()
121                         .setBuyer(AdTechIdentifier.fromString("buyer.example.com"))
122                         .setName("exampleCustomAudience")
123                         .setDailyUpdateUri(Uri.parse("https://buyer.example.com/daily-update"))
124                         .setBiddingLogicUri(Uri.parse("https://buyer.example.com/bidding-logic"))
125                         .build();
126 
127         ExecutionException exception =
128                 assertThrows(
129                         ExecutionException.class,
130                         () -> customAudienceClient.joinCustomAudience(customAudience).get());
131         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
132     }
133 
134     @Test
testPermissionNotRequested_fledgeLeaveCustomAudience()135     public void testPermissionNotRequested_fledgeLeaveCustomAudience() {
136         AdvertisingCustomAudienceClient customAudienceClient =
137                 new AdvertisingCustomAudienceClient.Builder()
138                         .setContext(sContext)
139                         .setExecutor(CALLBACK_EXECUTOR)
140                         .build();
141 
142         ExecutionException exception =
143                 assertThrows(
144                         ExecutionException.class,
145                         () ->
146                                 customAudienceClient
147                                         .leaveCustomAudience(
148                                                 AdTechIdentifier.fromString("buyer.example.com"),
149                                                 "exampleCustomAudience")
150                                         .get());
151         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
152     }
153 
154     @Test
testPermissionNotRequested_fledgeOverrideCustomAudienceRemoteInfo()155     public void testPermissionNotRequested_fledgeOverrideCustomAudienceRemoteInfo() {
156         TestAdvertisingCustomAudienceClient testCustomAudienceClient =
157                 new TestAdvertisingCustomAudienceClient.Builder()
158                         .setContext(sContext)
159                         .setExecutor(CALLBACK_EXECUTOR)
160                         .build();
161 
162         AddCustomAudienceOverrideRequest request =
163                 new AddCustomAudienceOverrideRequest.Builder()
164                         .setBuyer(AdTechIdentifier.fromString("buyer.example.com"))
165                         .setName("exampleCustomAudience")
166                         .setBiddingLogicJs("function test() { return \"hello, world!\"; }")
167                         .setTrustedBiddingSignals(AdSelectionSignals.fromString("{\"test\":1}"))
168                         .build();
169 
170         ExecutionException exception =
171                 assertThrows(
172                         ExecutionException.class,
173                         () ->
174                                 testCustomAudienceClient
175                                         .overrideCustomAudienceRemoteInfo(request)
176                                         .get());
177         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
178     }
179 
180     @Test
testPermissionNotRequested_fledgeRemoveCustomAudienceRemoteInfoOverride()181     public void testPermissionNotRequested_fledgeRemoveCustomAudienceRemoteInfoOverride() {
182         TestAdvertisingCustomAudienceClient testCustomAudienceClient =
183                 new TestAdvertisingCustomAudienceClient.Builder()
184                         .setContext(sContext)
185                         .setExecutor(CALLBACK_EXECUTOR)
186                         .build();
187 
188         RemoveCustomAudienceOverrideRequest request =
189                 new RemoveCustomAudienceOverrideRequest.Builder()
190                         .setBuyer(AdTechIdentifier.fromString("buyer.example.com"))
191                         .setName("exampleCustomAudience")
192                         .build();
193 
194         ExecutionException exception =
195                 assertThrows(
196                         ExecutionException.class,
197                         () ->
198                                 testCustomAudienceClient
199                                         .removeCustomAudienceRemoteInfoOverride(request)
200                                         .get());
201         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
202     }
203 
204     @Test
testPermissionNotRequested_fledgeResetAllCustomAudienceOverrides()205     public void testPermissionNotRequested_fledgeResetAllCustomAudienceOverrides() {
206         TestAdvertisingCustomAudienceClient testCustomAudienceClient =
207                 new TestAdvertisingCustomAudienceClient.Builder()
208                         .setContext(sContext)
209                         .setExecutor(CALLBACK_EXECUTOR)
210                         .build();
211 
212         ExecutionException exception =
213                 assertThrows(
214                         ExecutionException.class,
215                         () -> testCustomAudienceClient.resetAllCustomAudienceOverrides().get());
216         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
217     }
218 
219     @Test
testPermissionNotRequested_selectAds_adSelectionConfig()220     public void testPermissionNotRequested_selectAds_adSelectionConfig() {
221         AdSelectionConfig adSelectionConfig = AdSelectionConfigFixture.anAdSelectionConfig();
222 
223         AdSelectionClient mAdSelectionClient =
224                 new AdSelectionClient.Builder()
225                         .setContext(sContext)
226                         .setExecutor(CALLBACK_EXECUTOR)
227                         .build();
228 
229         ExecutionException exception =
230                 assertThrows(
231                         ExecutionException.class,
232                         () -> mAdSelectionClient.selectAds(adSelectionConfig).get());
233         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
234     }
235 
236     @Test
testPermissionNotRequested_reportImpression()237     public void testPermissionNotRequested_reportImpression() {
238         AdSelectionConfig adSelectionConfig = AdSelectionConfigFixture.anAdSelectionConfig();
239 
240         long adSelectionId = 1;
241 
242         AdSelectionClient mAdSelectionClient =
243                 new AdSelectionClient.Builder()
244                         .setContext(sContext)
245                         .setExecutor(CALLBACK_EXECUTOR)
246                         .build();
247 
248         ReportImpressionRequest request =
249                 new ReportImpressionRequest(adSelectionId, adSelectionConfig);
250 
251         ExecutionException exception =
252                 assertThrows(
253                         ExecutionException.class,
254                         () -> mAdSelectionClient.reportImpression(request).get());
255         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
256     }
257 
258 // TODO(b/274723533): Uncomment after un-hiding the API
259 /*
260     @Test
261     public void testPermissionNotRequested_reportInteraction() {
262         long adSelectionId = 1;
263         String interactionKey = "click";
264         String interactionData = "{\"key\":\"value\"}";
265 
266         AdSelectionClient mAdSelectionClient =
267                 new AdSelectionClient.Builder()
268                         .setContext(sContext)
269                         .setExecutor(CALLBACK_EXECUTOR)
270                         .build();
271 
272         ReportInteractionRequest request =
273                 new ReportInteractionRequest(
274                         adSelectionId,
275                         interactionKey,
276                         interactionData,
277                         ReportInteractionRequest.FLAG_REPORTING_DESTINATION_BUYER
278                                 | ReportInteractionRequest.FLAG_REPORTING_DESTINATION_SELLER);
279 
280         ExecutionException exception =
281                 assertThrows(
282                         ExecutionException.class,
283                         () -> mAdSelectionClient.reportInteraction(request).get());
284         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
285     }
286 */
287 
288     @Test
testPermissionNotRequested_fledgeOverrideAdSelectionConfigRemoteInfo()289     public void testPermissionNotRequested_fledgeOverrideAdSelectionConfigRemoteInfo() {
290         TestAdSelectionClient testAdSelectionClient =
291                 new TestAdSelectionClient.Builder()
292                         .setContext(sContext)
293                         .setExecutor(CALLBACK_EXECUTOR)
294                         .build();
295 
296         String decisionLogicJs = "function test() { return \"hello world\"; }";
297         AdSelectionSignals trustedScoringSignals =
298                 AdSelectionSignals.fromString(
299                         "{\n"
300                                 + "\t\"render_uri_1\": \"signals_for_1\",\n"
301                                 + "\t\"render_uri_2\": \"signals_for_2\"\n"
302                                 + "}");
303 
304         AdSelectionConfig adSelectionConfig = AdSelectionConfigFixture.anAdSelectionConfig();
305 
306         AddAdSelectionOverrideRequest request =
307                 new AddAdSelectionOverrideRequest(
308                         adSelectionConfig, decisionLogicJs, trustedScoringSignals);
309 
310         Exception exception =
311                 assertThrows(
312                         ExecutionException.class,
313                         () -> {
314                             testAdSelectionClient
315                                     .overrideAdSelectionConfigRemoteInfo(request)
316                                     .get();
317                         });
318         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
319     }
320 
321     @Test
testPermissionNotRequested_fledgeRemoveAdSelectionConfigRemoteInfo()322     public void testPermissionNotRequested_fledgeRemoveAdSelectionConfigRemoteInfo() {
323         TestAdSelectionClient testAdSelectionClient =
324                 new TestAdSelectionClient.Builder()
325                         .setContext(sContext)
326                         .setExecutor(CALLBACK_EXECUTOR)
327                         .build();
328 
329         AdSelectionConfig adSelectionConfig = AdSelectionConfigFixture.anAdSelectionConfig();
330 
331         RemoveAdSelectionOverrideRequest request =
332                 new RemoveAdSelectionOverrideRequest(adSelectionConfig);
333 
334         Exception exception =
335                 assertThrows(
336                         ExecutionException.class,
337                         () -> {
338                             testAdSelectionClient
339                                     .removeAdSelectionConfigRemoteInfoOverride(request)
340                                     .get();
341                         });
342         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
343     }
344 
345     @Test
testPermissionNotRequested_fledgeResetAllAdSelectionConfigRemoteOverrides()346     public void testPermissionNotRequested_fledgeResetAllAdSelectionConfigRemoteOverrides() {
347         TestAdSelectionClient testAdSelectionClient =
348                 new TestAdSelectionClient.Builder()
349                         .setContext(sContext)
350                         .setExecutor(CALLBACK_EXECUTOR)
351                         .build();
352 
353         Exception exception =
354                 assertThrows(
355                         ExecutionException.class,
356                         () -> {
357                             testAdSelectionClient.resetAllAdSelectionConfigRemoteOverrides().get();
358                         });
359         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
360     }
361 
362     // TODO(b/221876775): Unhide for frequency cap mainline promotion
363     /*
364     @Test
365     public void testPermissionNotRequested_updateAdCounterHistogram() {
366         long adSelectionId = 1;
367 
368         AdSelectionClient mAdSelectionClient =
369                 new AdSelectionClient.Builder()
370                         .setContext(sContext)
371                         .setExecutor(CALLBACK_EXECUTOR)
372                         .build();
373 
374         UpdateAdCounterHistogramRequest request =
375                 new UpdateAdCounterHistogramRequest.Builder()
376                         .setAdSelectionId(adSelectionId)
377                         .setAdEventType(FrequencyCapFilters.AD_EVENT_TYPE_IMPRESSION)
378                         .setCallerAdTech(AdTechIdentifier.fromString("test.com"))
379                         .build();
380         ExecutionException exception =
381                 assertThrows(
382                         ExecutionException.class,
383                         () -> mAdSelectionClient.updateAdCounterHistogram(request).get());
384 
385         assertThat(exception.getMessage()).isEqualTo(CALLER_NOT_AUTHORIZED);
386     }
387     */
388 }
389