blob: a3d8e0c64de8ce7882806b2903ef62ed933881f6 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/grit/generated_resources.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_info.h"
#include "extensions/common/permissions/settings_override_permission.h"
#include "extensions/common/permissions/usb_device_permission.h"
#include "extensions/common/url_pattern_set.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
namespace extensions {
// Tests that ChromePermissionMessageProvider provides correct permission
// messages for given permissions.
// NOTE: No extensions are created as part of these tests. Integration tests
// that test the messages are generated properly for extensions can be found in
// chrome/browser/extensions/permission_messages_unittest.cc.
class ChromePermissionMessageProviderUnittest : public testing::Test {
public:
ChromePermissionMessageProviderUnittest()
: message_provider_(new ChromePermissionMessageProvider()) {}
~ChromePermissionMessageProviderUnittest() override {}
protected:
PermissionMessages GetMessages(const APIPermissionSet& permissions,
Manifest::Type type) {
return message_provider_->GetPermissionMessages(
message_provider_->GetAllPermissionIDs(
PermissionSet(permissions.Clone(), ManifestPermissionSet(),
URLPatternSet(), URLPatternSet()),
type));
}
PermissionMessages GetPowerfulMessages(const APIPermissionSet& permissions,
Manifest::Type type) {
return message_provider_->GetPowerfulPermissionMessages(
message_provider_->GetAllPermissionIDs(
PermissionSet(permissions.Clone(), ManifestPermissionSet(),
URLPatternSet(), URLPatternSet()),
type));
}
bool IsPrivilegeIncrease(const APIPermissionSet& granted_permissions,
const APIPermissionSet& requested_permissions) {
return message_provider_->IsPrivilegeIncrease(
PermissionSet(granted_permissions.Clone(), ManifestPermissionSet(),
URLPatternSet(), URLPatternSet()),
PermissionSet(requested_permissions.Clone(), ManifestPermissionSet(),
URLPatternSet(), URLPatternSet()),
Manifest::TYPE_EXTENSION);
}
ChromePermissionMessageProvider* message_provider() {
return message_provider_.get();
}
private:
std::unique_ptr<ChromePermissionMessageProvider> message_provider_;
DISALLOW_COPY_AND_ASSIGN(ChromePermissionMessageProviderUnittest);
};
// Checks that if an app has a superset and a subset permission, only the
// superset permission message is displayed if they are both present.
TEST_F(ChromePermissionMessageProviderUnittest,
SupersetOverridesSubsetPermission) {
{
APIPermissionSet permissions;
permissions.insert(APIPermission::kTab);
PermissionMessages messages =
GetMessages(permissions, Manifest::TYPE_PLATFORM_APP);
ASSERT_EQ(1U, messages.size());
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
messages.front().message());
}
{
APIPermissionSet permissions;
permissions.insert(APIPermission::kTopSites);
PermissionMessages messages =
GetMessages(permissions, Manifest::TYPE_PLATFORM_APP);
ASSERT_EQ(1U, messages.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_TOPSITES),
messages.front().message());
}
{
APIPermissionSet permissions;
permissions.insert(APIPermission::kTab);
permissions.insert(APIPermission::kTopSites);
PermissionMessages messages =
GetMessages(permissions, Manifest::TYPE_PLATFORM_APP);
ASSERT_EQ(1U, messages.size());
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
messages.front().message());
}
}
// Checks that when permissions are merged into a single message, their details
// are merged as well.
TEST_F(ChromePermissionMessageProviderUnittest,
WarningsAndDetailsCoalesceTogether) {
// kTab and kTopSites should be merged into a single message.
APIPermissionSet permissions;
permissions.insert(APIPermission::kTab);
permissions.insert(APIPermission::kTopSites);
// The USB device permission message has a non-empty details string.
std::unique_ptr<UsbDevicePermission> usb(new UsbDevicePermission(
PermissionsInfo::GetInstance()->GetByID(APIPermission::kUsbDevice)));
std::unique_ptr<base::ListValue> devices_list(new base::ListValue());
devices_list->Append(
UsbDevicePermissionData(0x02ad, 0x138c, -1, -1).ToValue());
devices_list->Append(
UsbDevicePermissionData(0x02ad, 0x138d, -1, -1).ToValue());
ASSERT_TRUE(usb->FromValue(devices_list.get(), nullptr, nullptr));
permissions.insert(std::move(usb));
PermissionMessages messages =
GetMessages(permissions, Manifest::TYPE_EXTENSION);
ASSERT_EQ(2U, messages.size());
auto it = messages.begin();
const PermissionMessage& message0 = *it++;
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
message0.message());
EXPECT_TRUE(message0.submessages().empty());
const PermissionMessage& message1 = *it++;
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST),
message1.message());
EXPECT_FALSE(message1.submessages().empty());
}
// Check that if IDN domains are provided in host permissions, then those
// domains are converted to punycode.
TEST_F(ChromePermissionMessageProviderUnittest,
IDNDomainsInHostPermissionsArePunycoded) {
extensions::URLPatternSet explicit_hosts;
explicit_hosts.AddPattern(
URLPattern(URLPattern::SCHEME_ALL, "https://ɡoogle.com/"));
explicit_hosts.AddPattern(
URLPattern(URLPattern::SCHEME_ALL, "https://*.ɡoogle.com/"));
extensions::PermissionSet permissions(APIPermissionSet(),
ManifestPermissionSet(), explicit_hosts,
URLPatternSet());
PermissionMessages messages = message_provider()->GetPermissionMessages(
message_provider()->GetAllPermissionIDs(permissions,
Manifest::TYPE_EXTENSION));
ASSERT_EQ(1U, messages.size());
EXPECT_EQ(l10n_util::GetStringFUTF16(
IDS_EXTENSION_PROMPT_WARNING_2_HOSTS,
base::ASCIIToUTF16("all xn--oogle-qmc.com sites"),
base::ASCIIToUTF16("xn--oogle-qmc.com")),
messages.front().message());
}
// Checks whether powerful permissions are returned correctly.
TEST_F(ChromePermissionMessageProviderUnittest, PowerfulPermissions) {
{
APIPermissionSet permissions;
permissions.insert(APIPermission::kTab);
PermissionMessages messages =
GetPowerfulMessages(permissions, Manifest::TYPE_EXTENSION);
ASSERT_EQ(1U, messages.size());
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
messages.front().message());
}
{
APIPermissionSet permissions;
permissions.insert(APIPermission::kBookmark);
PermissionMessages messages =
GetPowerfulMessages(permissions, Manifest::TYPE_EXTENSION);
ASSERT_EQ(0U, messages.size());
}
{
APIPermissionSet permissions;
permissions.insert(APIPermission::kTab);
permissions.insert(APIPermission::kBookmark);
PermissionMessages messages =
GetPowerfulMessages(permissions, Manifest::TYPE_EXTENSION);
ASSERT_EQ(1U, messages.size());
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
messages.front().message());
}
}
} // namespace extensions