OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/extensions/public_session_permission_helper.h" | 5 #include "chrome/browser/chromeos/extensions/public_session_permission_helper.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
18 #include "chrome/browser/chromeos/extensions/device_local_account_management_pol icy_provider.h" | |
18 #include "chrome/browser/extensions/extension_install_prompt.h" | 19 #include "chrome/browser/extensions/extension_install_prompt.h" |
20 #include "chrome/browser/profiles/profiles_state.h" | |
21 #include "chrome/grit/generated_resources.h" | |
19 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/web_contents.h" | 23 #include "content/public/browser/web_contents.h" |
21 #include "extensions/common/extension.h" | 24 #include "extensions/common/extension.h" |
22 #include "extensions/common/extension_id.h" | 25 #include "extensions/common/extension_id.h" |
26 #include "extensions/common/permissions/api_permission_set.h" | |
23 #include "extensions/common/permissions/manifest_permission_set.h" | 27 #include "extensions/common/permissions/manifest_permission_set.h" |
28 #include "extensions/common/permissions/permission_message.h" | |
24 #include "extensions/common/permissions/permission_set.h" | 29 #include "extensions/common/permissions/permission_set.h" |
25 #include "extensions/common/url_pattern_set.h" | 30 #include "extensions/common/url_pattern_set.h" |
31 #include "ui/base/l10n/l10n_util.h" | |
26 | 32 |
27 namespace extensions { | 33 namespace extensions { |
28 namespace permission_helper { | 34 namespace permission_helper { |
29 | 35 |
30 namespace { | 36 namespace { |
31 | 37 |
32 std::unique_ptr<ExtensionInstallPrompt> CreateExtensionInstallPrompt( | 38 std::unique_ptr<ExtensionInstallPrompt> CreateExtensionInstallPrompt( |
33 content::WebContents* web_contents) { | 39 content::WebContents* web_contents) { |
34 return base::MakeUnique<ExtensionInstallPrompt>(web_contents); | 40 return base::MakeUnique<ExtensionInstallPrompt>(web_contents); |
35 } | 41 } |
36 | 42 |
43 bool PermissionCheckNeeded(const Extension* extension) { | |
44 return !chromeos::DeviceLocalAccountManagementPolicyProvider::IsWhitelisted( | |
45 extension->id()); | |
46 } | |
47 | |
37 // This class is the internal implementation of HandlePermissionRequest(). It | 48 // This class is the internal implementation of HandlePermissionRequest(). It |
38 // contains the actual prompt showing and resolving logic, and it caches the | 49 // contains the actual prompt showing and resolving logic, and it caches the |
39 // user choices. | 50 // user choices. |
40 class PublicSessionPermissionHelper { | 51 class PublicSessionPermissionHelper { |
41 public: | 52 public: |
42 PublicSessionPermissionHelper(); | 53 PublicSessionPermissionHelper(); |
43 PublicSessionPermissionHelper(PublicSessionPermissionHelper&& other); | 54 PublicSessionPermissionHelper(PublicSessionPermissionHelper&& other); |
44 ~PublicSessionPermissionHelper(); | 55 ~PublicSessionPermissionHelper(); |
45 | 56 |
46 void HandlePermissionRequestImpl(const Extension& extension, | 57 bool HandlePermissionRequestImpl(const Extension& extension, |
47 const PermissionIDSet& requested_permissions, | 58 const PermissionIDSet& requested_permissions, |
48 content::WebContents* web_contents, | 59 content::WebContents* web_contents, |
49 const RequestResolvedCallback& callback, | 60 const RequestResolvedCallback& callback, |
50 const PromptFactory& prompt_factory); | 61 const PromptFactory& prompt_factory); |
51 | 62 |
63 bool PermissionAllowedImpl(const Extension* extension, | |
64 APIPermission::ID permission); | |
65 | |
52 private: | 66 private: |
53 void ResolvePermissionPrompt(const ExtensionInstallPrompt* prompt, | 67 void ResolvePermissionPrompt(const ExtensionInstallPrompt* prompt, |
54 const PermissionIDSet& unprompted_permissions, | 68 const PermissionIDSet& unprompted_permissions, |
55 ExtensionInstallPrompt::Result prompt_result); | 69 ExtensionInstallPrompt::Result prompt_result); |
56 | 70 |
57 PermissionIDSet FilterAllowedPermissions(const PermissionIDSet& permissions); | 71 PermissionIDSet FilterAllowedPermissions(const PermissionIDSet& permissions); |
58 | 72 |
59 struct RequestCallback { | 73 struct RequestCallback { |
60 RequestCallback(const RequestResolvedCallback& callback, | 74 RequestCallback(const RequestResolvedCallback& callback, |
61 const PermissionIDSet& permission_list); | 75 const PermissionIDSet& permission_list); |
(...skipping 13 matching lines...) Expand all Loading... | |
75 DISALLOW_COPY_AND_ASSIGN(PublicSessionPermissionHelper); | 89 DISALLOW_COPY_AND_ASSIGN(PublicSessionPermissionHelper); |
76 }; | 90 }; |
77 | 91 |
78 PublicSessionPermissionHelper::PublicSessionPermissionHelper() {} | 92 PublicSessionPermissionHelper::PublicSessionPermissionHelper() {} |
79 | 93 |
80 PublicSessionPermissionHelper::PublicSessionPermissionHelper( | 94 PublicSessionPermissionHelper::PublicSessionPermissionHelper( |
81 PublicSessionPermissionHelper&& other) = default; | 95 PublicSessionPermissionHelper&& other) = default; |
82 | 96 |
83 PublicSessionPermissionHelper::~PublicSessionPermissionHelper() {} | 97 PublicSessionPermissionHelper::~PublicSessionPermissionHelper() {} |
84 | 98 |
85 void PublicSessionPermissionHelper::HandlePermissionRequestImpl( | 99 bool PublicSessionPermissionHelper::HandlePermissionRequestImpl( |
86 const Extension& extension, | 100 const Extension& extension, |
87 const PermissionIDSet& requested_permissions, | 101 const PermissionIDSet& requested_permissions, |
88 content::WebContents* web_contents, | 102 content::WebContents* web_contents, |
89 const RequestResolvedCallback& callback, | 103 const RequestResolvedCallback& callback, |
90 const PromptFactory& prompt_factory) { | 104 const PromptFactory& prompt_factory) { |
91 CHECK(web_contents); | 105 DCHECK(profiles::IsPublicSession()); |
106 if (!PermissionCheckNeeded(&extension)) { | |
107 if (!callback.is_null()) | |
108 callback.Run(requested_permissions); | |
109 return true; | |
110 } | |
92 | 111 |
93 PermissionIDSet unresolved_permissions = PermissionIDSet::Difference( | 112 PermissionIDSet unresolved_permissions = PermissionIDSet::Difference( |
94 requested_permissions, allowed_permission_set_); | 113 requested_permissions, allowed_permission_set_); |
95 unresolved_permissions = PermissionIDSet::Difference( | 114 unresolved_permissions = PermissionIDSet::Difference( |
96 unresolved_permissions, denied_permission_set_); | 115 unresolved_permissions, denied_permission_set_); |
97 if (unresolved_permissions.empty()) { | 116 if (unresolved_permissions.empty()) { |
98 // All requested permissions are already resolved. | 117 // All requested permissions are already resolved. |
99 callback.Run(FilterAllowedPermissions(requested_permissions)); | 118 if (!callback.is_null()) |
100 return; | 119 callback.Run(FilterAllowedPermissions(requested_permissions)); |
120 return true; | |
101 } | 121 } |
102 | 122 |
103 // Since not all permissions are resolved yet, queue the callback to be called | 123 // Since not all permissions are resolved yet, queue the callback to be called |
104 // when all of them are resolved. | 124 // when all of them are resolved. |
105 callbacks_.push_back(RequestCallback(callback, requested_permissions)); | 125 if (!callback.is_null()) |
126 callbacks_.push_back(RequestCallback(callback, requested_permissions)); | |
106 | 127 |
107 PermissionIDSet unprompted_permissions = PermissionIDSet::Difference( | 128 PermissionIDSet unprompted_permissions = PermissionIDSet::Difference( |
108 unresolved_permissions, prompted_permission_set_); | 129 unresolved_permissions, prompted_permission_set_); |
109 if (unprompted_permissions.empty()) { | 130 if (unprompted_permissions.empty()) { |
110 // Some permissions aren't resolved yet, but they are currently being | 131 // Some permissions aren't resolved yet, but they are currently being |
111 // prompted for, so no need to show a prompt. | 132 // prompted for, so no need to show a prompt. |
112 return; | 133 return false; |
113 } | 134 } |
114 | 135 |
115 // Some permissions need prompting, setup the prompt and show it. | 136 // Some permissions need prompting, setup the prompt and show it. |
116 APIPermissionSet new_apis; | 137 APIPermissionSet new_apis; |
117 for (const auto& permission : unprompted_permissions) { | 138 for (const auto& permission : unprompted_permissions) { |
118 prompted_permission_set_.insert(permission.id()); | 139 prompted_permission_set_.insert(permission.id()); |
119 new_apis.insert(permission.id()); | 140 new_apis.insert(permission.id()); |
120 } | 141 } |
121 auto permission_set = base::MakeUnique<PermissionSet>( | 142 auto permission_set = base::MakeUnique<PermissionSet>( |
122 new_apis, ManifestPermissionSet(), URLPatternSet(), URLPatternSet()); | 143 new_apis, ManifestPermissionSet(), URLPatternSet(), URLPatternSet()); |
123 auto prompt = prompt_factory.Run(web_contents); | 144 auto prompt = prompt_factory.Run(web_contents); |
145 | |
146 auto permissions_prompt = base::MakeUnique<ExtensionInstallPrompt::Prompt>( | |
147 ExtensionInstallPrompt::PERMISSIONS_PROMPT); | |
148 // activeTab has no permission message by default, so one is added here. | |
149 if (unprompted_permissions.ContainsID(APIPermission::kActiveTab)) { | |
150 PermissionMessages messages; | |
151 messages.push_back(PermissionMessage( | |
152 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_CURRENT_HOST), | |
153 extensions::PermissionIDSet())); | |
154 permissions_prompt->SetPermissions( | |
155 messages, ExtensionInstallPrompt::REGULAR_PERMISSIONS); | |
156 } | |
157 | |
124 // This Unretained is safe because the lifetime of this object is until | 158 // This Unretained is safe because the lifetime of this object is until |
125 // process exit. | 159 // process exit. |
126 prompt->ShowDialog( | 160 prompt->ShowDialog( |
127 base::Bind(&PublicSessionPermissionHelper::ResolvePermissionPrompt, | 161 base::Bind(&PublicSessionPermissionHelper::ResolvePermissionPrompt, |
128 base::Unretained(this), prompt.get(), | 162 base::Unretained(this), prompt.get(), |
129 std::move(unprompted_permissions)), | 163 std::move(unprompted_permissions)), |
130 &extension, | 164 &extension, |
131 nullptr, // Use the extension icon. | 165 nullptr, // Use the extension icon. |
132 base::MakeUnique<ExtensionInstallPrompt::Prompt>( | 166 std::move(permissions_prompt), |
133 ExtensionInstallPrompt::PERMISSIONS_PROMPT), | |
134 std::move(permission_set), | 167 std::move(permission_set), |
135 ExtensionInstallPrompt::GetDefaultShowDialogCallback()); | 168 ExtensionInstallPrompt::GetDefaultShowDialogCallback()); |
136 prompts_.insert(std::move(prompt)); | 169 prompts_.insert(std::move(prompt)); |
170 | |
171 return false; | |
172 } | |
173 | |
174 bool PublicSessionPermissionHelper::PermissionAllowedImpl( | |
175 const Extension* extension, | |
176 APIPermission::ID permission) { | |
177 DCHECK(profiles::IsPublicSession()); | |
178 if (!PermissionCheckNeeded(extension)) | |
Devlin
2017/05/23 19:28:03
return !PermissionCheckNeeded(extension) || allowe
Ivan Šandrk
2017/05/24 09:29:01
Done.
| |
179 return true; | |
180 return allowed_permission_set_.ContainsID(permission); | |
137 } | 181 } |
138 | 182 |
139 void PublicSessionPermissionHelper::ResolvePermissionPrompt( | 183 void PublicSessionPermissionHelper::ResolvePermissionPrompt( |
140 const ExtensionInstallPrompt* prompt, | 184 const ExtensionInstallPrompt* prompt, |
141 const PermissionIDSet& unprompted_permissions, | 185 const PermissionIDSet& unprompted_permissions, |
142 ExtensionInstallPrompt::Result prompt_result) { | 186 ExtensionInstallPrompt::Result prompt_result) { |
143 PermissionIDSet& add_to_set = | 187 PermissionIDSet& add_to_set = |
144 prompt_result == ExtensionInstallPrompt::Result::ACCEPTED ? | 188 prompt_result == ExtensionInstallPrompt::Result::ACCEPTED ? |
145 allowed_permission_set_ : denied_permission_set_; | 189 allowed_permission_set_ : denied_permission_set_; |
146 for (const auto& permission : unprompted_permissions) { | 190 for (const auto& permission : unprompted_permissions) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 PublicSessionPermissionHelper::RequestCallback::RequestCallback( | 240 PublicSessionPermissionHelper::RequestCallback::RequestCallback( |
197 const RequestCallback& other) = default; | 241 const RequestCallback& other) = default; |
198 | 242 |
199 PublicSessionPermissionHelper::RequestCallback::~RequestCallback() {} | 243 PublicSessionPermissionHelper::RequestCallback::~RequestCallback() {} |
200 | 244 |
201 base::LazyInstance<std::map<ExtensionId, PublicSessionPermissionHelper>>::Leaky | 245 base::LazyInstance<std::map<ExtensionId, PublicSessionPermissionHelper>>::Leaky |
202 g_helpers = LAZY_INSTANCE_INITIALIZER; | 246 g_helpers = LAZY_INSTANCE_INITIALIZER; |
203 | 247 |
204 } // namespace | 248 } // namespace |
205 | 249 |
206 void HandlePermissionRequest(const Extension& extension, | 250 bool HandlePermissionRequest(const Extension& extension, |
207 const PermissionIDSet& requested_permissions, | 251 const PermissionIDSet& requested_permissions, |
208 content::WebContents* web_contents, | 252 content::WebContents* web_contents, |
209 const RequestResolvedCallback& callback, | 253 const RequestResolvedCallback& callback, |
210 const PromptFactory& prompt_factory) { | 254 const PromptFactory& prompt_factory) { |
211 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 255 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
212 const PromptFactory& factory = prompt_factory.is_null() | 256 const PromptFactory& factory = prompt_factory.is_null() |
213 ? base::Bind(&CreateExtensionInstallPrompt) | 257 ? base::Bind(&CreateExtensionInstallPrompt) |
214 : prompt_factory; | 258 : prompt_factory; |
215 return g_helpers.Get()[extension.id()].HandlePermissionRequestImpl( | 259 return g_helpers.Get()[extension.id()].HandlePermissionRequestImpl( |
216 extension, requested_permissions, web_contents, callback, factory); | 260 extension, requested_permissions, web_contents, callback, factory); |
217 } | 261 } |
218 | 262 |
263 bool PermissionAllowed(const Extension* extension, | |
264 APIPermission::ID permission) { | |
265 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
266 return g_helpers.Get()[extension->id()].PermissionAllowedImpl(extension, | |
267 permission); | |
268 } | |
269 | |
219 void ResetPermissionsForTesting() { | 270 void ResetPermissionsForTesting() { |
220 // Clear out the std::map between tests. Just setting g_helpers to | 271 // Clear out the std::map between tests. Just setting g_helpers to |
221 // LAZY_INSTANCE_INITIALIZER again causes a memory leak (because of the | 272 // LAZY_INSTANCE_INITIALIZER again causes a memory leak (because of the |
222 // LazyInstance::Leaky). | 273 // LazyInstance::Leaky). |
223 g_helpers.Get().clear(); | 274 g_helpers.Get().clear(); |
224 } | 275 } |
225 | 276 |
226 } // namespace permission_helper | 277 } // namespace permission_helper |
227 } // namespace extensions | 278 } // namespace extensions |
OLD | NEW |