1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// found in the LICENSE file.
4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/command_line.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/common/url_constants.h"
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "extensions/common/constants.h"
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "extensions/common/error_utils.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/extensions_client.h"
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/manifest_handlers/permissions_parser.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "extensions/common/permissions/permission_message_provider.h"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "extensions/common/switches.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "extensions/common/url_pattern_set.h"
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "extensions/common/user_script.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "url/url_constants.h"
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace extensions {
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace {
25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PermissionsData::PolicyDelegate* g_policy_delegate = NULL;
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)PermissionsData::PermissionsData(const Extension* extension)
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : extension_id_(extension->id()), manifest_type_(extension->GetType()) {
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::AutoLock auto_lock(runtime_lock_);
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<const PermissionSet> required_permissions =
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      PermissionsParser::GetRequiredPermissions(extension);
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  active_permissions_unsafe_ =
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new PermissionSet(required_permissions->apis(),
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        required_permissions->manifest_permissions(),
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        required_permissions->explicit_hosts(),
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        required_permissions->scriptable_hosts());
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  withheld_permissions_unsafe_ = new PermissionSet();
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)PermissionsData::~PermissionsData() {
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// static
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PermissionsData::SetPolicyDelegate(PolicyDelegate* delegate) {
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  g_policy_delegate = delegate;
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::CanSilentlyIncreasePermissions(
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const Extension* extension) {
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return extension->location() != Manifest::INTERNAL;
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::CanExecuteScriptEverywhere(const Extension* extension) {
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (extension->location() == Manifest::COMPONENT)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return true;
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const ExtensionsClient::ScriptingWhitelist& whitelist =
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ExtensionsClient::Get()->GetScriptingWhitelist();
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return std::find(whitelist.begin(), whitelist.end(), extension->id()) !=
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)         whitelist.end();
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool PermissionsData::ShouldSkipPermissionWarnings(
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& extension_id) {
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // See http://b/4946060 for more details.
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return extension_id == std::string("nckgahadagoaajjgafhacjanaoiihapd");
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PermissionsData::IsRestrictedUrl(const GURL& document_url,
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      const GURL& top_frame_url,
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      const Extension* extension,
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      std::string* error) {
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension && CanExecuteScriptEverywhere(extension))
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Check if the scheme is valid for extensions. If not, return.
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!URLPattern::IsValidSchemeForExtensions(document_url.scheme()) &&
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      document_url.spec() != url::kAboutBlankURL) {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (error) {
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *error = ErrorUtils::FormatErrorMessage(
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   manifest_errors::kCannotAccessPage,
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   document_url.spec());
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!ExtensionsClient::Get()->IsScriptableURL(document_url, error))
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool allow_on_chrome_urls = base::CommandLine::ForCurrentProcess()->HasSwitch(
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  switches::kExtensionsOnChromeURLs);
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (document_url.SchemeIs(content::kChromeUIScheme) &&
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      !allow_on_chrome_urls) {
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (error)
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *error = manifest_errors::kCannotAccessChromeUrl;
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension && top_frame_url.SchemeIs(kExtensionScheme) &&
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      top_frame_url.host() != extension->id() && !allow_on_chrome_urls) {
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (error)
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *error = manifest_errors::kCannotAccessExtensionUrl;
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return false;
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionsData::SetPermissions(
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const scoped_refptr<const PermissionSet>& active,
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const scoped_refptr<const PermissionSet>& withheld) const {
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::AutoLock auto_lock(runtime_lock_);
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  active_permissions_unsafe_ = active;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  withheld_permissions_unsafe_ = withheld;
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PermissionsData::UpdateTabSpecificPermissions(
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int tab_id,
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_refptr<const PermissionSet> permissions) const {
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::AutoLock auto_lock(runtime_lock_);
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CHECK_GE(tab_id, 0);
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id);
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (iter == tab_specific_permissions_.end())
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    tab_specific_permissions_[tab_id] = permissions;
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  else
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    iter->second =
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        PermissionSet::CreateUnion(iter->second.get(), permissions.get());
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void PermissionsData::ClearTabSpecificPermissions(int tab_id) const {
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::AutoLock auto_lock(runtime_lock_);
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CHECK_GE(tab_id, 0);
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  tab_specific_permissions_.erase(tab_id);
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::HasAPIPermission(APIPermission::ID permission) const {
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return active_permissions()->HasAPIPermission(permission);
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool PermissionsData::HasAPIPermission(
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& permission_name) const {
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return active_permissions()->HasAPIPermission(permission_name);
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool PermissionsData::HasAPIPermissionForTab(
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int tab_id,
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    APIPermission::ID permission) const {
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (HasAPIPermission(permission))
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const PermissionSet> tab_permissions =
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      GetTabSpecificPermissions(tab_id);
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Place autolock below the HasAPIPermission() and
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GetTabSpecificPermissions(), since each already acquires the lock.
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::AutoLock auto_lock(runtime_lock_);
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return tab_permissions.get() && tab_permissions->HasAPIPermission(permission);
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool PermissionsData::CheckAPIPermissionWithParam(
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    APIPermission::ID permission,
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const APIPermission::CheckParam* param) const {
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return active_permissions()->CheckAPIPermissionWithParam(permission, param);
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const URLPatternSet& PermissionsData::GetEffectiveHostPermissions() const {
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return active_permissions()->effective_hosts();
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::HasHostPermission(const GURL& url) const {
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return active_permissions()->HasExplicitAccessToOrigin(url);
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::HasEffectiveAccessToAllHosts() const {
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return active_permissions()->HasEffectiveAccessToAllHosts();
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)PermissionMessages PermissionsData::GetPermissionMessages() const {
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (ShouldSkipPermissionWarnings(extension_id_)) {
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return PermissionMessages();
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return PermissionMessageProvider::Get()->GetPermissionMessages(
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        active_permissions().get(), manifest_type_);
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::vector<base::string16> PermissionsData::GetPermissionMessageStrings()
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const {
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (ShouldSkipPermissionWarnings(extension_id_))
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::vector<base::string16>();
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return PermissionMessageProvider::Get()->GetWarningMessages(
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      active_permissions().get(), manifest_type_);
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::vector<base::string16>
20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)PermissionsData::GetPermissionMessageDetailsStrings() const {
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (ShouldSkipPermissionWarnings(extension_id_))
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::vector<base::string16>();
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return PermissionMessageProvider::Get()->GetWarningMessagesDetails(
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      active_permissions().get(), manifest_type_);
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PermissionsData::HasWithheldImpliedAllHosts() const {
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Since we currently only withhold all_hosts, it's sufficient to check
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // that either set is not empty.
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return !withheld_permissions()->explicit_hosts().is_empty() ||
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         !withheld_permissions()->scriptable_hosts().is_empty();
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::CanAccessPage(const Extension* extension,
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    const GURL& document_url,
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    const GURL& top_frame_url,
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    int tab_id,
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    int process_id,
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    std::string* error) const {
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AccessType result = CanRunOnPage(extension,
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   document_url,
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   top_frame_url,
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   tab_id,
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   process_id,
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   active_permissions()->explicit_hosts(),
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   withheld_permissions()->explicit_hosts(),
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   error);
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED.
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD;
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
235116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPermissionsData::AccessType PermissionsData::GetPageAccess(
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const Extension* extension,
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& document_url,
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& top_frame_url,
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int tab_id,
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int process_id,
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string* error) const {
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return CanRunOnPage(extension,
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      document_url,
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      top_frame_url,
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      tab_id,
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      process_id,
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      active_permissions()->explicit_hosts(),
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      withheld_permissions()->explicit_hosts(),
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      error);
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension,
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                const GURL& document_url,
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                const GURL& top_frame_url,
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                int tab_id,
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                int process_id,
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                std::string* error) const {
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AccessType result = CanRunOnPage(extension,
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   document_url,
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   top_frame_url,
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   tab_id,
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   process_id,
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   active_permissions()->scriptable_hosts(),
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   withheld_permissions()->scriptable_hosts(),
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   error);
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED.
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD;
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
270116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPermissionsData::AccessType PermissionsData::GetContentScriptAccess(
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const Extension* extension,
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& document_url,
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& top_frame_url,
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int tab_id,
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int process_id,
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string* error) const {
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return CanRunOnPage(extension,
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      document_url,
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      top_frame_url,
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      tab_id,
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      process_id,
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      active_permissions()->scriptable_hosts(),
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      withheld_permissions()->scriptable_hosts(),
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      error);
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::CanCaptureVisiblePage(int tab_id,
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                            std::string* error) const {
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const URLPattern all_urls(URLPattern::SCHEME_ALL,
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            URLPattern::kAllUrlsPattern);
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (active_permissions()->explicit_hosts().ContainsPattern(all_urls))
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (tab_id >= 0) {
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_refptr<const PermissionSet> tab_permissions =
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GetTabSpecificPermissions(tab_id);
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (tab_permissions.get() &&
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        tab_permissions->HasAPIPermission(APIPermission::kTab)) {
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return true;
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (error)
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      *error = manifest_errors::kActiveTabPermissionNotGranted;
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error)
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    *error = manifest_errors::kAllURLOrActiveTabNeeded;
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return false;
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions(
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int tab_id) const {
31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::AutoLock auto_lock(runtime_lock_);
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CHECK_GE(tab_id, 0);
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TabPermissionsMap::const_iterator iter =
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      tab_specific_permissions_.find(tab_id);
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return (iter != tab_specific_permissions_.end()) ? iter->second : NULL;
31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool PermissionsData::HasTabSpecificPermissionToExecuteScript(
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int tab_id,
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GURL& url) const {
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (tab_id >= 0) {
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_refptr<const PermissionSet> tab_permissions =
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GetTabSpecificPermissions(tab_id);
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (tab_permissions.get() &&
32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) {
32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return true;
33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return false;
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
335116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPermissionsData::AccessType PermissionsData::CanRunOnPage(
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const Extension* extension,
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& document_url,
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& top_frame_url,
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int tab_id,
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int process_id,
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const URLPatternSet& permitted_url_patterns,
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const URLPatternSet& withheld_url_patterns,
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string* error) const {
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (g_policy_delegate &&
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      !g_policy_delegate->CanExecuteScriptOnPage(
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          extension, document_url, top_frame_url, tab_id, process_id, error)) {
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return ACCESS_DENIED;
348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (IsRestrictedUrl(document_url, top_frame_url, extension, error))
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return ACCESS_DENIED;
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (HasTabSpecificPermissionToExecuteScript(tab_id, top_frame_url))
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return ACCESS_ALLOWED;
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (permitted_url_patterns.MatchesURL(document_url))
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return ACCESS_ALLOWED;
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (withheld_url_patterns.MatchesURL(document_url))
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return ACCESS_WITHHELD;
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (error) {
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    *error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage,
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                            document_url.spec());
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ACCESS_DENIED;
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace extensions
370