/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.permission2.cts;

import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;

import static com.google.common.collect.Maps.filterValues;
import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.newHashSet;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.test.AndroidTestCase;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;

import androidx.test.InstrumentationRegistry;

import com.android.compatibility.common.util.SystemUtil;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * Tests enforcement of signature|privileged permission whitelist:
 * <ul>
 * <li>Report what is granted into the CTS log
 * <li>Ensure all priv permissions are exclusively granted to applications declared in
 * &lt;privapp-permissions&gt;
 * </ul>
 */
public class PrivappPermissionsTest extends AndroidTestCase {

    private static final String TAG = "PrivappPermissionsTest";

    private static final String PLATFORM_PACKAGE_NAME = "android";

    public void testPrivappPermissionsEnforcement() throws Exception {
        Set<String> platformPrivPermissions = new HashSet<>();
        PackageManager pm = getContext().getPackageManager();
        PackageInfo platformPackage = pm.getPackageInfo(PLATFORM_PACKAGE_NAME,
                PackageManager.GET_PERMISSIONS);

        for (PermissionInfo permission : platformPackage.permissions) {
            int protectionLevel = permission.protectionLevel;
            if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
                platformPrivPermissions.add(permission.name);
            }
        }

        List<PackageInfo> installedPackages = pm
                .getInstalledPackages(MATCH_UNINSTALLED_PACKAGES | GET_PERMISSIONS);
        installedPackages.sort(Comparator.comparing(p -> p.packageName));

        Map<String, Set<String>> packagesGrantedNotInWhitelist = new HashMap<>();
        Map<String, Set<String>> packagesNotGrantedNotRemovedNotInDenylist = new HashMap<>();
        for (PackageInfo pkg : installedPackages) {
            String packageName = pkg.packageName;
            if (!pkg.applicationInfo.isPrivilegedApp()
                    || PLATFORM_PACKAGE_NAME.equals(packageName)) {
                continue;
            }

            PackageInfo factoryPkg = pm
                    .getPackageInfo(packageName, MATCH_FACTORY_ONLY | GET_PERMISSIONS
                        | MATCH_UNINSTALLED_PACKAGES);

            assertNotNull("No system image version found for " + packageName, factoryPkg);

            Set<String> factoryRequestedPrivPermissions;
            if (factoryPkg.requestedPermissions == null) {
                factoryRequestedPrivPermissions = Collections.emptySet();
            } else {
                factoryRequestedPrivPermissions = intersection(
                        newHashSet(factoryPkg.requestedPermissions), platformPrivPermissions);
            }

            Map<String, Boolean> requestedPrivPermissions = new ArrayMap<>();
            if (pkg.requestedPermissions != null) {
                for (int i = 0; i < pkg.requestedPermissions.length; i++) {
                    String permission = pkg.requestedPermissions[i];
                    if (platformPrivPermissions.contains(permission)) {
                        requestedPrivPermissions.put(permission,
                                (pkg.requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
                                        != 0);
                    }
                }
            }

            // If an app is requesting any privileged permissions, log the details and verify
            // that granted permissions are whitelisted
            if (!factoryRequestedPrivPermissions.isEmpty() && !requestedPrivPermissions.isEmpty()) {
                Set<String> granted = filterValues(requestedPrivPermissions,
                        isGranted -> isGranted).keySet();

                Set<String> factoryNotGranted = difference(factoryRequestedPrivPermissions,
                        granted);

                // priv permissions that the system package requested, but the current package not
                // anymore
                Set<String> removed = difference(factoryRequestedPrivPermissions,
                        requestedPrivPermissions.keySet());

                Set<String> whitelist = getPrivAppPermissions(packageName);
                Set<String> denylist = getPrivAppDenyPermissions(packageName);
                String msg = "Application " + packageName + "\n"
                        + "  Factory requested permissions:\n"
                        + getPrintableSet("    ", factoryRequestedPrivPermissions)
                        + "  Granted:\n"
                        + getPrintableSet("    ", granted)
                        + "  Removed:\n"
                        + getPrintableSet("    ", removed)
                        + "  Whitelisted:\n"
                        + getPrintableSet("    ", whitelist)
                        + "  Denylisted:\n"
                        + getPrintableSet("    ", denylist)
                        + "  Factory not granted:\n"
                        + getPrintableSet("    ", factoryNotGranted);

                for (String line : msg.split("\n")) {
                    Log.i(TAG, line);

                    // Prevent log from truncating output
                    Thread.sleep(10);
                }

                Set<String> grantedNotInWhitelist = difference(granted, whitelist);
                Set<String> factoryNotGrantedNotRemovedNotInDenylist = difference(difference(
                        factoryNotGranted, removed), denylist);

                if (!grantedNotInWhitelist.isEmpty()) {
                    packagesGrantedNotInWhitelist.put(packageName, grantedNotInWhitelist);
                }

                if (!factoryNotGrantedNotRemovedNotInDenylist.isEmpty()) {
                    packagesNotGrantedNotRemovedNotInDenylist.put(packageName,
                            factoryNotGrantedNotRemovedNotInDenylist);
                }
            }
        }
        StringBuilder message = new StringBuilder();
        if (!packagesGrantedNotInWhitelist.isEmpty()) {
            message.append("Not whitelisted permissions are granted: "
                    + packagesGrantedNotInWhitelist.toString());
        }
        if (!packagesNotGrantedNotRemovedNotInDenylist.isEmpty()) {
            if (message.length() != 0) {
                message.append(", ");
            }
            message.append("Requested permissions not granted: "
                    + packagesNotGrantedNotRemovedNotInDenylist.toString());
        }
        if (!packagesGrantedNotInWhitelist.isEmpty()
                || !packagesNotGrantedNotRemovedNotInDenylist.isEmpty()) {
            fail(message.toString());
        }
    }

    private <T> String getPrintableSet(String indendation, Set<T> set) {
        if (set.isEmpty()) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        for (T e : new TreeSet<>(set)) {
            if (!TextUtils.isEmpty(e.toString().trim())) {
                sb.append(indendation);
                sb.append(e);
                sb.append("\n");
            }
        }

        return sb.toString();
    }

    private Set<String> getPrivAppPermissions(String packageName) throws IOException {
        String output = SystemUtil.runShellCommand(
                InstrumentationRegistry.getInstrumentation(),
                "cmd package get-privapp-permissions " + packageName).trim();
        if (output.startsWith("{") && output.endsWith("}")) {
            String[] split = output.substring(1, output.length() - 1).split("\\s*,\\s*");
            return new LinkedHashSet<>(Arrays.asList(split));
        }
        return Collections.emptySet();
    }

    private Set<String> getPrivAppDenyPermissions(String packageName) throws IOException {
        String output = SystemUtil.runShellCommand(
                InstrumentationRegistry.getInstrumentation(),
                "cmd package get-privapp-deny-permissions " + packageName).trim();
        if (output.startsWith("{") && output.endsWith("}")) {
            String[] split = output.substring(1, output.length() - 1).split("\\s*,\\s*");
            return new LinkedHashSet<>(Arrays.asList(split));
        }
        return Collections.emptySet();
    }

}
