001/*
002 * Copyright 2016 The AppAuth for Android Authors. All Rights Reserved.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the
010 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
011 * express or implied. See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014
015package net.openid.appauth.browser;
016
017import androidx.annotation.NonNull;
018
019import java.util.Collections;
020import java.util.Set;
021
022/**
023 * Matches a browser based on its package name, set of signatures, version and whether it is
024 * being used as a custom tab. This can be used as part of a browser allowList or denyList.
025 */
026public class VersionedBrowserMatcher implements BrowserMatcher {
027
028    /**
029     * Matches any version of Chrome for use as a custom tab.
030     */
031    public static final VersionedBrowserMatcher CHROME_CUSTOM_TAB = new VersionedBrowserMatcher(
032            Browsers.Chrome.PACKAGE_NAME,
033            Browsers.Chrome.SIGNATURE_SET,
034            true,
035            VersionRange.atLeast(Browsers.Chrome.MINIMUM_VERSION_FOR_CUSTOM_TAB));
036
037    /**
038     * Matches any version of Google Chrome for use as a standalone browser.
039     */
040    public static final VersionedBrowserMatcher CHROME_BROWSER = new VersionedBrowserMatcher(
041            Browsers.Chrome.PACKAGE_NAME,
042            Browsers.Chrome.SIGNATURE_SET,
043            false,
044            VersionRange.ANY_VERSION);
045
046    /**
047     * Matches any version of Firefox for use as a custom tab.
048     */
049    public static final VersionedBrowserMatcher FIREFOX_CUSTOM_TAB = new VersionedBrowserMatcher(
050            Browsers.Firefox.PACKAGE_NAME,
051            Browsers.Firefox.SIGNATURE_SET,
052            true,
053            VersionRange.atLeast(Browsers.Firefox.MINIMUM_VERSION_FOR_CUSTOM_TAB));
054
055    /**
056     * Matches any version of Mozilla Firefox.
057     */
058    public static final VersionedBrowserMatcher FIREFOX_BROWSER = new VersionedBrowserMatcher(
059            Browsers.Firefox.PACKAGE_NAME,
060            Browsers.Firefox.SIGNATURE_SET,
061            false,
062            VersionRange.ANY_VERSION);
063
064    /**
065     * Matches any version of SBrowser for use as a standalone browser.
066     */
067    public static final VersionedBrowserMatcher SAMSUNG_BROWSER = new VersionedBrowserMatcher(
068            Browsers.SBrowser.PACKAGE_NAME,
069            Browsers.SBrowser.SIGNATURE_SET,
070            false,
071            VersionRange.ANY_VERSION);
072
073    /**
074     * Matches any version of SBrowser for use as a custom tab.
075     */
076    public static final VersionedBrowserMatcher SAMSUNG_CUSTOM_TAB = new VersionedBrowserMatcher(
077            Browsers.SBrowser.PACKAGE_NAME,
078            Browsers.SBrowser.SIGNATURE_SET,
079            true,
080            VersionRange.atLeast(Browsers.SBrowser.MINIMUM_VERSION_FOR_CUSTOM_TAB));
081
082    private String mPackageName;
083    private Set<String> mSignatureHashes;
084    private VersionRange mVersionRange;
085    private boolean mUsingCustomTab;
086
087    /**
088     * Creates a browser matcher that requires an exact match on package name, single signature
089     * hash, custom tab usage mode, and a version range.
090     */
091    public VersionedBrowserMatcher(
092            @NonNull String packageName,
093            @NonNull String signatureHash,
094            boolean usingCustomTab,
095            @NonNull VersionRange versionRange) {
096        this(packageName,
097                Collections.singleton(signatureHash),
098                usingCustomTab,
099                versionRange);
100    }
101
102    /**
103     * Creates a browser matcher that requires an exact match on package name, set of signature
104     * hashes, custom tab usage mode, and a version range.
105     */
106    public VersionedBrowserMatcher(
107            @NonNull String packageName,
108            @NonNull Set<String> signatureHashes,
109            boolean usingCustomTab,
110            @NonNull VersionRange versionRange) {
111        mPackageName = packageName;
112        mSignatureHashes = signatureHashes;
113        mUsingCustomTab = usingCustomTab;
114        mVersionRange = versionRange;
115    }
116
117    @Override
118    public boolean matches(@NonNull BrowserDescriptor descriptor) {
119        return mPackageName.equals(descriptor.packageName)
120                && mUsingCustomTab == descriptor.useCustomTab
121                && mVersionRange.matches(descriptor.version)
122                && mSignatureHashes.equals(descriptor.signatureHashes);
123    }
124}