1 // Copyright 2018 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 #include "content/browser/cookie_store/cookie_change_subscription.h"
6
7 #include <utility>
8
9 #include "content/browser/cookie_store/cookie_change_subscriptions.pb.h"
10
11 namespace content {
12
13 namespace {
14
15 #define STATIC_ASSERT_ENUM(a, b) \
16 static_assert(static_cast<int>(a) == static_cast<int>(b), \
17 "mismatching enums: " #a)
18
19 STATIC_ASSERT_ENUM(network::mojom::CookieMatchType::EQUALS,
20 proto::CookieMatchType::EQUALS);
21 STATIC_ASSERT_ENUM(network::mojom::CookieMatchType::STARTS_WITH,
22 proto::CookieMatchType::STARTS_WITH);
23
CookieMatchTypeToProto(network::mojom::CookieMatchType match_type)24 proto::CookieMatchType CookieMatchTypeToProto(
25 network::mojom::CookieMatchType match_type) {
26 switch (match_type) {
27 case network::mojom::CookieMatchType::EQUALS:
28 return proto::CookieMatchType::EQUALS;
29 case ::network::mojom::CookieMatchType::STARTS_WITH:
30 return proto::CookieMatchType::STARTS_WITH;
31 }
32 NOTREACHED();
33 return proto::CookieMatchType::EQUALS;
34 }
35
CookieMatchTypeFromProto(proto::CookieMatchType match_type_proto)36 network::mojom::CookieMatchType CookieMatchTypeFromProto(
37 proto::CookieMatchType match_type_proto) {
38 switch (match_type_proto) {
39 case proto::CookieMatchType::EQUALS:
40 return network::mojom::CookieMatchType::EQUALS;
41 case proto::CookieMatchType::STARTS_WITH:
42 return ::network::mojom::CookieMatchType::STARTS_WITH;
43 default:
44 // The on-disk value was corrupted.
45 return network::mojom::CookieMatchType::EQUALS;
46 }
47 }
48
49 } // namespace
50
51 // static
52 std::vector<std::unique_ptr<CookieChangeSubscription>>
DeserializeVector(const std::string & proto_string,int64_t service_worker_registration_id)53 CookieChangeSubscription::DeserializeVector(
54 const std::string& proto_string,
55 int64_t service_worker_registration_id) {
56 std::vector<std::unique_ptr<CookieChangeSubscription>> subscriptions;
57
58 proto::CookieChangeSubscriptionsProto subscriptions_proto;
59 if (!subscriptions_proto.ParseFromString(proto_string))
60 return subscriptions;
61
62 int subscription_count = subscriptions_proto.subscriptions_size();
63 subscriptions.reserve(subscription_count);
64 for (int i = 0; i < subscription_count; ++i) {
65 std::unique_ptr<CookieChangeSubscription> subscription =
66 CookieChangeSubscription::Create(subscriptions_proto.subscriptions(i),
67 service_worker_registration_id);
68 if (!subscription)
69 continue;
70 subscriptions.push_back(std::move(subscription));
71 }
72
73 return subscriptions;
74 }
75
76 // static
SerializeVector(const std::vector<std::unique_ptr<CookieChangeSubscription>> & subscriptions)77 std::string CookieChangeSubscription::SerializeVector(
78 const std::vector<std::unique_ptr<CookieChangeSubscription>>&
79 subscriptions) {
80 DCHECK(!subscriptions.empty());
81 proto::CookieChangeSubscriptionsProto subscriptions_proto;
82 for (const auto& subscription : subscriptions)
83 subscription->Serialize(subscriptions_proto.add_subscriptions());
84 return subscriptions_proto.SerializeAsString();
85 }
86
87 // static
88 std::vector<blink::mojom::CookieChangeSubscriptionPtr>
ToMojoVector(const std::vector<std::unique_ptr<CookieChangeSubscription>> & subscriptions)89 CookieChangeSubscription::ToMojoVector(
90 const std::vector<std::unique_ptr<CookieChangeSubscription>>&
91 subscriptions) {
92 std::vector<blink::mojom::CookieChangeSubscriptionPtr> mojo_subscriptions;
93 mojo_subscriptions.reserve(subscriptions.size());
94 for (const auto& subscription : subscriptions) {
95 auto mojo_subscription = blink::mojom::CookieChangeSubscription::New();
96 subscription->Serialize(mojo_subscription.get());
97 mojo_subscriptions.push_back(std::move(mojo_subscription));
98 }
99 return mojo_subscriptions;
100 }
101
102 // static
Create(proto::CookieChangeSubscriptionProto proto,int64_t service_worker_registration_id)103 std::unique_ptr<CookieChangeSubscription> CookieChangeSubscription::Create(
104 proto::CookieChangeSubscriptionProto proto,
105 int64_t service_worker_registration_id) {
106 GURL url(proto.url());
107 if (!url.is_valid())
108 return nullptr;
109
110 std::string name = proto.name();
111 ::network::mojom::CookieMatchType match_type =
112 CookieMatchTypeFromProto(proto.match_type());
113
114 return std::make_unique<CookieChangeSubscription>(
115 std::move(url), std::move(name), match_type,
116 service_worker_registration_id);
117 }
118
119 CookieChangeSubscription::~CookieChangeSubscription() = default;
120
CookieChangeSubscription(blink::mojom::CookieChangeSubscriptionPtr mojo_subscription,int64_t service_worker_registration_id)121 CookieChangeSubscription::CookieChangeSubscription(
122 blink::mojom::CookieChangeSubscriptionPtr mojo_subscription,
123 int64_t service_worker_registration_id)
124 : url_(std::move(mojo_subscription->url)),
125 name_(std::move(mojo_subscription->name)),
126 match_type_(mojo_subscription->match_type),
127 service_worker_registration_id_(service_worker_registration_id) {}
128
CookieChangeSubscription(GURL url,std::string name,::network::mojom::CookieMatchType match_type,int64_t service_worker_registration_id)129 CookieChangeSubscription::CookieChangeSubscription(
130 GURL url,
131 std::string name,
132 ::network::mojom::CookieMatchType match_type,
133 int64_t service_worker_registration_id)
134 : url_(std::move(url)),
135 name_(std::move(name)),
136 match_type_(match_type),
137 service_worker_registration_id_(service_worker_registration_id) {}
138
Serialize(proto::CookieChangeSubscriptionProto * proto) const139 void CookieChangeSubscription::Serialize(
140 proto::CookieChangeSubscriptionProto* proto) const {
141 proto->set_match_type(CookieMatchTypeToProto(match_type_));
142 proto->set_name(name_);
143 proto->set_url(url_.spec());
144 }
145
Serialize(blink::mojom::CookieChangeSubscription * mojo_subscription) const146 void CookieChangeSubscription::Serialize(
147 blink::mojom::CookieChangeSubscription* mojo_subscription) const {
148 mojo_subscription->url = url_;
149 mojo_subscription->name = name_;
150 mojo_subscription->match_type = match_type_;
151 }
152
ShouldObserveChangeTo(const net::CanonicalCookie & cookie,net::CookieAccessSemantics access_semantics) const153 bool CookieChangeSubscription::ShouldObserveChangeTo(
154 const net::CanonicalCookie& cookie,
155 net::CookieAccessSemantics access_semantics) const {
156 switch (match_type_) {
157 case ::network::mojom::CookieMatchType::EQUALS:
158 if (cookie.Name() != name_)
159 return false;
160 break;
161 case ::network::mojom::CookieMatchType::STARTS_WITH:
162 if (!base::StartsWith(cookie.Name(), name_, base::CompareCase::SENSITIVE))
163 return false;
164 break;
165 }
166
167 net::CookieOptions net_options;
168 net_options.set_same_site_cookie_context(
169 net::CookieOptions::SameSiteCookieContext::MakeInclusive());
170
171 return cookie.IncludeForRequestURL(url_, net_options, access_semantics)
172 .status.IsInclude();
173 }
174
operator ==(const CookieChangeSubscription & lhs,const CookieChangeSubscription & rhs)175 bool operator==(const CookieChangeSubscription& lhs,
176 const CookieChangeSubscription& rhs) {
177 return (lhs.match_type() == rhs.match_type()) && (lhs.name() == rhs.name()) &&
178 (lhs.url() == rhs.url());
179 }
180
181 } // namespace content
182