Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: chrome/browser/extensions/api/cookies/cookies_helpers.cc

Issue 10702088: Refactor chrome.cookies API to use JSON schema compiler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Sync Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Implements common functionality for the Chrome Extensions Cookies API. 5 // Implements common functionality for the Chrome Extensions Cookies API.
6 6
7 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h" 7 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
8 8
9 #include <vector>
10
9 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/linked_ptr.h"
13 #include "base/memory/scoped_ptr.h"
10 #include "base/string_util.h" 14 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
12 #include "base/values.h" 16 #include "base/values.h"
13 #include "chrome/browser/extensions/api/cookies/cookies_api_constants.h" 17 #include "chrome/browser/extensions/api/cookies/cookies_api_constants.h"
14 #include "chrome/browser/extensions/extension_tab_util.h" 18 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/tab_contents/tab_contents.h" 21 #include "chrome/browser/ui/tab_contents/tab_contents.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h" 22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/extensions/api/cookies.h"
19 #include "chrome/common/extensions/extension.h" 24 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/url_constants.h" 25 #include "chrome/common/url_constants.h"
21 #include "content/public/browser/web_contents.h" 26 #include "content/public/browser/web_contents.h"
22 #include "googleurl/src/gurl.h" 27 #include "googleurl/src/gurl.h"
23 #include "net/cookies/canonical_cookie.h" 28 #include "net/cookies/canonical_cookie.h"
24 #include "net/cookies/cookie_util.h" 29 #include "net/cookies/cookie_util.h"
25 30
31 using extensions::api::cookies::Cookie;
32 using extensions::api::cookies::CookieStore;
33
34 namespace GetAll = extensions::api::cookies::GetAll;
35
26 namespace extensions { 36 namespace extensions {
27 37
28 namespace keys = cookies_api_constants; 38 namespace keys = cookies_api_constants;
29 39
30 namespace cookies_helpers { 40 namespace cookies_helpers {
31 41
32 static const char kOriginalProfileStoreId[] = "0"; 42 static const char kOriginalProfileStoreId[] = "0";
33 static const char kOffTheRecordProfileStoreId[] = "1"; 43 static const char kOffTheRecordProfileStoreId[] = "1";
34 44
35 Profile* ChooseProfileFromStoreId(const std::string& store_id, 45 Profile* ChooseProfileFromStoreId(const std::string& store_id,
36 Profile* profile, 46 Profile* profile,
37 bool include_incognito) { 47 bool include_incognito) {
38 DCHECK(profile); 48 DCHECK(profile);
39 bool allow_original = !profile->IsOffTheRecord(); 49 bool allow_original = !profile->IsOffTheRecord();
40 bool allow_incognito = profile->IsOffTheRecord() || 50 bool allow_incognito = profile->IsOffTheRecord() ||
41 (include_incognito && profile->HasOffTheRecordProfile()); 51 (include_incognito && profile->HasOffTheRecordProfile());
42 if (store_id == kOriginalProfileStoreId && allow_original) 52 if (store_id == kOriginalProfileStoreId && allow_original)
43 return profile->GetOriginalProfile(); 53 return profile->GetOriginalProfile();
44 if (store_id == kOffTheRecordProfileStoreId && allow_incognito) 54 if (store_id == kOffTheRecordProfileStoreId && allow_incognito)
45 return profile->GetOffTheRecordProfile(); 55 return profile->GetOffTheRecordProfile();
46 return NULL; 56 return NULL;
47 } 57 }
48 58
49 const char* GetStoreIdFromProfile(Profile* profile) { 59 const char* GetStoreIdFromProfile(Profile* profile) {
50 DCHECK(profile); 60 DCHECK(profile);
51 return profile->IsOffTheRecord() ? 61 return profile->IsOffTheRecord() ?
52 kOffTheRecordProfileStoreId : kOriginalProfileStoreId; 62 kOffTheRecordProfileStoreId : kOriginalProfileStoreId;
53 } 63 }
54 64
55 DictionaryValue* CreateCookieValue(const net::CanonicalCookie& cookie, 65 scoped_ptr<Cookie> CreateCookie(
56 const std::string& store_id) { 66 const net::CanonicalCookie& canonical_cookie,
57 DictionaryValue* result = new DictionaryValue(); 67 const std::string& store_id) {
68 scoped_ptr<Cookie> cookie(new Cookie());
58 69
59 // A cookie is a raw byte sequence. By explicitly parsing it as UTF8, we 70 // A cookie is a raw byte sequence. By explicitly parsing it as UTF-8, we
60 // apply error correction, so the string can be safely passed to the 71 // apply error correction, so the string can be safely passed to the renderer.
61 // renderer. 72 cookie->name = UTF16ToUTF8(UTF8ToUTF16(canonical_cookie.Name()));
62 result->SetString(keys::kNameKey, UTF8ToUTF16(cookie.Name())); 73 cookie->value = UTF16ToUTF8(UTF8ToUTF16(canonical_cookie.Value()));
63 result->SetString(keys::kValueKey, UTF8ToUTF16(cookie.Value())); 74 cookie->domain = canonical_cookie.Domain();
64 result->SetString(keys::kDomainKey, cookie.Domain()); 75 cookie->host_only = net::cookie_util::DomainIsHostOnly(
65 result->SetBoolean(keys::kHostOnlyKey, 76 canonical_cookie.Domain());
66 net::cookie_util::DomainIsHostOnly(cookie.Domain())); 77 // A non-UTF8 path is invalid, so we just replace it with an empty string.
78 cookie->path = IsStringUTF8(canonical_cookie.Path()) ?
79 canonical_cookie.Path() : "";
80 cookie->secure = canonical_cookie.IsSecure();
81 cookie->http_only = canonical_cookie.IsHttpOnly();
82 cookie->session = !canonical_cookie.IsPersistent();
83 if (canonical_cookie.IsPersistent()) {
84 cookie->expiration_date.reset(
85 new double(canonical_cookie.ExpiryDate().ToDoubleT()));
86 }
87 cookie->store_id = store_id;
67 88
68 // A non-UTF8 path is invalid, so we just replace it with an empty string. 89 return cookie.Pass();
69 result->SetString(keys::kPathKey,
70 IsStringUTF8(cookie.Path()) ? cookie.Path() : "");
71 result->SetBoolean(keys::kSecureKey, cookie.IsSecure());
72 result->SetBoolean(keys::kHttpOnlyKey, cookie.IsHttpOnly());
73 result->SetBoolean(keys::kSessionKey, !cookie.IsPersistent());
74 if (cookie.IsPersistent()) {
75 result->SetDouble(keys::kExpirationDateKey,
76 cookie.ExpiryDate().ToDoubleT());
77 }
78 result->SetString(keys::kStoreIdKey, store_id);
79
80 return result;
81 } 90 }
82 91
83 DictionaryValue* CreateCookieStoreValue(Profile* profile, 92 scoped_ptr<CookieStore> CreateCookieStore(Profile* profile,
84 ListValue* tab_ids) { 93 ListValue* tab_ids) {
85 DCHECK(profile); 94 DCHECK(profile);
86 DCHECK(tab_ids); 95 DCHECK(tab_ids);
87 DictionaryValue* result = new DictionaryValue(); 96 DictionaryValue dict;
88 result->SetString(keys::kIdKey, GetStoreIdFromProfile(profile)); 97 dict.SetString(keys::kIdKey, GetStoreIdFromProfile(profile));
89 result->Set(keys::kTabIdsKey, tab_ids); 98 dict.Set(keys::kTabIdsKey, tab_ids);
90 return result; 99
100 CookieStore* cookie_store = new CookieStore();
101 bool rv = CookieStore::Populate(dict, cookie_store);
102 CHECK(rv);
103 return scoped_ptr<CookieStore>(cookie_store);
91 } 104 }
92 105
93 void GetCookieListFromStore( 106 void GetCookieListFromStore(
94 net::CookieStore* cookie_store, const GURL& url, 107 net::CookieStore* cookie_store, const GURL& url,
95 const net::CookieMonster::GetCookieListCallback& callback) { 108 const net::CookieMonster::GetCookieListCallback& callback) {
96 DCHECK(cookie_store); 109 DCHECK(cookie_store);
97 net::CookieMonster* monster = cookie_store->GetCookieMonster(); 110 net::CookieMonster* monster = cookie_store->GetCookieMonster();
98 if (!url.is_empty()) { 111 if (!url.is_empty()) {
99 DCHECK(url.is_valid()); 112 DCHECK(url.is_valid());
100 monster->GetAllCookiesForURLAsync(url, callback); 113 monster->GetAllCookiesForURLAsync(url, callback);
101 } else { 114 } else {
102 monster->GetAllCookiesAsync(callback); 115 monster->GetAllCookiesAsync(callback);
103 } 116 }
104 } 117 }
105 118
106 GURL GetURLFromCanonicalCookie(const net::CanonicalCookie& cookie) { 119 GURL GetURLFromCanonicalCookie(const net::CanonicalCookie& cookie) {
107 const std::string& domain_key = cookie.Domain(); 120 const std::string& domain_key = cookie.Domain();
108 const std::string scheme = 121 const std::string scheme =
109 cookie.IsSecure() ? chrome::kHttpsScheme : chrome::kHttpScheme; 122 cookie.IsSecure() ? chrome::kHttpsScheme : chrome::kHttpScheme;
110 const std::string host = 123 const std::string host =
111 domain_key.find('.') != 0 ? domain_key : domain_key.substr(1); 124 domain_key.find('.') != 0 ? domain_key : domain_key.substr(1);
112 return GURL(scheme + content::kStandardSchemeSeparator + host + "/"); 125 return GURL(scheme + content::kStandardSchemeSeparator + host + "/");
113 } 126 }
114 127
115 void AppendMatchingCookiesToList( 128 void AppendMatchingCookiesToVector(const net::CookieList& all_cookies,
116 const net::CookieList& all_cookies, 129 const GURL& url,
117 const std::string& store_id, 130 const GetAll::Params::Details* details,
118 const GURL& url, const DictionaryValue* details, 131 const Extension* extension,
119 const Extension* extension, 132 LinkedCookieVec* match_vector) {
120 ListValue* match_list) {
121 net::CookieList::const_iterator it; 133 net::CookieList::const_iterator it;
122 for (it = all_cookies.begin(); it != all_cookies.end(); ++it) { 134 for (it = all_cookies.begin(); it != all_cookies.end(); ++it) {
123 // Ignore any cookie whose domain doesn't match the extension's 135 // Ignore any cookie whose domain doesn't match the extension's
124 // host permissions. 136 // host permissions.
125 GURL cookie_domain_url = GetURLFromCanonicalCookie(*it); 137 GURL cookie_domain_url = GetURLFromCanonicalCookie(*it);
126 if (!extension->HasHostPermission(cookie_domain_url)) 138 if (!extension->HasHostPermission(cookie_domain_url))
127 continue; 139 continue;
128 // Filter the cookie using the match filter. 140 // Filter the cookie using the match filter.
129 cookies_helpers::MatchFilter filter(details); 141 cookies_helpers::MatchFilter filter(details);
130 if (filter.MatchesCookie(*it)) 142 if (filter.MatchesCookie(*it)) {
131 match_list->Append(CreateCookieValue(*it, store_id)); 143 match_vector->push_back(make_linked_ptr(
144 CreateCookie(*it, *details->store_id).release()));
145 }
132 } 146 }
133 } 147 }
134 148
135 void AppendToTabIdList(Browser* browser, ListValue* tab_ids) { 149 void AppendToTabIdList(Browser* browser, ListValue* tab_ids) {
136 DCHECK(browser); 150 DCHECK(browser);
137 DCHECK(tab_ids); 151 DCHECK(tab_ids);
138 TabStripModel* tab_strip = browser->tab_strip_model(); 152 TabStripModel* tab_strip = browser->tab_strip_model();
139 for (int i = 0; i < tab_strip->count(); ++i) { 153 for (int i = 0; i < tab_strip->count(); ++i) {
140 tab_ids->Append(Value::CreateIntegerValue( 154 tab_ids->Append(Value::CreateIntegerValue(
141 ExtensionTabUtil::GetTabId( 155 ExtensionTabUtil::GetTabId(
142 tab_strip->GetTabContentsAt(i)->web_contents()))); 156 tab_strip->GetTabContentsAt(i)->web_contents())));
143 } 157 }
144 } 158 }
145 159
146 MatchFilter::MatchFilter(const DictionaryValue* details) 160 MatchFilter::MatchFilter(const GetAll::Params::Details* details)
147 : details_(details) { 161 : details_(details) {
148 DCHECK(details_); 162 DCHECK(details_);
149 } 163 }
150 164
151 bool MatchFilter::MatchesCookie(const net::CanonicalCookie& cookie) { 165 bool MatchFilter::MatchesCookie(
152 return MatchesString(keys::kNameKey, cookie.Name()) && 166 const net::CanonicalCookie& cookie) {
153 MatchesDomain(cookie.Domain()) && 167 if (details_->name.get() && *details_->name != cookie.Name())
154 MatchesString(keys::kPathKey, cookie.Path()) && 168 return false;
155 MatchesBoolean(keys::kSecureKey, cookie.IsSecure()) &&
156 MatchesBoolean(keys::kSessionKey, !cookie.IsPersistent());
157 }
158 169
159 bool MatchFilter::MatchesString(const char* key, const std::string& value) { 170 if (!MatchesDomain(cookie.Domain()))
160 if (!details_->HasKey(key)) 171 return false;
161 return true;
162 std::string filter_value;
163 return (details_->GetString(key, &filter_value) &&
164 value == filter_value);
165 }
166 172
167 bool MatchFilter::MatchesBoolean(const char* key, bool value) { 173 if (details_->path.get() && *details_->path != cookie.Path())
168 if (!details_->HasKey(key)) 174 return false;
169 return true; 175
170 bool filter_value = false; 176 if (details_->secure.get() && *details_->secure != cookie.IsSecure())
171 return (details_->GetBoolean(key, &filter_value) && 177 return false;
172 value == filter_value); 178
179 if (details_->session.get() && *details_->session != !cookie.IsPersistent())
180 return false;
181
182 return true;
173 } 183 }
174 184
175 bool MatchFilter::MatchesDomain(const std::string& domain) { 185 bool MatchFilter::MatchesDomain(const std::string& domain) {
176 if (!details_->HasKey(keys::kDomainKey)) 186 if (!details_->domain.get())
177 return true; 187 return true;
178 188
179 std::string filter_value;
180 if (!details_->GetString(keys::kDomainKey, &filter_value))
181 return false;
182 // Add a leading '.' character to the filter domain if it doesn't exist. 189 // Add a leading '.' character to the filter domain if it doesn't exist.
183 if (net::cookie_util::DomainIsHostOnly(filter_value)) 190 if (net::cookie_util::DomainIsHostOnly(*details_->domain))
184 filter_value.insert(0, "."); 191 details_->domain->insert(0, ".");
185 192
186 std::string sub_domain(domain); 193 std::string sub_domain(domain);
187 // Strip any leading '.' character from the input cookie domain. 194 // Strip any leading '.' character from the input cookie domain.
188 if (!net::cookie_util::DomainIsHostOnly(sub_domain)) 195 if (!net::cookie_util::DomainIsHostOnly(sub_domain))
189 sub_domain = sub_domain.substr(1); 196 sub_domain = sub_domain.substr(1);
190 197
191 // Now check whether the domain argument is a subdomain of the filter domain. 198 // Now check whether the domain argument is a subdomain of the filter domain.
192 for (sub_domain.insert(0, "."); 199 for (sub_domain.insert(0, ".");
193 sub_domain.length() >= filter_value.length();) { 200 sub_domain.length() >= details_->domain->length();) {
194 if (sub_domain == filter_value) 201 if (sub_domain == *details_->domain)
195 return true; 202 return true;
196 const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot. 203 const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
197 sub_domain.erase(0, next_dot); 204 sub_domain.erase(0, next_dot);
198 } 205 }
199 return false; 206 return false;
200 } 207 }
201 208
202 } // namespace cookies_helpers 209 } // namespace cookies_helpers
203 } // namespace extension 210 } // namespace extension
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/cookies/cookies_helpers.h ('k') | chrome/browser/extensions/api/cookies/cookies_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698