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
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_H_
6 #define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_H_
7 
8 #include "mojo/public/cpp/bindings/remote.h"
9 #include "net/cookies/site_for_cookies.h"
10 #include "services/network/public/mojom/restricted_cookie_manager.mojom-blink-forward.h"
11 #include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom-blink.h"
12 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
13 #include "third_party/blink/renderer/core/dom/events/event_target.h"
14 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
15 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
16 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
17 #include "third_party/blink/renderer/platform/heap/handle.h"
18 #include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
19 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
20 #include "third_party/blink/renderer/platform/wtf/vector.h"
21 
22 namespace blink {
23 
24 class CanonicalCookie;
25 class CookieStoreDeleteOptions;
26 class CookieStoreGetOptions;
27 class CookieStoreSetOptions;
28 class CookieStoreSetExtraOptions;
29 class ExceptionState;
30 class ScriptPromiseResolver;
31 class ScriptState;
32 
33 class CookieStore final : public EventTargetWithInlineData,
34                           public ExecutionContextLifecycleObserver,
35                           public network::mojom::blink::CookieChangeListener {
36   DEFINE_WRAPPERTYPEINFO();
37   USING_GARBAGE_COLLECTED_MIXIN(CookieStore);
38 
39  public:
40   CookieStore(
41       ExecutionContext*,
42       mojo::Remote<network::mojom::blink::RestrictedCookieManager> backend);
43   // Needed because of the
44   // mojo::Remote<network::mojom::blink::RestrictedCookieManager>
45   ~CookieStore() override;
46 
47   ScriptPromise getAll(ScriptState*, const String& name, ExceptionState&);
48   ScriptPromise getAll(ScriptState*,
49                        const CookieStoreGetOptions*,
50                        ExceptionState&);
51   ScriptPromise get(ScriptState*, const String& name, ExceptionState&);
52   ScriptPromise get(ScriptState*,
53                     const CookieStoreGetOptions*,
54                     ExceptionState&);
55 
56   ScriptPromise set(ScriptState*,
57                     const CookieStoreSetExtraOptions*,
58                     ExceptionState&);
59   ScriptPromise set(ScriptState*,
60                     const String& name,
61                     const String& value,
62                     const CookieStoreSetOptions*,
63                     ExceptionState&);
64   ScriptPromise Delete(ScriptState*, const String& name, ExceptionState&);
65   ScriptPromise Delete(ScriptState*,
66                        const CookieStoreDeleteOptions*,
67                        ExceptionState&);
68 
69   // GarbageCollected
70   void Trace(Visitor* visitor) override;
71 
72   // ExecutionContextLifecycleObserver
73   void ContextDestroyed() override;
74 
75   // EventTargetWithInlineData
76   DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
77   const AtomicString& InterfaceName() const override;
78   ExecutionContext* GetExecutionContext() const override;
79   void RemoveAllEventListeners() override;
80 
81   // RestrictedCookieChangeListener
82   void OnCookieChange(
83       network::mojom::blink::CookieChangeInfoPtr change) override;
84 
85  protected:
86   // EventTarget overrides.
87   void AddedEventListener(const AtomicString& event_type,
88                           RegisteredEventListener&) final;
89   void RemovedEventListener(const AtomicString& event_type,
90                             const RegisteredEventListener&) final;
91 
92  private:
93   using DoReadBackendResultConverter = void (*)(ScriptPromiseResolver*,
94                                                 const Vector<CanonicalCookie>&);
95 
96   // Common code in CookieStore::{get,getAll}.
97   //
98   // All cookie-reading methods use the same RestrictedCookieManager API, and
99   // only differ in how they present the returned data. The difference is
100   // captured in the DoReadBackendResultConverter argument, which should point
101   // to one of the static methods below.
102   ScriptPromise DoRead(ScriptState*,
103                        const CookieStoreGetOptions*,
104                        DoReadBackendResultConverter,
105                        ExceptionState&);
106 
107   // Converts the result of a RestrictedCookieManager::GetAllForUrl mojo call to
108   // the promise result expected by CookieStore.getAll.
109   static void GetAllForUrlToGetAllResult(
110       ScriptPromiseResolver*,
111       const Vector<CanonicalCookie>& backend_result);
112 
113   // Converts the result of a RestrictedCookieManager::GetAllForUrl mojo call to
114   // the promise result expected by CookieStore.get.
115   static void GetAllForUrlToGetResult(
116       ScriptPromiseResolver*,
117       const Vector<CanonicalCookie>& backend_result);
118 
119   // Common code in CookieStore::delete and CookieStore::set.
120   ScriptPromise DoWrite(ScriptState*,
121                         const CookieStoreSetExtraOptions*,
122                         ExceptionState&);
123 
124   static void OnSetCanonicalCookieResult(ScriptPromiseResolver*,
125                                          bool backend_result);
126 
127   // Called when a change event listener is added.
128   //
129   // This is idempotent during the time intervals between StopObserving() calls.
130   void StartObserving();
131 
132   // Called when all the change event listeners have been removed.
133   void StopObserving();
134 
135   // Wraps an always-on Mojo pipe for sending requests to the Network Service.
136   mojo::Remote<network::mojom::blink::RestrictedCookieManager> backend_;
137 
138   // Wraps a Mojo pipe used to receive cookie change notifications.
139   //
140   // This receiver is set up on-demand, when the cookie store has at least one
141   // change event listener. If all the listeners are unregistered, the receiver
142   // is torn down.
143   HeapMojoReceiver<network::mojom::blink::CookieChangeListener>
144       change_listener_receiver_;
145 
146   // Default for cookie_url in CookieStoreGetOptions.
147   //
148   // This is the current document's URL. API calls coming from a document
149   // context are not allowed to specify a different cookie_url, whereas Service
150   // Workers may specify any URL that falls under their registration.
151   const KURL default_cookie_url_;
152 
153   // The RFC 6265bis "site for cookies" for this store's ExecutionContext.
154   const net::SiteForCookies default_site_for_cookies_;
155 
156   // The context in which cookies are accessed.
157   const scoped_refptr<SecurityOrigin> default_top_frame_origin_;
158 };
159 
160 }  // namespace blink
161 
162 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_H_
163