File: child_frame_registrar.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (128 lines) | stat: -rw-r--r-- 5,748 bytes parent folder | download | duplicates (5)
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
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_AUTOFILL_IOS_FORM_UTIL_CHILD_FRAME_REGISTRAR_H_
#define COMPONENTS_AUTOFILL_IOS_FORM_UTIL_CHILD_FRAME_REGISTRAR_H_

#import <map>
#import <optional>

#import "base/observer_list.h"
#import "base/scoped_multi_source_observation.h"
#import "base/scoped_observation.h"
#import "components/autofill/core/common/unique_ids.h"
#import "ios/web/public/js_messaging/java_script_feature.h"
#import "ios/web/public/js_messaging/web_frames_manager.h"
#import "ios/web/public/web_state_observer.h"
#import "ios/web/public/web_state_user_data.h"

namespace autofill {

// Observer of ChildFrameRegistrar events.
class ChildFrameRegistrarObserver : public base::CheckedObserver {
 public:
  // Called when there was an attempt made to register the same remote token
  // twice with a different |local| token. This may mean spoofing so the
  // receiver of this notification should act accordingly.
  virtual void OnDidDoubleRegistration(LocalFrameToken local) = 0;
};

// Child frame registration is the process whereby a frame can assign an ID (a
// remote frame token) to a child frame, establishing a relationship between
// that frame in the DOM (and JS) and the corresponding WebFrame object in C++.
// This class maintains those mappings.
class ChildFrameRegistrar : public web::WebStateUserData<ChildFrameRegistrar>,
                            public web::WebFramesManager::Observer,
                            public web::WebStateObserver {
 public:
  ~ChildFrameRegistrar() override;

  // Maps from remote to local tokens for all registered frames, to allow
  // lookup of a frame based on its remote token.
  //
  // Frame Tokens are used by browser-layer Autofill code to identify and
  // interact with a specific frame. Local Frame Tokens must not leak to frames
  // other than the ones they identify, while Remote Frame Tokens are also known
  // to the parent frame.
  //
  // In the context of iOS, the LocalFrameToken is equal to the frameId and can
  // be used to fetch the appropriate WebFrame from the WebFramesManager.
  std::optional<LocalFrameToken> LookupChildFrame(RemoteFrameToken remote);

  // Informs the Registrar that `remote` corresponds to the frame with frame ID
  // `local`.
  void RegisterMapping(RemoteFrameToken remote, LocalFrameToken local);

  // Convenience method that looks for dict values with keys "local_frame_id"
  // and "remote_frame_id" in the given `message`, converts them to the
  // appropriate tokens, and calls `RegisterMapping` using them. No-op if
  // `message` is not a dict, if the needed keys are not present, or if the
  // values are malformed.
  void ProcessRegistrationMessage(base::Value* message);

  // Notifies the registrar that a remote token `remote` has been dispatched to
  // a child frame. If the registrar already knows about this token, `callback`
  // will be invoked immediately with the corresponding local token. If not,
  // the registrar will hold on to the callback until it encounters `remote` and
  // execute it at that time.
  // Be careful what you bind to `callback`, and use WeakPtr as necessary, as
  // it may be retained indefinitely.
  void DeclareNewRemoteToken(
      RemoteFrameToken remote,
      base::OnceCallback<void(LocalFrameToken)> callback);

  // Returns the existing registrar for the given `web_state`, if there is one,
  // or creates a new one. May return nullptr if this functionality is not
  // available.
  static ChildFrameRegistrar* GetOrCreateForWebState(web::WebState* web_state);

  // Adds the |observer| to the list of observers.
  void AddObserver(ChildFrameRegistrarObserver* observer);

  // Removes |observer| from the list of observers.
  void RemoveObserver(ChildFrameRegistrarObserver* observer);

  // web::WebFramesManager::Observer:
  void WebFrameBecameUnavailable(web::WebFramesManager* web_frames_manager,
                                 const std::string& frame_id) override;

  // web::WebStateObserver
  void WebStateDestroyed(web::WebState* web_state) override;

 private:
  explicit ChildFrameRegistrar(web::WebState* web_state);
  friend class web::WebStateUserData<ChildFrameRegistrar>;

  // Deletes all entries in `lookup_map_` that contain `frame_id` as local frame
  // token.
  void RemoveFrameID(const std::string& frame_id);

  // Maintains the mapping used by `LookupChildFrame`. The value containing the
  // local frame token is set to std::nullopt if there was at least one attempt
  // to register the same remote token, as a security precaution, making the
  // token and thus the frame invalid for the entire registrar's lifetime.
  std::map<RemoteFrameToken, std::optional<LocalFrameToken>> lookup_map_;

  // When `DeclareNewRemoteToken` is called, the RemoteFrameToken may not
  // yet correspond to a known frame. In this case, the callback is stored in
  // this map until a matching remote token is registered.
  std::map<RemoteFrameToken, base::OnceCallback<void(LocalFrameToken)>>
      pending_callbacks_;

  base::ObserverList<ChildFrameRegistrarObserver> observers_;

  // Observation for listening to WebFrame events. Multiple observations are
  // required because there are two WebFramesManager per WebState, one for each
  // ContentWorld.
  base::ScopedMultiSourceObservation<web::WebFramesManager,
                                     web::WebFramesManager::Observer>
      web_frames_managers_observation_{this};

  base::ScopedObservation<web::WebState, web::WebStateObserver>
      web_state_observation_{this};
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_IOS_FORM_UTIL_CHILD_FRAME_REGISTRAR_H_