diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-08 21:10:55 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-08 21:10:55 +0000 |
commit | 45134197a411fd9e02986c9e11d7b6d876891f23 (patch) | |
tree | c46c08306d7424b3a607ca0d06b2742d7e879c68 /chrome/browser/net | |
parent | 7d74aaab9390a7502dac835ddcd2a5175224702e (diff) | |
download | chromium_src-45134197a411fd9e02986c9e11d7b6d876891f23.zip chromium_src-45134197a411fd9e02986c9e11d7b6d876891f23.tar.gz chromium_src-45134197a411fd9e02986c9e11d7b6d876891f23.tar.bz2 |
Show an app modal dialog when the cookie policy is ASK.
This hooks up the dialog for cookies and localstorage. It also includes
support for remembering the decision, and in the case of cookies, support is
added for forcing a cookie to be a stored as a session cookie.
BUG=34625,34572
Review URL: http://codereview.chromium.org/583004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38393 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net')
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy.cc | 159 | ||||
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy.h | 29 |
2 files changed, 150 insertions, 38 deletions
diff --git a/chrome/browser/net/chrome_cookie_policy.cc b/chrome/browser/net/chrome_cookie_policy.cc index 3e924d1..a72d916 100644 --- a/chrome/browser/net/chrome_cookie_policy.cc +++ b/chrome/browser/net/chrome_cookie_policy.cc @@ -5,8 +5,11 @@ #include "chrome/browser/net/chrome_cookie_policy.h" #include "base/string_util.h" +#include "chrome/browser/browser_list.h" #include "chrome/browser/chrome_thread.h" +#include "chrome/browser/cookie_prompt_modal_dialog_delegate.h" #include "chrome/browser/host_content_settings_map.h" +#include "chrome/browser/message_box_handler.h" #include "googleurl/src/gurl.h" #include "net/base/net_errors.h" #include "net/base/static_cookie_policy.h" @@ -16,6 +19,40 @@ // sign of trouble anyways. static const size_t kMaxCompletionsPerHost = 10000; +// ---------------------------------------------------------------------------- + +class ChromeCookiePolicy::PromptDelegate + : public CookiePromptModalDialogDelegate { + public: + PromptDelegate(ChromeCookiePolicy* cookie_policy, const std::string& host) + : cookie_policy_(cookie_policy), + host_(host) { + } + + // CookiesPromptViewDelegate methods: + virtual void AllowSiteData(bool remember, bool session_expire); + virtual void BlockSiteData(bool remember); + + private: + scoped_refptr<ChromeCookiePolicy> cookie_policy_; + std::string host_; +}; + +void ChromeCookiePolicy::PromptDelegate::AllowSiteData(bool remember, + bool session_expire) { + int policy = net::OK; + if (session_expire) + policy = net::OK_FOR_SESSION_ONLY; + cookie_policy_->DidPromptForSetCookie(host_, policy, remember); +} + +void ChromeCookiePolicy::PromptDelegate::BlockSiteData(bool remember) { + cookie_policy_->DidPromptForSetCookie(host_, net::ERR_ACCESS_DENIED, + remember); +} + +// ---------------------------------------------------------------------------- + ChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map) : host_content_settings_map_(map) { } @@ -27,6 +64,8 @@ ChromeCookiePolicy::~ChromeCookiePolicy() { int ChromeCookiePolicy::CanGetCookies(const GURL& url, const GURL& first_party, net::CompletionCallback* callback) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + if (host_content_settings_map_->BlockThirdPartyCookies()) { net::StaticCookiePolicy policy( net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES); @@ -37,36 +76,33 @@ int ChromeCookiePolicy::CanGetCookies(const GURL& url, const std::string& host = url.host(); - ContentSetting setting = host_content_settings_map_->GetContentSetting( - host, CONTENT_SETTINGS_TYPE_COOKIES); - if (setting == CONTENT_SETTING_BLOCK) - return net::ERR_ACCESS_DENIED; - if (setting == CONTENT_SETTING_ALLOW) - return net::OK; + int policy = CheckPolicy(host); + if (policy != net::ERR_IO_PENDING) + return policy; DCHECK(callback); // If we are currently prompting the user for a 'set-cookie' matching this // host, then we need to defer reading cookies. - HostCompletionsMap::iterator it = host_completions_map_.find(host); - if (it == host_completions_map_.end()) - return net::OK; - - if (it->second.size() >= kMaxCompletionsPerHost) { + if (it == host_completions_map_.end()) { + policy = net::OK; + } else if (it->second.size() >= kMaxCompletionsPerHost) { LOG(ERROR) << "Would exceed kMaxCompletionsPerHost"; - return net::ERR_ACCESS_DENIED; + policy = net::ERR_ACCESS_DENIED; + } else { + it->second.push_back(Completion::ForGetCookies(callback)); + policy = net::ERR_IO_PENDING; } - - it->second.push_back(Completion::ForGetCookies(callback)); - - return net::ERR_IO_PENDING; + return policy; } int ChromeCookiePolicy::CanSetCookie(const GURL& url, const GURL& first_party, const std::string& cookie_line, net::CompletionCallback* callback) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + if (host_content_settings_map_->BlockThirdPartyCookies()) { net::StaticCookiePolicy policy( net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES); @@ -77,12 +113,9 @@ int ChromeCookiePolicy::CanSetCookie(const GURL& url, const std::string& host = url.host(); - ContentSetting setting = host_content_settings_map_->GetContentSetting( - host, CONTENT_SETTINGS_TYPE_COOKIES); - if (setting == CONTENT_SETTING_BLOCK) - return net::ERR_ACCESS_DENIED; - if (setting == CONTENT_SETTING_ALLOW) - return net::OK; + int policy = CheckPolicy(host); + if (policy != net::ERR_IO_PENDING) + return policy; DCHECK(callback); @@ -92,13 +125,56 @@ int ChromeCookiePolicy::CanSetCookie(const GURL& url, if (completions.size() >= kMaxCompletionsPerHost) { LOG(ERROR) << "Would exceed kMaxCompletionsPerHost"; + policy = net::ERR_ACCESS_DENIED; + } else { + completions.push_back(Completion::ForSetCookie(callback)); + policy = net::ERR_IO_PENDING; + } + + PromptForSetCookie(host, cookie_line); + return policy; +} + +int ChromeCookiePolicy::CheckPolicy(const std::string& host) const { + ContentSetting setting = host_content_settings_map_->GetContentSetting( + host, CONTENT_SETTINGS_TYPE_COOKIES); + if (setting == CONTENT_SETTING_BLOCK) return net::ERR_ACCESS_DENIED; + if (setting == CONTENT_SETTING_ALLOW) + return net::OK; + return net::ERR_IO_PENDING; // Need to prompt. +} + +void ChromeCookiePolicy::ShowNextPrompt() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + if (prompt_queue_.empty()) + return; + PromptData data = prompt_queue_.front(); + + // The policy may have changed (due to the "remember" option). + int policy = CheckPolicy(data.host); + if (policy != net::ERR_IO_PENDING) { + DidPromptForSetCookie(data.host, policy, false); + return; } - completions.push_back(Completion::ForSetCookie(callback)); + // Show the prompt on top of the current tab. + Browser* browser = BrowserList::GetLastActive(); + if (!browser || !browser->GetSelectedTabContents()) { + DidPromptForSetCookie(data.host, net::ERR_ACCESS_DENIED, false); + return; + } - PromptForSetCookie(host, cookie_line); - return net::ERR_IO_PENDING; +#if defined(OS_WIN) + RunCookiePrompt(browser->GetSelectedTabContents(), + data.host, + data.cookie_line, + new PromptDelegate(this, data.host)); +#else + // TODO(darin): Enable prompting for other ports. + DidPromptForSetCookie(data.host, net::ERR_ACCESS_DENIED, false); +#endif } void ChromeCookiePolicy::PromptForSetCookie(const std::string &host, @@ -111,27 +187,38 @@ void ChromeCookiePolicy::PromptForSetCookie(const std::string &host, return; } - // TODO(darin): Prompt user! -#if 0 - MessageBox(NULL, - UTF8ToWide(cookie_line).c_str(), - UTF8ToWide(host).c_str(), - MB_OK); -#endif + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - DidPromptForSetCookie(host, net::OK); + bool show_now = prompt_queue_.empty(); + prompt_queue_.push(PromptData(host, cookie_line)); + if (show_now) + ShowNextPrompt(); } void ChromeCookiePolicy::DidPromptForSetCookie(const std::string &host, - int result) { + int policy, bool remember) { if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { + // Process the remember flag immediately. + if (remember) { + ContentSetting content_setting = CONTENT_SETTING_BLOCK; + if (policy == net::OK || policy == net::OK_FOR_SESSION_ONLY) + content_setting = CONTENT_SETTING_ALLOW; + host_content_settings_map_->SetContentSetting( + host, CONTENT_SETTINGS_TYPE_COOKIES, content_setting); + } + ChromeThread::PostTask( ChromeThread::IO, FROM_HERE, NewRunnableMethod(this, &ChromeCookiePolicy::DidPromptForSetCookie, - host, result)); + host, policy, remember)); + + prompt_queue_.pop(); + ShowNextPrompt(); return; } + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + // Notify all callbacks, starting with the first until we hit another that // is for a 'set-cookie'. HostCompletionsMap::iterator it = host_completions_map_.find(host); @@ -158,5 +245,5 @@ void ChromeCookiePolicy::DidPromptForSetCookie(const std::string &host, host_completions_map_.erase(it); for (size_t j = 0; j < callbacks.size(); ++j) - callbacks[j]->Run(result); + callbacks[j]->Run(policy); } diff --git a/chrome/browser/net/chrome_cookie_policy.h b/chrome/browser/net/chrome_cookie_policy.h index 0d536f8..6b4d675 100644 --- a/chrome/browser/net/chrome_cookie_policy.h +++ b/chrome/browser/net/chrome_cookie_policy.h @@ -6,6 +6,8 @@ #define CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_ #include <map> +#include <queue> +#include <string> #include <vector> #include "base/ref_counted.h" @@ -35,6 +37,9 @@ class ChromeCookiePolicy net::CompletionCallback* callback); private: + class PromptDelegate; + friend class PromptDelegate; + class Completion { public: static Completion ForSetCookie(net::CompletionCallback* callback) { @@ -57,17 +62,37 @@ class ChromeCookiePolicy bool is_set_cookie_request_; net::CompletionCallback* callback_; }; - typedef std::vector<Completion> Completions; typedef std::map<std::string, Completions> HostCompletionsMap; + struct PromptData { + std::string host; + std::string cookie_line; + + PromptData(const std::string& host, const std::string& cookie_line) + : host(host), + cookie_line(cookie_line) { + } + }; + typedef std::queue<PromptData> PromptQueue; + + int CheckPolicy(const std::string& host) const; + void ShowNextPrompt(); void PromptForSetCookie(const std::string& host, const std::string& cookie_line); - void DidPromptForSetCookie(const std::string& host, int result); + void DidPromptForSetCookie(const std::string& host, int result, + bool remember); // A map from hostname to callbacks awaiting a cookie policy response. + // This map is only accessed on the IO thread. HostCompletionsMap host_completions_map_; + // A queue of pending prompts. We queue these up here so that before showing + // the next prompt we can reconsult the HostContentSettingsMap in case + // settings have changed since the prompt request was placed in the queue. + // This queue is only accessed on the UI thread. + PromptQueue prompt_queue_; + scoped_refptr<HostContentSettingsMap> host_content_settings_map_; }; |