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.service.customaudience;
18 
19 import static com.android.adservices.service.common.Validator.EXCEPTION_MESSAGE_FORMAT;
20 import static com.android.adservices.service.customaudience.CustomAudienceFieldSizeValidator.VIOLATION_TRUSTED_BIDDING_DATA_TOO_BIG;
21 
22 import android.adservices.common.AdTechIdentifier;
23 import android.adservices.customaudience.TrustedBiddingData;
24 import android.annotation.NonNull;
25 
26 import com.android.adservices.data.customaudience.DBTrustedBiddingData;
27 import com.android.adservices.service.common.AdTechUriValidator;
28 import com.android.adservices.service.common.ValidatorUtil;
29 import com.android.internal.annotations.VisibleForTesting;
30 
31 import com.google.common.collect.ImmutableCollection;
32 import com.google.common.collect.ImmutableList;
33 
34 import java.util.Collection;
35 import java.util.Locale;
36 import java.util.Objects;
37 
38 /** Validator for the {@code trustedBiddingData} field of a Custom Audience. */
39 public class TrustedBiddingDataValidator {
40     @VisibleForTesting
41     static final String TRUSTED_BIDDING_DATA_CLASS_NAME = TrustedBiddingData.class.getName();
42     public static final String TRUSTED_BIDDING_URI_FIELD_NAME = "trusted bidding URI";
43     private final int mCustomAudienceMaxTrustedBiddingDataSizeB;
44 
TrustedBiddingDataValidator(int customAudienceMaxTrustedBiddingDataSizeB)45     public TrustedBiddingDataValidator(int customAudienceMaxTrustedBiddingDataSizeB) {
46         mCustomAudienceMaxTrustedBiddingDataSizeB = customAudienceMaxTrustedBiddingDataSizeB;
47     }
48 
49     /**
50      * Validates the {@code trustedBiddingData} field of a Custom Audience against multiple
51      * parameters.
52      *
53      * @param trustedBiddingData the {@code trustedBiddingData} field of a Custom Audience.
54      * @param buyer the buyer expected to be associated with the trustedBiddingData.
55      * @throws IllegalArgumentException if any violation is found
56      */
validate( @onNull TrustedBiddingData trustedBiddingData, @NonNull AdTechIdentifier buyer)57     public void validate(
58             @NonNull TrustedBiddingData trustedBiddingData, @NonNull AdTechIdentifier buyer)
59             throws IllegalArgumentException {
60         Objects.requireNonNull(trustedBiddingData);
61         Objects.requireNonNull(buyer);
62 
63         Collection<String> violations = getValidationViolations(trustedBiddingData, buyer);
64         if (!violations.isEmpty()) {
65             throw new IllegalArgumentException(
66                     String.format(
67                             Locale.ENGLISH,
68                             EXCEPTION_MESSAGE_FORMAT,
69                             TRUSTED_BIDDING_DATA_CLASS_NAME,
70                             violations));
71         }
72     }
73 
74     /**
75      * Populates violations.
76      *
77      * @param trustedBiddingData the {@code trustedBiddingData} field of a Custom Audience.
78      * @param buyer the buyer expected to be associated with the trustedBiddingData.
79      * @return the {@code Collection<String>} of violations found.
80      */
getValidationViolations( @onNull TrustedBiddingData trustedBiddingData, @NonNull AdTechIdentifier buyer)81     public Collection<String> getValidationViolations(
82             @NonNull TrustedBiddingData trustedBiddingData, @NonNull AdTechIdentifier buyer) {
83         Objects.requireNonNull(trustedBiddingData);
84         Objects.requireNonNull(buyer);
85 
86         ImmutableCollection.Builder<String> violations = new ImmutableList.Builder<>();
87         addValidation(trustedBiddingData, buyer, violations);
88         return violations.build();
89     }
90 
91     /**
92      * Validates the {@link TrustedBiddingData} as follows:
93      *
94      * <ul>
95      *   <li>{@link TrustedBiddingData#getTrustedBiddingUri()} is well-formed.
96      *   <li>Size is less than {@code customAudienceMaxTrustedBiddingDataSizeB} (set while
97      *       instantiating a {@link TrustedBiddingDataValidator}).
98      * </ul>
99      *
100      * @param trustedBiddingData the {@link TrustedBiddingData} instance to be validated.
101      * @param violations the collection of violations to add to.
102      */
addValidation( @onNull TrustedBiddingData trustedBiddingData, @NonNull AdTechIdentifier buyer, @NonNull ImmutableCollection.Builder<String> violations)103     public void addValidation(
104             @NonNull TrustedBiddingData trustedBiddingData,
105             @NonNull AdTechIdentifier buyer,
106             @NonNull ImmutableCollection.Builder<String> violations) {
107         Objects.requireNonNull(trustedBiddingData);
108         Objects.requireNonNull(violations);
109 
110         // Validate uri format.
111         AdTechUriValidator adTechUriValidator =
112                 new AdTechUriValidator(
113                         ValidatorUtil.AD_TECH_ROLE_BUYER,
114                         buyer.toString(),
115                         TRUSTED_BIDDING_DATA_CLASS_NAME,
116                         TRUSTED_BIDDING_URI_FIELD_NAME);
117 
118         adTechUriValidator.addValidation(trustedBiddingData.getTrustedBiddingUri(), violations);
119 
120         // Validate the size is within limits.
121         int trustedBiddingDataSizeB =
122                 DBTrustedBiddingData.fromServiceObject(trustedBiddingData).size();
123         if (trustedBiddingDataSizeB > mCustomAudienceMaxTrustedBiddingDataSizeB) {
124             violations.add(
125                     String.format(
126                             Locale.ENGLISH,
127                             VIOLATION_TRUSTED_BIDDING_DATA_TOO_BIG,
128                             mCustomAudienceMaxTrustedBiddingDataSizeB,
129                             trustedBiddingDataSizeB));
130         }
131     }
132 }
133