Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "chrome/browser/ui/views/ssl_client_certificate_selector.h" | 5 #include "chrome/browser/ui/views/certificate_selector.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | |
| 8 #include "base/logging.h" | 7 #include "base/logging.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/certificate_viewer.h" | 9 #include "chrome/browser/certificate_viewer.h" |
| 11 #include "chrome/grit/generated_resources.h" | 10 #include "chrome/grit/generated_resources.h" |
| 12 #include "components/constrained_window/constrained_window_views.h" | 11 #include "components/constrained_window/constrained_window_views.h" |
| 13 #include "content/public/browser/browser_thread.h" | |
| 14 #include "content/public/browser/web_contents.h" | 12 #include "content/public/browser/web_contents.h" |
| 15 #include "net/cert/x509_certificate.h" | 13 #include "net/cert/x509_certificate.h" |
| 16 #include "net/ssl/ssl_cert_request_info.h" | |
| 17 #include "ui/base/l10n/l10n_util.h" | 14 #include "ui/base/l10n/l10n_util.h" |
| 18 #include "ui/base/models/table_model.h" | 15 #include "ui/base/models/table_model.h" |
| 19 #include "ui/base/models/table_model_observer.h" | 16 #include "ui/base/models/table_model_observer.h" |
| 20 #include "ui/views/controls/button/label_button.h" | 17 #include "ui/views/controls/button/label_button.h" |
| 21 #include "ui/views/controls/label.h" | 18 #include "ui/views/controls/label.h" |
| 22 #include "ui/views/controls/table/table_view.h" | 19 #include "ui/views/controls/table/table_view.h" |
| 23 #include "ui/views/layout/grid_layout.h" | 20 #include "ui/views/layout/grid_layout.h" |
| 24 #include "ui/views/layout/layout_constants.h" | 21 #include "ui/views/layout/layout_constants.h" |
| 25 #include "ui/views/widget/widget.h" | 22 #include "ui/views/widget/widget.h" |
| 26 #include "ui/views/window/dialog_client_view.h" | 23 #include "ui/views/window/dialog_client_view.h" |
| 27 | 24 |
| 28 #if defined(USE_NSS) | 25 namespace chrome { |
|
davidben
2015/02/18 20:32:01
To confirm: is //chrome namespaced these days? I r
pneubeck (no reviews)
2015/02/19 15:12:24
I found a few places that use 'namespace chrome'.
| |
| 29 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h" | |
| 30 #endif | |
| 31 | 26 |
| 32 /////////////////////////////////////////////////////////////////////////////// | 27 class CertificateSelector::CertificateTableModel : public ui::TableModel { |
| 33 // CertificateSelectorTableModel: | |
| 34 | |
| 35 class CertificateSelectorTableModel : public ui::TableModel { | |
| 36 public: | 28 public: |
| 37 explicit CertificateSelectorTableModel( | 29 explicit CertificateTableModel(const net::CertificateList& certificates); |
| 38 net::SSLCertRequestInfo* cert_request_info); | |
| 39 | 30 |
| 40 // ui::TableModel implementation: | 31 // ui::TableModel implementation: |
| 41 int RowCount() override; | 32 int RowCount() override; |
| 42 base::string16 GetText(int index, int column_id) override; | 33 base::string16 GetText(int index, int column_id) override; |
| 43 void SetObserver(ui::TableModelObserver* observer) override; | 34 void SetObserver(ui::TableModelObserver* observer) override; |
| 44 | 35 |
| 45 private: | 36 private: |
| 46 std::vector<base::string16> items_; | 37 std::vector<base::string16> items_; |
| 47 | 38 |
| 48 DISALLOW_COPY_AND_ASSIGN(CertificateSelectorTableModel); | 39 DISALLOW_COPY_AND_ASSIGN(CertificateTableModel); |
| 49 }; | 40 }; |
| 50 | 41 |
| 51 CertificateSelectorTableModel::CertificateSelectorTableModel( | 42 CertificateSelector::CertificateTableModel::CertificateTableModel( |
| 52 net::SSLCertRequestInfo* cert_request_info) { | 43 const net::CertificateList& certificates) { |
| 53 for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) { | 44 for (const scoped_refptr<net::X509Certificate>& cert : certificates) { |
| 54 net::X509Certificate* cert = cert_request_info->client_certs[i].get(); | |
| 55 base::string16 text = l10n_util::GetStringFUTF16( | 45 base::string16 text = l10n_util::GetStringFUTF16( |
| 56 IDS_CERT_SELECTOR_TABLE_CERT_FORMAT, | 46 IDS_CERT_SELECTOR_TABLE_CERT_FORMAT, |
| 57 base::UTF8ToUTF16(cert->subject().GetDisplayName()), | 47 base::UTF8ToUTF16(cert->subject().GetDisplayName()), |
| 58 base::UTF8ToUTF16(cert->issuer().GetDisplayName())); | 48 base::UTF8ToUTF16(cert->issuer().GetDisplayName())); |
| 59 items_.push_back(text); | 49 items_.push_back(text); |
| 60 } | 50 } |
| 61 } | 51 } |
| 62 | 52 |
| 63 int CertificateSelectorTableModel::RowCount() { | 53 int CertificateSelector::CertificateTableModel::RowCount() { |
| 64 return items_.size(); | 54 return items_.size(); |
| 65 } | 55 } |
| 66 | 56 |
| 67 base::string16 CertificateSelectorTableModel::GetText(int index, | 57 base::string16 CertificateSelector::CertificateTableModel::GetText( |
| 68 int column_id) { | 58 int index, |
| 59 int column_id) { | |
| 69 DCHECK_EQ(column_id, 0); | 60 DCHECK_EQ(column_id, 0); |
| 70 DCHECK_GE(index, 0); | 61 DCHECK_GE(index, 0); |
| 71 DCHECK_LT(index, static_cast<int>(items_.size())); | 62 DCHECK_LT(index, static_cast<int>(items_.size())); |
| 72 | 63 |
| 73 return items_[index]; | 64 return items_[index]; |
| 74 } | 65 } |
| 75 | 66 |
| 76 void CertificateSelectorTableModel::SetObserver( | 67 void CertificateSelector::CertificateTableModel::SetObserver( |
| 77 ui::TableModelObserver* observer) { | 68 ui::TableModelObserver* observer) { |
| 78 } | 69 } |
| 79 | 70 |
| 80 /////////////////////////////////////////////////////////////////////////////// | 71 CertificateSelector::CertificateSelector( |
| 81 // SSLClientCertificateSelector: | |
| 82 | |
| 83 SSLClientCertificateSelector::SSLClientCertificateSelector( | |
| 84 content::WebContents* web_contents, | 72 content::WebContents* web_contents, |
| 85 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, | 73 const net::CertificateList& certificates, |
| 86 const chrome::SelectCertificateCallback& callback) | 74 const SelectCertificateCallback& callback) |
| 87 : SSLClientAuthObserver(web_contents->GetBrowserContext(), | 75 : certificates_(certificates), |
| 88 cert_request_info, callback), | 76 callback_(callback), |
| 89 model_(new CertificateSelectorTableModel(cert_request_info.get())), | 77 model_(new CertificateTableModel(certificates)), |
| 90 web_contents_(web_contents), | 78 web_contents_(web_contents), |
| 91 table_(NULL), | 79 table_(nullptr), |
| 92 view_cert_button_(NULL) { | 80 view_cert_button_(nullptr) { |
| 93 DVLOG(1) << __FUNCTION__; | 81 DVLOG(1) << __FUNCTION__; |
| 94 } | 82 } |
| 95 | 83 |
| 96 SSLClientCertificateSelector::~SSLClientCertificateSelector() { | 84 CertificateSelector::~CertificateSelector() { |
| 97 table_->SetModel(NULL); | 85 table_->SetModel(nullptr); |
| 98 } | 86 } |
| 99 | 87 |
| 100 void SSLClientCertificateSelector::Init() { | 88 void CertificateSelector::Init(const base::string16& text) { |
| 101 views::GridLayout* layout = views::GridLayout::CreatePanel(this); | 89 views::GridLayout* layout = views::GridLayout::CreatePanel(this); |
| 102 SetLayoutManager(layout); | 90 SetLayoutManager(layout); |
| 103 | 91 |
| 104 const int column_set_id = 0; | 92 const int column_set_id = 0; |
| 105 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); | 93 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); |
| 106 column_set->AddColumn( | 94 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, |
| 107 views::GridLayout::FILL, views::GridLayout::FILL, | 95 views::GridLayout::USE_PREF, 0, 0); |
| 108 1, views::GridLayout::USE_PREF, 0, 0); | |
| 109 | 96 |
| 110 layout->StartRow(0, column_set_id); | 97 layout->StartRow(0, column_set_id); |
| 111 base::string16 text = l10n_util::GetStringFUTF16( | |
| 112 IDS_CLIENT_CERT_DIALOG_TEXT, | |
| 113 base::ASCIIToUTF16(cert_request_info()->host_and_port.ToString())); | |
| 114 views::Label* label = new views::Label(text); | 98 views::Label* label = new views::Label(text); |
| 115 label->SetMultiLine(true); | 99 label->SetMultiLine(true); |
| 116 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 100 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 117 label->SetAllowCharacterBreak(true); | 101 label->SetAllowCharacterBreak(true); |
| 118 layout->AddView(label); | 102 layout->AddView(label); |
| 119 | 103 |
| 120 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 104 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 121 | 105 |
| 122 // The dimensions of the certificate selector table view, in pixels. | 106 // The dimensions of the certificate selector table view, in pixels. |
| 123 static const int kTableViewWidth = 400; | 107 static const int kTableViewWidth = 400; |
| 124 static const int kTableViewHeight = 100; | 108 static const int kTableViewHeight = 100; |
| 125 | 109 |
| 126 CreateCertTable(); | 110 CreateCertTable(); |
| 127 layout->StartRow(1, column_set_id); | 111 layout->StartRow(1, column_set_id); |
| 128 layout->AddView(table_->CreateParentIfNecessary(), 1, 1, | 112 layout->AddView(table_->CreateParentIfNecessary(), 1, 1, |
| 129 views::GridLayout::FILL, | 113 views::GridLayout::FILL, views::GridLayout::FILL, |
| 130 views::GridLayout::FILL, kTableViewWidth, kTableViewHeight); | 114 kTableViewWidth, kTableViewHeight); |
| 131 | 115 |
| 132 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 116 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 133 | 117 |
| 134 StartObserving(); | |
| 135 | |
| 136 constrained_window::ShowWebModalDialogViews(this, web_contents_); | 118 constrained_window::ShowWebModalDialogViews(this, web_contents_); |
| 137 | 119 |
| 138 // Select the first row automatically. This must be done after the dialog has | 120 // Select the first row automatically. This must be done after the dialog has |
| 139 // been created. | 121 // been created. |
| 140 table_->Select(0); | 122 table_->Select(0); |
| 141 } | 123 } |
| 142 | 124 |
| 143 net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() const { | 125 net::X509Certificate* CertificateSelector::GetSelectedCert() const { |
| 144 int selected = table_->FirstSelectedRow(); | 126 int selected = table_->FirstSelectedRow(); |
| 145 if (selected >= 0 && | 127 if (selected >= 0 && selected < static_cast<int>(certificates_.size())) |
| 146 selected < static_cast<int>(cert_request_info()->client_certs.size())) | 128 return certificates_[selected].get(); |
| 147 return cert_request_info()->client_certs[selected].get(); | 129 return nullptr; |
| 148 return NULL; | |
| 149 } | 130 } |
| 150 | 131 |
| 151 /////////////////////////////////////////////////////////////////////////////// | 132 bool CertificateSelector::CanResize() const { |
| 152 // SSLClientAuthObserver implementation: | |
| 153 | |
| 154 void SSLClientCertificateSelector::OnCertSelectedByNotification() { | |
| 155 DVLOG(1) << __FUNCTION__; | |
| 156 GetWidget()->Close(); | |
| 157 } | |
| 158 | |
| 159 /////////////////////////////////////////////////////////////////////////////// | |
| 160 // DialogDelegateView implementation: | |
| 161 | |
| 162 bool SSLClientCertificateSelector::CanResize() const { | |
| 163 return true; | 133 return true; |
| 164 } | 134 } |
| 165 | 135 |
| 166 base::string16 SSLClientCertificateSelector::GetWindowTitle() const { | 136 base::string16 CertificateSelector::GetWindowTitle() const { |
| 167 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE); | 137 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE); |
| 168 } | 138 } |
| 169 | 139 |
| 170 void SSLClientCertificateSelector::DeleteDelegate() { | 140 void CertificateSelector::DeleteDelegate() { |
| 171 DVLOG(1) << __FUNCTION__; | 141 DVLOG(1) << __FUNCTION__; |
| 172 delete this; | 142 delete this; |
| 173 } | 143 } |
| 174 | 144 |
| 175 bool SSLClientCertificateSelector::IsDialogButtonEnabled( | 145 bool CertificateSelector::IsDialogButtonEnabled(ui::DialogButton button) const { |
| 176 ui::DialogButton button) const { | |
| 177 if (button == ui::DIALOG_BUTTON_OK) | 146 if (button == ui::DIALOG_BUTTON_OK) |
| 178 return !!GetSelectedCert(); | 147 return GetSelectedCert() != nullptr; |
| 179 return true; | 148 return true; |
| 180 } | 149 } |
| 181 | 150 |
| 182 bool SSLClientCertificateSelector::Cancel() { | 151 bool CertificateSelector::Cancel() { |
| 183 DVLOG(1) << __FUNCTION__; | 152 DVLOG(1) << __FUNCTION__; |
| 184 StopObserving(); | 153 callback_.Run(nullptr); |
| 185 CertificateSelected(NULL); | |
| 186 return true; | 154 return true; |
| 187 } | 155 } |
| 188 | 156 |
| 189 bool SSLClientCertificateSelector::Accept() { | 157 bool CertificateSelector::Accept() { |
| 190 DVLOG(1) << __FUNCTION__; | 158 DVLOG(1) << __FUNCTION__; |
| 191 scoped_refptr<net::X509Certificate> cert = GetSelectedCert(); | 159 scoped_refptr<net::X509Certificate> cert = GetSelectedCert(); |
| 192 if (cert.get()) { | 160 if (!cert.get()) |
| 193 // Remove the observer before we try unlocking, otherwise we might act on a | 161 return false; |
| 194 // notification while waiting for the unlock dialog, causing us to delete | |
| 195 // ourself before the Unlocked callback gets called. | |
| 196 StopObserving(); | |
| 197 #if defined(USE_NSS) | |
| 198 chrome::UnlockCertSlotIfNecessary( | |
| 199 cert.get(), | |
| 200 chrome::kCryptoModulePasswordClientAuth, | |
| 201 cert_request_info()->host_and_port, | |
| 202 GetWidget()->GetNativeView(), | |
| 203 base::Bind(&SSLClientCertificateSelector::Unlocked, | |
| 204 base::Unretained(this), | |
| 205 cert)); | |
| 206 #else | |
| 207 Unlocked(cert.get()); | |
| 208 #endif | |
| 209 return false; // Unlocked() will close the dialog. | |
| 210 } | |
| 211 | 162 |
| 212 return false; | 163 callback_.Run(cert); |
| 164 return true; | |
| 213 } | 165 } |
| 214 | 166 |
| 215 views::View* SSLClientCertificateSelector::GetInitiallyFocusedView() { | 167 views::View* CertificateSelector::GetInitiallyFocusedView() { |
| 216 return table_; | 168 return table_; |
| 217 } | 169 } |
| 218 | 170 |
| 219 views::View* SSLClientCertificateSelector::CreateExtraView() { | 171 views::View* CertificateSelector::CreateExtraView() { |
| 220 DCHECK(!view_cert_button_); | 172 DCHECK(!view_cert_button_); |
| 221 view_cert_button_ = new views::LabelButton(this, | 173 view_cert_button_ = new views::LabelButton( |
| 222 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)); | 174 this, l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)); |
| 223 view_cert_button_->SetStyle(views::Button::STYLE_BUTTON); | 175 view_cert_button_->SetStyle(views::Button::STYLE_BUTTON); |
| 224 return view_cert_button_; | 176 return view_cert_button_; |
| 225 } | 177 } |
| 226 | 178 |
| 227 ui::ModalType SSLClientCertificateSelector::GetModalType() const { | 179 ui::ModalType CertificateSelector::GetModalType() const { |
| 228 return ui::MODAL_TYPE_CHILD; | 180 return ui::MODAL_TYPE_CHILD; |
| 229 } | 181 } |
| 230 | 182 |
| 231 /////////////////////////////////////////////////////////////////////////////// | 183 void CertificateSelector::ButtonPressed(views::Button* sender, |
| 232 // views::ButtonListener implementation: | 184 const ui::Event& event) { |
| 233 | |
| 234 void SSLClientCertificateSelector::ButtonPressed( | |
| 235 views::Button* sender, const ui::Event& event) { | |
| 236 if (sender == view_cert_button_) { | 185 if (sender == view_cert_button_) { |
| 237 net::X509Certificate* cert = GetSelectedCert(); | 186 net::X509Certificate* cert = GetSelectedCert(); |
| 238 if (cert) | 187 if (cert) |
| 239 ShowCertificateViewer(web_contents_, | 188 ShowCertificateViewer(web_contents_, |
| 240 web_contents_->GetTopLevelNativeWindow(), | 189 web_contents_->GetTopLevelNativeWindow(), cert); |
| 241 cert); | |
| 242 } | 190 } |
| 243 } | 191 } |
| 244 | 192 |
| 245 /////////////////////////////////////////////////////////////////////////////// | 193 void CertificateSelector::OnSelectionChanged() { |
| 246 // views::TableViewObserver implementation: | 194 GetDialogClientView()->ok_button()->SetEnabled(GetSelectedCert() != nullptr); |
| 247 void SSLClientCertificateSelector::OnSelectionChanged() { | |
| 248 GetDialogClientView()->ok_button()->SetEnabled(!!GetSelectedCert()); | |
| 249 } | 195 } |
| 250 | 196 |
| 251 void SSLClientCertificateSelector::OnDoubleClick() { | 197 void CertificateSelector::OnDoubleClick() { |
| 252 if (Accept()) | 198 if (Accept()) |
| 253 GetWidget()->Close(); | 199 GetWidget()->Close(); |
| 254 } | 200 } |
| 255 | 201 |
| 256 /////////////////////////////////////////////////////////////////////////////// | 202 void CertificateSelector::CreateCertTable() { |
| 257 // SSLClientCertificateSelector private methods: | |
| 258 | |
| 259 void SSLClientCertificateSelector::CreateCertTable() { | |
| 260 std::vector<ui::TableColumn> columns; | 203 std::vector<ui::TableColumn> columns; |
| 261 columns.push_back(ui::TableColumn()); | 204 columns.push_back(ui::TableColumn()); |
| 262 table_ = new views::TableView(model_.get(), columns, views::TEXT_ONLY, | 205 table_ = new views::TableView(model_.get(), columns, views::TEXT_ONLY, |
| 263 true /* single_selection */); | 206 true /* single_selection */); |
| 264 table_->SetObserver(this); | 207 table_->SetObserver(this); |
| 265 } | 208 } |
| 266 | 209 |
| 267 void SSLClientCertificateSelector::Unlocked(net::X509Certificate* cert) { | |
| 268 DVLOG(1) << __FUNCTION__; | |
| 269 CertificateSelected(cert); | |
| 270 GetWidget()->Close(); | |
| 271 } | |
| 272 | |
| 273 namespace chrome { | |
| 274 | |
| 275 void ShowSSLClientCertificateSelector( | |
| 276 content::WebContents* contents, | |
| 277 net::SSLCertRequestInfo* cert_request_info, | |
| 278 const chrome::SelectCertificateCallback& callback) { | |
| 279 DVLOG(1) << __FUNCTION__ << " " << contents; | |
| 280 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 281 (new SSLClientCertificateSelector( | |
| 282 contents, cert_request_info, callback))->Init(); | |
| 283 } | |
| 284 | |
| 285 } // namespace chrome | 210 } // namespace chrome |
| OLD | NEW |