1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// Copyright (c) 2012 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/browser/extensions/active_tab_permission_granter.h"
#include "chrome/browser/extensions/active_script_controller.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/user_script.h"
#include "url/gurl.h"
using content::RenderProcessHost;
using content::WebContentsObserver;
namespace extensions {
ActiveTabPermissionGranter::ActiveTabPermissionGranter(
content::WebContents* web_contents,
int tab_id,
Profile* profile)
: WebContentsObserver(web_contents),
tab_id_(tab_id),
extension_registry_observer_(this) {
extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
}
ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {}
void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) {
// Active tab grant request implies there was a user gesture.
web_contents()->UserGestureDone();
if (granted_extensions_.Contains(extension->id()))
return;
APIPermissionSet new_apis;
URLPatternSet new_hosts;
const PermissionsData* permissions_data = extension->permissions_data();
// If the extension requires action for script execution, we grant it
// active tab-style permissions, even if it doesn't have the activeTab
// permission in the manifest.
// We don't take tab id into account, because we want to know if the extension
// should require active tab in general (not for the current tab).
bool requires_action_for_script_execution =
permissions_data->RequiresActionForScriptExecution(extension,
-1, // No tab id.
GURL());
if (extension->permissions_data()->HasAPIPermission(
APIPermission::kActiveTab) ||
requires_action_for_script_execution) {
URLPattern pattern(UserScript::ValidUserScriptSchemes());
// Pattern parsing could fail if this is an unsupported URL e.g. chrome://.
if (pattern.Parse(web_contents()->GetURL().spec()) ==
URLPattern::PARSE_SUCCESS) {
new_hosts.AddPattern(pattern);
}
new_apis.insert(APIPermission::kTab);
}
if (extension->permissions_data()->HasAPIPermission(
APIPermission::kTabCapture))
new_apis.insert(APIPermission::kTabCaptureForTab);
if (!new_apis.empty() || !new_hosts.is_empty()) {
granted_extensions_.Insert(extension);
scoped_refptr<const PermissionSet> new_permissions =
new PermissionSet(new_apis, ManifestPermissionSet(),
new_hosts, URLPatternSet());
permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions);
const content::NavigationEntry* navigation_entry =
web_contents()->GetController().GetVisibleEntry();
if (navigation_entry) {
Send(new ExtensionMsg_UpdateTabSpecificPermissions(
navigation_entry->GetPageID(),
tab_id_,
extension->id(),
new_hosts));
// If more things ever need to know about this, we should consider making
// an observer class.
// It's important that this comes after the IPC is sent to the renderer,
// so that any tasks executing in the renderer occur after it has the
// updated permissions.
ActiveScriptController::GetForWebContents(web_contents())
->OnActiveTabPermissionGranted(extension);
}
}
}
void ActiveTabPermissionGranter::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
if (details.is_in_page)
return;
DCHECK(details.is_main_frame); // important: sub-frames don't get granted!
ClearActiveExtensionsAndNotify();
}
void ActiveTabPermissionGranter::WebContentsDestroyed() {
ClearActiveExtensionsAndNotify();
}
void ActiveTabPermissionGranter::OnExtensionUnloaded(
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {
// Note: don't need to clear the permissions (nor tell the renderer about it)
// because it's being unloaded anyway.
granted_extensions_.Remove(extension->id());
}
void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() {
if (granted_extensions_.is_empty())
return;
std::vector<std::string> extension_ids;
for (ExtensionSet::const_iterator it = granted_extensions_.begin();
it != granted_extensions_.end(); ++it) {
it->get()->permissions_data()->ClearTabSpecificPermissions(tab_id_);
extension_ids.push_back((*it)->id());
}
Send(new ExtensionMsg_ClearTabSpecificPermissions(tab_id_, extension_ids));
granted_extensions_.Clear();
}
} // namespace extensions
|