api_signature.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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
  3. // found in the LICENSE file.
  4. #ifndef EXTENSIONS_RENDERER_BINDINGS_API_SIGNATURE_H_
  5. #define EXTENSIONS_RENDERER_BINDINGS_API_SIGNATURE_H_
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. #include "extensions/renderer/bindings/api_binding_types.h"
  10. #include "extensions/renderer/bindings/binding_access_checker.h"
  11. #include "third_party/abseil-cpp/absl/types/optional.h"
  12. #include "v8/include/v8.h"
  13. namespace base {
  14. class Value;
  15. }
  16. namespace extensions {
  17. class APITypeReferenceMap;
  18. class ArgumentSpec;
  19. class BindingAccessChecker;
  20. // Whether promises are allowed to be used for a given call to an API.
  21. enum class PromisesAllowed {
  22. kAllowed,
  23. kDisallowed,
  24. };
  25. // A representation of the expected signature for an API, along with the
  26. // ability to match provided arguments and convert them to base::Values.
  27. // This is primarily used for API methods, but can also be used for API event
  28. // signatures.
  29. class APISignature {
  30. public:
  31. // Struct that bundles all the details about an asynchronous return.
  32. struct ReturnsAsync {
  33. ReturnsAsync();
  34. ~ReturnsAsync();
  35. // The list of expected arguments for the asynchronous return. Can be
  36. // nullopt if response validation isn't enabled, as it is only used when
  37. // validating a response from the API.
  38. absl::optional<std::vector<std::unique_ptr<ArgumentSpec>>> signature;
  39. // Indicates if passing the callback when calling the API is optional for
  40. // contexts or APIs which do not support promises (passing the callback is
  41. // always inheriently optional if promises are supported).
  42. bool optional = false;
  43. // Indicates if this API supports allowing promises for the asynchronous
  44. // return. Note that this is distinct from whether an actual call to the API
  45. // is allowed to use the promise based form, as that also depends on if the
  46. // calling context being checked by the access_checker.
  47. binding::APIPromiseSupport promise_support =
  48. binding::APIPromiseSupport::kUnsupported;
  49. };
  50. APISignature(std::vector<std::unique_ptr<ArgumentSpec>> signature,
  51. std::unique_ptr<APISignature::ReturnsAsync> returns_async,
  52. BindingAccessChecker* access_checker);
  53. APISignature(const APISignature&) = delete;
  54. APISignature& operator=(const APISignature&) = delete;
  55. ~APISignature();
  56. // Creates an APISignature object from the raw Value representations of an
  57. // API schema.
  58. static std::unique_ptr<APISignature> CreateFromValues(
  59. const base::Value& specification_list,
  60. const base::Value* returns_async,
  61. BindingAccessChecker* access_checker,
  62. const std::string& api_name,
  63. bool is_event_signature);
  64. struct V8ParseResult {
  65. // Appease the Chromium style plugin (out of line ctor/dtor).
  66. V8ParseResult();
  67. ~V8ParseResult();
  68. V8ParseResult(V8ParseResult&& other);
  69. V8ParseResult& operator=(V8ParseResult&& other);
  70. bool succeeded() const { return arguments.has_value(); }
  71. // The parsed v8 arguments. These may differ from the original v8 arguments
  72. // since it will include null-filled optional arguments. Populated if
  73. // parsing was successful. Note that the callback, if any, is included in
  74. // this list.
  75. absl::optional<std::vector<v8::Local<v8::Value>>> arguments;
  76. // Whether the asynchronous response is handled by a callback or a promise.
  77. binding::AsyncResponseType async_type = binding::AsyncResponseType::kNone;
  78. // The parse error, if parsing failed.
  79. absl::optional<std::string> error;
  80. };
  81. struct JSONParseResult {
  82. // Appease the Chromium style plugin (out of line ctor/dtor).
  83. JSONParseResult();
  84. ~JSONParseResult();
  85. JSONParseResult(JSONParseResult&& other);
  86. JSONParseResult& operator=(JSONParseResult&& other);
  87. bool succeeded() const { return !!arguments_list; }
  88. // The parsed JSON arguments, with null-filled optional arguments filled in.
  89. // Populated if parsing was successful. Does not include the callback (if
  90. // any).
  91. std::unique_ptr<base::Value> arguments_list;
  92. // The callback, if one was provided.
  93. v8::Local<v8::Function> callback;
  94. // Whether the asynchronous response is handled by a callback or a promise.
  95. binding::AsyncResponseType async_type = binding::AsyncResponseType::kNone;
  96. // The parse error, if parsing failed.
  97. absl::optional<std::string> error;
  98. };
  99. // Parses |arguments| against this signature, returning the result and
  100. // performing no argument conversion.
  101. V8ParseResult ParseArgumentsToV8(
  102. v8::Local<v8::Context> context,
  103. const std::vector<v8::Local<v8::Value>>& arguments,
  104. const APITypeReferenceMap& type_refs) const;
  105. // Parses |arguments| against this signature, returning the result after
  106. // converting to base::Values.
  107. JSONParseResult ParseArgumentsToJSON(
  108. v8::Local<v8::Context> context,
  109. const std::vector<v8::Local<v8::Value>>& arguments,
  110. const APITypeReferenceMap& type_refs) const;
  111. // Converts |arguments| to base::Values, ignoring the defined signature.
  112. // This is used when custom bindings modify the passed arguments to a form
  113. // that doesn't match the documented signature. Since we ignore the schema,
  114. // this parsing will never fail.
  115. JSONParseResult ConvertArgumentsIgnoringSchema(
  116. v8::Local<v8::Context> context,
  117. const std::vector<v8::Local<v8::Value>>& arguments) const;
  118. // Validates the provided |arguments| as if they were returned as a response
  119. // to an API call. This validation is much stricter than the versions above,
  120. // since response arguments are not allowed to have optional inner parameters.
  121. bool ValidateResponse(v8::Local<v8::Context> context,
  122. const std::vector<v8::Local<v8::Value>>& arguments,
  123. const APITypeReferenceMap& type_refs,
  124. std::string* error) const;
  125. // Same as `ValidateResponse`, but verifies the given `arguments` against the
  126. // `signature_` instead of the `returns_async_` types. This can be used when
  127. // validating that APIs return proper values to an event (which has a
  128. // signature, but no return).
  129. bool ValidateCall(v8::Local<v8::Context> context,
  130. const std::vector<v8::Local<v8::Value>>& arguments,
  131. const APITypeReferenceMap& type_refs,
  132. std::string* error) const;
  133. // Returns a developer-readable string of the expected signature. For
  134. // instance, if this signature expects a string 'someStr' and an optional int
  135. // 'someInt', this would return "string someStr, optional integer someInt".
  136. std::string GetExpectedSignature() const;
  137. bool has_async_return() const { return returns_async_ != nullptr; }
  138. bool has_async_return_signature() const {
  139. return has_async_return() && returns_async_->signature.has_value();
  140. }
  141. private:
  142. // Checks if promises are allowed to be used for a call to an API from a given
  143. // |context|.
  144. PromisesAllowed CheckPromisesAllowed(v8::Local<v8::Context> context) const;
  145. // The list of expected arguments for the API signature.
  146. std::vector<std::unique_ptr<ArgumentSpec>> signature_;
  147. // The details of any asynchronous return an API method may have. This will be
  148. // nullptr if the the API doesn't have an asynchronous return.
  149. std::unique_ptr<APISignature::ReturnsAsync> returns_async_;
  150. // The associated access checker; required to outlive this object.
  151. const BindingAccessChecker* access_checker_;
  152. // A developer-readable method signature string, lazily set.
  153. mutable std::string expected_signature_;
  154. };
  155. } // namespace extensions
  156. #endif // EXTENSIONS_RENDERER_BINDINGS_API_SIGNATURE_H_