diff options
author | davidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-02 21:26:11 +0000 |
---|---|---|
committer | davidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-02 21:26:11 +0000 |
commit | 4a729ae7ff3f615214d2120a2218a5bef4742c58 (patch) | |
tree | 0b1adbf4970808323a2c564abd58780bf3f87c71 /chrome/browser/tab_contents | |
parent | 0107dbdf9eaa3d5c60d070c1ccfaee2972bdfec3 (diff) | |
download | chromium_src-4a729ae7ff3f615214d2120a2218a5bef4742c58.zip chromium_src-4a729ae7ff3f615214d2120a2218a5bef4742c58.tar.gz chromium_src-4a729ae7ff3f615214d2120a2218a5bef4742c58.tar.bz2 |
Display an infobar after enrolling a client certificate
This gives the user some feedback that we added a certificate.
R=wtc,brettw
TEST=none
BUG=50782
Review URL: http://codereview.chromium.org/2815023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54602 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tab_contents')
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_ssl_helper.cc | 198 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_ssl_helper.h | 18 |
2 files changed, 216 insertions, 0 deletions
diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc index 0f00d1e..90041d9 100644 --- a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc +++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc @@ -4,9 +4,155 @@ #include "chrome/browser/tab_contents/tab_contents_ssl_helper.h" +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/basictypes.h" +#include "base/string_number_conversions.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/certificate_viewer.h" +#include "chrome/browser/ssl/ssl_add_cert_handler.h" #include "chrome/browser/ssl/ssl_client_auth_handler.h" #include "chrome/browser/ssl_client_certificate_selector.h" +#include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/notification_service.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "net/base/net_errors.h" + +namespace { + +SkBitmap* GetCertIcon() { + // TODO(davidben): use a more appropriate icon. + return ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_INFOBAR_SAVE_PASSWORD); +} + +class SSLCertAddedInfoBarDelegate : public ConfirmInfoBarDelegate { + public: + SSLCertAddedInfoBarDelegate(TabContents* tab_contents, + net::X509Certificate* cert) + : ConfirmInfoBarDelegate(tab_contents), + tab_contents_(tab_contents), + cert_(cert) { + } + + virtual ~SSLCertAddedInfoBarDelegate() { + } + + // Overridden from ConfirmInfoBarDelegate: + virtual std::wstring GetMessageText() const { + return l10n_util::GetStringF(IDS_ADD_CERT_SUCCESS_INFOBAR_LABEL, + UTF8ToWide(cert_->issuer().GetDisplayName())); + } + + virtual SkBitmap* GetIcon() const { + return GetCertIcon(); + } + + virtual int GetButtons() const { + return BUTTON_OK; + } + + virtual std::wstring GetButtonLabel(InfoBarButton button) const { + switch (button) { + case BUTTON_OK: + return l10n_util::GetString(IDS_ADD_CERT_SUCCESS_INFOBAR_BUTTON); + default: + return std::wstring(); + } + } + + virtual Type GetInfoBarType() { + return PAGE_ACTION_TYPE; + } + + virtual bool Accept() { + ShowCertificateViewer(tab_contents_->GetMessageBoxRootWindow(), cert_); + return false; // Hiding the infobar just as the dialog opens looks weird. + } + + virtual void InfoBarClosed() { + // ConfirmInfoBarDelegate doesn't delete itself. + delete this; + } + + private: + // The TabContents we are attached to + TabContents* tab_contents_; + // The cert we added. + scoped_refptr<net::X509Certificate> cert_; +}; + +} // namespace + +class TabContentsSSLHelper::SSLAddCertData : public NotificationObserver { + public: + SSLAddCertData(TabContents* tab, SSLAddCertHandler* handler) + : tab_(tab), + handler_(handler), + infobar_delegate_(NULL) { + // Listen for disappearing InfoBars. + Source<TabContents> tc_source(tab_); + registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, + tc_source); + registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, + tc_source); + } + ~SSLAddCertData() {} + + // Displays |delegate| as an infobar in |tab_|, replacing our current one if + // still active. + void ShowInfoBar(InfoBarDelegate* delegate) { + if (infobar_delegate_) { + tab_->ReplaceInfoBar(infobar_delegate_, delegate); + } else { + tab_->AddInfoBar(delegate); + } + infobar_delegate_ = delegate; + } + + void ShowErrorInfoBar(const std::wstring& message) { + ShowInfoBar( + new SimpleAlertInfoBarDelegate(tab_, message, GetCertIcon(), true)); + } + + // NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + switch (type.value) { + case NotificationType::TAB_CONTENTS_INFOBAR_REMOVED: + InfoBarClosed(Details<InfoBarDelegate>(details).ptr()); + break; + case NotificationType::TAB_CONTENTS_INFOBAR_REPLACED: + typedef std::pair<InfoBarDelegate*, InfoBarDelegate*> + InfoBarDelegatePair; + InfoBarClosed(Details<InfoBarDelegatePair>(details).ptr()->first); + break; + default: + NOTREACHED(); + break; + } + } + + private: + void InfoBarClosed(InfoBarDelegate* delegate) { + if (infobar_delegate_ == delegate) + infobar_delegate_ = NULL; + } + + // The TabContents we are attached to. + TabContents* tab_; + // The handler we call back to. + scoped_refptr<SSLAddCertHandler> handler_; + // The current InfoBarDelegate we're displaying. + InfoBarDelegate* infobar_delegate_; + + NotificationRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(SSLAddCertData); +}; TabContentsSSLHelper::TabContentsSSLHelper(TabContents* tab_contents) : tab_contents_(tab_contents) { @@ -22,3 +168,55 @@ void TabContentsSSLHelper::ShowClientCertificateRequestDialog( tab_contents_->GetMessageBoxRootWindow(), handler->cert_request_info(), handler); } + +void TabContentsSSLHelper::OnVerifyClientCertificateError( + scoped_refptr<SSLAddCertHandler> handler, int error_code) { + SSLAddCertData* add_cert_data = GetAddCertData(handler); + // Display an infobar with the error message. + // TODO(davidben): Display a more user-friendly error string. + add_cert_data->ShowErrorInfoBar( + l10n_util::GetStringF(IDS_ADD_CERT_ERR_INVALID_CERT, + UTF8ToWide(base::IntToString(-error_code)), + ASCIIToWide(net::ErrorToString(error_code)))); +} + +void TabContentsSSLHelper::AskToAddClientCertificate( + scoped_refptr<SSLAddCertHandler> handler) { + NOTREACHED(); // Not implemented yet. +} + +void TabContentsSSLHelper::OnAddClientCertificateSuccess( + scoped_refptr<SSLAddCertHandler> handler) { + SSLAddCertData* add_cert_data = GetAddCertData(handler); + // Display an infobar to inform the user. + add_cert_data->ShowInfoBar( + new SSLCertAddedInfoBarDelegate(tab_contents_, handler->cert())); +} + +void TabContentsSSLHelper::OnAddClientCertificateError( + scoped_refptr<SSLAddCertHandler> handler, int error_code) { + SSLAddCertData* add_cert_data = GetAddCertData(handler); + // Display an infobar with the error message. + // TODO(davidben): Display a more user-friendly error string. + add_cert_data->ShowErrorInfoBar( + l10n_util::GetStringF(IDS_ADD_CERT_ERR_FAILED, + UTF8ToWide(base::IntToString(-error_code)), + ASCIIToWide(net::ErrorToString(error_code)))); +} + +void TabContentsSSLHelper::OnAddClientCertificateFinished( + scoped_refptr<SSLAddCertHandler> handler) { + // Clean up. + request_id_to_add_cert_data_.erase(handler->network_request_id()); +} + +TabContentsSSLHelper::SSLAddCertData* TabContentsSSLHelper::GetAddCertData( + SSLAddCertHandler* handler) { + // Find/create the slot. + linked_ptr<SSLAddCertData>& ptr_ref = + request_id_to_add_cert_data_[handler->network_request_id()]; + // Fill it if necessary. + if (!ptr_ref.get()) + ptr_ref.reset(new SSLAddCertData(tab_contents_, handler)); + return ptr_ref.get(); +} diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.h b/chrome/browser/tab_contents/tab_contents_ssl_helper.h index 682829ab..9233561 100644 --- a/chrome/browser/tab_contents/tab_contents_ssl_helper.h +++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.h @@ -6,6 +6,9 @@ #define CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_SSL_HELPER_H_ #pragma once +#include <map> + +#include "base/linked_ptr.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" class SSLClientAuthHandler; @@ -19,10 +22,25 @@ class TabContentsSSLHelper : public RenderViewHostDelegate::SSL { // RenderViewHostDelegate::SSL implementation: virtual void ShowClientCertificateRequestDialog( scoped_refptr<SSLClientAuthHandler> handler); + virtual void OnVerifyClientCertificateError( + scoped_refptr<SSLAddCertHandler> handler, int error_code); + virtual void AskToAddClientCertificate( + scoped_refptr<SSLAddCertHandler> handler); + virtual void OnAddClientCertificateSuccess( + scoped_refptr<SSLAddCertHandler> handler); + virtual void OnAddClientCertificateError( + scoped_refptr<SSLAddCertHandler> handler, int error_code); + virtual void OnAddClientCertificateFinished( + scoped_refptr<SSLAddCertHandler> handler); private: TabContents* tab_contents_; + class SSLAddCertData; + std::map<int, linked_ptr<SSLAddCertData> > request_id_to_add_cert_data_; + + SSLAddCertData* GetAddCertData(SSLAddCertHandler *handler); + DISALLOW_COPY_AND_ASSIGN(TabContentsSSLHelper); }; |