123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- // Copyright 2016 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.
- #ifndef EXTENSIONS_RENDERER_BINDINGS_API_SIGNATURE_H_
- #define EXTENSIONS_RENDERER_BINDINGS_API_SIGNATURE_H_
- #include <memory>
- #include <string>
- #include <vector>
- #include "extensions/renderer/bindings/api_binding_types.h"
- #include "extensions/renderer/bindings/binding_access_checker.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "v8/include/v8.h"
- namespace base {
- class Value;
- }
- namespace extensions {
- class APITypeReferenceMap;
- class ArgumentSpec;
- class BindingAccessChecker;
- // Whether promises are allowed to be used for a given call to an API.
- enum class PromisesAllowed {
- kAllowed,
- kDisallowed,
- };
- // A representation of the expected signature for an API, along with the
- // ability to match provided arguments and convert them to base::Values.
- // This is primarily used for API methods, but can also be used for API event
- // signatures.
- class APISignature {
- public:
- // Struct that bundles all the details about an asynchronous return.
- struct ReturnsAsync {
- ReturnsAsync();
- ~ReturnsAsync();
- // The list of expected arguments for the asynchronous return. Can be
- // nullopt if response validation isn't enabled, as it is only used when
- // validating a response from the API.
- absl::optional<std::vector<std::unique_ptr<ArgumentSpec>>> signature;
- // Indicates if passing the callback when calling the API is optional for
- // contexts or APIs which do not support promises (passing the callback is
- // always inheriently optional if promises are supported).
- bool optional = false;
- // Indicates if this API supports allowing promises for the asynchronous
- // return. Note that this is distinct from whether an actual call to the API
- // is allowed to use the promise based form, as that also depends on if the
- // calling context being checked by the access_checker.
- binding::APIPromiseSupport promise_support =
- binding::APIPromiseSupport::kUnsupported;
- };
- APISignature(std::vector<std::unique_ptr<ArgumentSpec>> signature,
- std::unique_ptr<APISignature::ReturnsAsync> returns_async,
- BindingAccessChecker* access_checker);
- APISignature(const APISignature&) = delete;
- APISignature& operator=(const APISignature&) = delete;
- ~APISignature();
- // Creates an APISignature object from the raw Value representations of an
- // API schema.
- static std::unique_ptr<APISignature> CreateFromValues(
- const base::Value& specification_list,
- const base::Value* returns_async,
- BindingAccessChecker* access_checker,
- const std::string& api_name,
- bool is_event_signature);
- struct V8ParseResult {
- // Appease the Chromium style plugin (out of line ctor/dtor).
- V8ParseResult();
- ~V8ParseResult();
- V8ParseResult(V8ParseResult&& other);
- V8ParseResult& operator=(V8ParseResult&& other);
- bool succeeded() const { return arguments.has_value(); }
- // The parsed v8 arguments. These may differ from the original v8 arguments
- // since it will include null-filled optional arguments. Populated if
- // parsing was successful. Note that the callback, if any, is included in
- // this list.
- absl::optional<std::vector<v8::Local<v8::Value>>> arguments;
- // Whether the asynchronous response is handled by a callback or a promise.
- binding::AsyncResponseType async_type = binding::AsyncResponseType::kNone;
- // The parse error, if parsing failed.
- absl::optional<std::string> error;
- };
- struct JSONParseResult {
- // Appease the Chromium style plugin (out of line ctor/dtor).
- JSONParseResult();
- ~JSONParseResult();
- JSONParseResult(JSONParseResult&& other);
- JSONParseResult& operator=(JSONParseResult&& other);
- bool succeeded() const { return !!arguments_list; }
- // The parsed JSON arguments, with null-filled optional arguments filled in.
- // Populated if parsing was successful. Does not include the callback (if
- // any).
- std::unique_ptr<base::Value> arguments_list;
- // The callback, if one was provided.
- v8::Local<v8::Function> callback;
- // Whether the asynchronous response is handled by a callback or a promise.
- binding::AsyncResponseType async_type = binding::AsyncResponseType::kNone;
- // The parse error, if parsing failed.
- absl::optional<std::string> error;
- };
- // Parses |arguments| against this signature, returning the result and
- // performing no argument conversion.
- V8ParseResult ParseArgumentsToV8(
- v8::Local<v8::Context> context,
- const std::vector<v8::Local<v8::Value>>& arguments,
- const APITypeReferenceMap& type_refs) const;
- // Parses |arguments| against this signature, returning the result after
- // converting to base::Values.
- JSONParseResult ParseArgumentsToJSON(
- v8::Local<v8::Context> context,
- const std::vector<v8::Local<v8::Value>>& arguments,
- const APITypeReferenceMap& type_refs) const;
- // Converts |arguments| to base::Values, ignoring the defined signature.
- // This is used when custom bindings modify the passed arguments to a form
- // that doesn't match the documented signature. Since we ignore the schema,
- // this parsing will never fail.
- JSONParseResult ConvertArgumentsIgnoringSchema(
- v8::Local<v8::Context> context,
- const std::vector<v8::Local<v8::Value>>& arguments) const;
- // Validates the provided |arguments| as if they were returned as a response
- // to an API call. This validation is much stricter than the versions above,
- // since response arguments are not allowed to have optional inner parameters.
- bool ValidateResponse(v8::Local<v8::Context> context,
- const std::vector<v8::Local<v8::Value>>& arguments,
- const APITypeReferenceMap& type_refs,
- std::string* error) const;
- // Same as `ValidateResponse`, but verifies the given `arguments` against the
- // `signature_` instead of the `returns_async_` types. This can be used when
- // validating that APIs return proper values to an event (which has a
- // signature, but no return).
- bool ValidateCall(v8::Local<v8::Context> context,
- const std::vector<v8::Local<v8::Value>>& arguments,
- const APITypeReferenceMap& type_refs,
- std::string* error) const;
- // Returns a developer-readable string of the expected signature. For
- // instance, if this signature expects a string 'someStr' and an optional int
- // 'someInt', this would return "string someStr, optional integer someInt".
- std::string GetExpectedSignature() const;
- bool has_async_return() const { return returns_async_ != nullptr; }
- bool has_async_return_signature() const {
- return has_async_return() && returns_async_->signature.has_value();
- }
- private:
- // Checks if promises are allowed to be used for a call to an API from a given
- // |context|.
- PromisesAllowed CheckPromisesAllowed(v8::Local<v8::Context> context) const;
- // The list of expected arguments for the API signature.
- std::vector<std::unique_ptr<ArgumentSpec>> signature_;
- // The details of any asynchronous return an API method may have. This will be
- // nullptr if the the API doesn't have an asynchronous return.
- std::unique_ptr<APISignature::ReturnsAsync> returns_async_;
- // The associated access checker; required to outlive this object.
- const BindingAccessChecker* access_checker_;
- // A developer-readable method signature string, lazily set.
- mutable std::string expected_signature_;
- };
- } // namespace extensions
- #endif // EXTENSIONS_RENDERER_BINDINGS_API_SIGNATURE_H_
|