| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "extensions/renderer/api_binding.h" | 5 #include "extensions/renderer/api_binding.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "extensions/common/extension_api.h" | 15 #include "extensions/common/extension_api.h" |
| 16 #include "extensions/renderer/api_binding_hooks.h" | 16 #include "extensions/renderer/api_binding_hooks.h" |
| 17 #include "extensions/renderer/api_binding_types.h" | 17 #include "extensions/renderer/api_binding_types.h" |
| 18 #include "extensions/renderer/api_event_handler.h" | 18 #include "extensions/renderer/api_event_handler.h" |
| 19 #include "extensions/renderer/api_invocation_errors.h" | 19 #include "extensions/renderer/api_invocation_errors.h" |
| 20 #include "extensions/renderer/api_request_handler.h" | 20 #include "extensions/renderer/api_request_handler.h" |
| 21 #include "extensions/renderer/api_signature.h" | 21 #include "extensions/renderer/api_signature.h" |
| 22 #include "extensions/renderer/api_type_reference_map.h" | 22 #include "extensions/renderer/api_type_reference_map.h" |
| 23 #include "extensions/renderer/binding_access_checker.h" |
| 23 #include "extensions/renderer/declarative_event.h" | 24 #include "extensions/renderer/declarative_event.h" |
| 24 #include "extensions/renderer/v8_helpers.h" | 25 #include "extensions/renderer/v8_helpers.h" |
| 25 #include "gin/arguments.h" | 26 #include "gin/arguments.h" |
| 26 #include "gin/handle.h" | 27 #include "gin/handle.h" |
| 27 #include "gin/per_context_data.h" | 28 #include "gin/per_context_data.h" |
| 28 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 29 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
| 29 | 30 |
| 30 namespace extensions { | 31 namespace extensions { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 | 173 |
| 173 CreateCustomType create_custom_type; | 174 CreateCustomType create_custom_type; |
| 174 }; | 175 }; |
| 175 | 176 |
| 176 APIBinding::APIBinding(const std::string& api_name, | 177 APIBinding::APIBinding(const std::string& api_name, |
| 177 const base::ListValue* function_definitions, | 178 const base::ListValue* function_definitions, |
| 178 const base::ListValue* type_definitions, | 179 const base::ListValue* type_definitions, |
| 179 const base::ListValue* event_definitions, | 180 const base::ListValue* event_definitions, |
| 180 const base::DictionaryValue* property_definitions, | 181 const base::DictionaryValue* property_definitions, |
| 181 const CreateCustomType& create_custom_type, | 182 const CreateCustomType& create_custom_type, |
| 182 const AvailabilityCallback& is_available, | |
| 183 std::unique_ptr<APIBindingHooks> binding_hooks, | 183 std::unique_ptr<APIBindingHooks> binding_hooks, |
| 184 APITypeReferenceMap* type_refs, | 184 APITypeReferenceMap* type_refs, |
| 185 APIRequestHandler* request_handler, | 185 APIRequestHandler* request_handler, |
| 186 APIEventHandler* event_handler) | 186 APIEventHandler* event_handler, |
| 187 BindingAccessChecker* access_checker) |
| 187 : api_name_(api_name), | 188 : api_name_(api_name), |
| 188 property_definitions_(property_definitions), | 189 property_definitions_(property_definitions), |
| 189 create_custom_type_(create_custom_type), | 190 create_custom_type_(create_custom_type), |
| 190 is_available_(is_available), | |
| 191 binding_hooks_(std::move(binding_hooks)), | 191 binding_hooks_(std::move(binding_hooks)), |
| 192 type_refs_(type_refs), | 192 type_refs_(type_refs), |
| 193 request_handler_(request_handler), | 193 request_handler_(request_handler), |
| 194 event_handler_(event_handler), | 194 event_handler_(event_handler), |
| 195 access_checker_(access_checker), |
| 195 weak_factory_(this) { | 196 weak_factory_(this) { |
| 196 // TODO(devlin): It might make sense to instantiate the object_template_ | 197 // TODO(devlin): It might make sense to instantiate the object_template_ |
| 197 // directly here, which would avoid the need to hold on to | 198 // directly here, which would avoid the need to hold on to |
| 198 // |property_definitions_| and |enums_|. However, there are *some* cases where | 199 // |property_definitions_| and |enums_|. However, there are *some* cases where |
| 199 // we don't immediately stamp out an API from the template following | 200 // we don't immediately stamp out an API from the template following |
| 200 // construction. | 201 // construction. |
| 201 | 202 |
| 202 if (function_definitions) { | 203 if (function_definitions) { |
| 203 for (const auto& func : *function_definitions) { | 204 for (const auto& func : *function_definitions) { |
| 204 const base::DictionaryValue* func_dict = nullptr; | 205 const base::DictionaryValue* func_dict = nullptr; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 v8::Local<v8::Object> object = | 339 v8::Local<v8::Object> object = |
| 339 object_template_.Get(isolate)->NewInstance(context).ToLocalChecked(); | 340 object_template_.Get(isolate)->NewInstance(context).ToLocalChecked(); |
| 340 | 341 |
| 341 // The object created from the template includes all methods, but some may | 342 // The object created from the template includes all methods, but some may |
| 342 // be unavailable in this context. Iterate over them and delete any that | 343 // be unavailable in this context. Iterate over them and delete any that |
| 343 // aren't available. | 344 // aren't available. |
| 344 // TODO(devlin): Ideally, we'd only do this check on the methods that are | 345 // TODO(devlin): Ideally, we'd only do this check on the methods that are |
| 345 // conditionally exposed. Or, we could have multiple templates for different | 346 // conditionally exposed. Or, we could have multiple templates for different |
| 346 // configurations, assuming there are a small number of possibilities. | 347 // configurations, assuming there are a small number of possibilities. |
| 347 for (const auto& key_value : methods_) { | 348 for (const auto& key_value : methods_) { |
| 348 if (!is_available_.Run(context, key_value.second->full_name)) { | 349 if (!access_checker_->HasAccess(context, key_value.second->full_name)) { |
| 349 v8::Maybe<bool> success = object->Delete( | 350 v8::Maybe<bool> success = object->Delete( |
| 350 context, gin::StringToSymbol(isolate, key_value.first)); | 351 context, gin::StringToSymbol(isolate, key_value.first)); |
| 351 CHECK(success.IsJust()); | 352 CHECK(success.IsJust()); |
| 352 CHECK(success.FromJust()); | 353 CHECK(success.FromJust()); |
| 353 } | 354 } |
| 354 } | 355 } |
| 355 for (const auto& event : events_) { | 356 for (const auto& event : events_) { |
| 356 if (!is_available_.Run(context, event->full_name)) { | 357 if (!access_checker_->HasAccess(context, event->full_name)) { |
| 357 v8::Maybe<bool> success = object->Delete( | 358 v8::Maybe<bool> success = object->Delete( |
| 358 context, gin::StringToSymbol(isolate, event->exposed_name)); | 359 context, gin::StringToSymbol(isolate, event->exposed_name)); |
| 359 CHECK(success.IsJust()); | 360 CHECK(success.IsJust()); |
| 360 CHECK(success.FromJust()); | 361 CHECK(success.FromJust()); |
| 361 } | 362 } |
| 362 } | 363 } |
| 363 | 364 |
| 364 return object; | 365 return object; |
| 365 } | 366 } |
| 366 | 367 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 const binding::RequestThread thread, | 536 const binding::RequestThread thread, |
| 536 gin::Arguments* arguments) { | 537 gin::Arguments* arguments) { |
| 537 std::string error; | 538 std::string error; |
| 538 v8::Isolate* isolate = arguments->isolate(); | 539 v8::Isolate* isolate = arguments->isolate(); |
| 539 v8::HandleScope handle_scope(isolate); | 540 v8::HandleScope handle_scope(isolate); |
| 540 | 541 |
| 541 // Since this is called synchronously from the JS entry point, | 542 // Since this is called synchronously from the JS entry point, |
| 542 // GetCurrentContext() should always be correct. | 543 // GetCurrentContext() should always be correct. |
| 543 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | 544 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| 544 | 545 |
| 545 if (!is_available_.Run(context, name)) { | 546 if (!access_checker_->HasAccessOrThrowError(context, name)) { |
| 546 // TODO(devlin): Do we need handle this for events as well? I'm not sure the | 547 // TODO(devlin): Do we need handle this for events as well? I'm not sure the |
| 547 // currrent system does (though perhaps it should). Investigate. | 548 // currrent system does (though perhaps it should). Investigate. |
| 548 isolate->ThrowException(v8::Exception::Error(gin::StringToV8( | |
| 549 isolate, base::StringPrintf("'%s' is not available in this context.", | |
| 550 name.c_str())))); | |
| 551 return; | 549 return; |
| 552 } | 550 } |
| 553 | 551 |
| 554 std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); | 552 std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); |
| 555 | 553 |
| 556 bool invalid_invocation = false; | 554 bool invalid_invocation = false; |
| 557 v8::Local<v8::Function> custom_callback; | 555 v8::Local<v8::Function> custom_callback; |
| 558 bool updated_args = false; | 556 bool updated_args = false; |
| 559 { | 557 { |
| 560 v8::TryCatch try_catch(isolate); | 558 v8::TryCatch try_catch(isolate); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 arguments->ThrowTypeError(api_errors::InvocationError( | 624 arguments->ThrowTypeError(api_errors::InvocationError( |
| 627 name, signature->GetExpectedSignature(), error)); | 625 name, signature->GetExpectedSignature(), error)); |
| 628 return; | 626 return; |
| 629 } | 627 } |
| 630 | 628 |
| 631 request_handler_->StartRequest(context, name, std::move(converted_arguments), | 629 request_handler_->StartRequest(context, name, std::move(converted_arguments), |
| 632 callback, custom_callback, thread); | 630 callback, custom_callback, thread); |
| 633 } | 631 } |
| 634 | 632 |
| 635 } // namespace extensions | 633 } // namespace extensions |
| OLD | NEW |