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

Side by Side Diff: chrome/browser/ui/views/certificate_selector.cc

Issue 932553002: Refactor SSLClientCertificateSelector for reuse with platformKeys API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert_perms
Patch Set: Addressed comments, some cleanup like const-ness, CHECKs, logging, includes, ... Created 5 years, 10 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 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 {
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: 28 public:
29 explicit CertificateTableModel(const net::CertificateList& certificates);
34 30
35 class CertificateSelectorTableModel : public ui::TableModel { 31 // ui::TableModel:
36 public:
37 explicit CertificateSelectorTableModel(
38 net::SSLCertRequestInfo* cert_request_info);
39
40 // 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) {
bartfab (slow) 2015/02/19 17:53:06 Why not |auto|?
pneubeck (no reviews) 2015/02/19 19:43:51 I find it helpful to document the element type, in
54 net::X509Certificate* cert = cert_request_info->client_certs[i].get(); 45 const base::string16 text = l10n_util::GetStringFUTF16(
msw 2015/02/19 19:53:53 nit: inline this in the push_back call.
pneubeck (no reviews) 2015/02/19 20:43:49 Done.
55 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(static_cast<size_t>(index), 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: 72 const net::CertificateList& certificates,
82 73 content::WebContents* web_contents)
83 SSLClientCertificateSelector::SSLClientCertificateSelector( 74 : certificates_(certificates),
84 content::WebContents* web_contents, 75 model_(new CertificateTableModel(certificates)),
85 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, 76 web_contents_(web_contents) {
86 const chrome::SelectCertificateCallback& callback) 77 CHECK(web_contents_);
87 : SSLClientAuthObserver(web_contents->GetBrowserContext(),
88 cert_request_info, callback),
89 model_(new CertificateSelectorTableModel(cert_request_info.get())),
90 web_contents_(web_contents),
91 table_(NULL),
92 view_cert_button_(NULL) {
93 DVLOG(1) << __FUNCTION__;
94 } 78 }
95 79
96 SSLClientCertificateSelector::~SSLClientCertificateSelector() { 80 CertificateSelector::~CertificateSelector() {
97 table_->SetModel(NULL); 81 table_->SetModel(nullptr);
98 } 82 }
99 83
100 void SSLClientCertificateSelector::Init() { 84 void CertificateSelector::Init(const base::string16& text) {
101 views::GridLayout* layout = views::GridLayout::CreatePanel(this); 85 views::GridLayout* const layout = views::GridLayout::CreatePanel(this);
bartfab (slow) 2015/02/19 17:53:07 Nit: Use a |scoped_ptr| while you are holding owne
pneubeck (no reviews) 2015/02/19 19:43:51 impractical in this case. The ownership is passed
bartfab (slow) 2015/02/20 12:19:47 That super bulky code is what I tend to do :). But
102 SetLayoutManager(layout); 86 SetLayoutManager(layout);
103 87
104 const int column_set_id = 0; 88 const int column_set_id = 0;
bartfab (slow) 2015/02/19 17:53:06 Nit 1: Use are using inconsistent naming for const
pneubeck (no reviews) 2015/02/19 19:43:51 Done.
105 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); 89 views::ColumnSet* const column_set = layout->AddColumnSet(column_set_id);
106 column_set->AddColumn( 90 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
bartfab (slow) 2015/02/19 17:53:06 If you have a single column only, why not use a Bo
pneubeck (no reviews) 2015/02/19 19:43:51 Agreed. I can try that in a follow up. This CL tri
107 views::GridLayout::FILL, views::GridLayout::FILL, 91 views::GridLayout::USE_PREF, 0, 0);
108 1, views::GridLayout::USE_PREF, 0, 0);
109 92
110 layout->StartRow(0, column_set_id); 93 layout->StartRow(0, column_set_id);
111 base::string16 text = l10n_util::GetStringFUTF16( 94 views::Label* const label = new views::Label(text);
bartfab (slow) 2015/02/19 17:53:06 Nit: Use a |scoped_ptr| while you are holding owne
pneubeck (no reviews) 2015/02/19 19:43:51 Done.
112 IDS_CLIENT_CERT_DIALOG_TEXT,
113 base::ASCIIToUTF16(cert_request_info()->host_and_port.ToString()));
114 views::Label* label = new views::Label(text);
115 label->SetMultiLine(true); 95 label->SetMultiLine(true);
116 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 96 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
117 label->SetAllowCharacterBreak(true); 97 label->SetAllowCharacterBreak(true);
118 layout->AddView(label); 98 layout->AddView(label);
119 99
120 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 100 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
121 101
122 // The dimensions of the certificate selector table view, in pixels. 102 // The dimensions of the certificate selector table view, in pixels.
123 static const int kTableViewWidth = 400; 103 static const int kTableViewWidth = 400;
124 static const int kTableViewHeight = 100; 104 static const int kTableViewHeight = 100;
125 105
126 CreateCertTable(); 106 table_ = CreateCertTable();
127 layout->StartRow(1, column_set_id); 107 layout->StartRow(1, column_set_id);
128 layout->AddView(table_->CreateParentIfNecessary(), 1, 1, 108 layout->AddView(table_->CreateParentIfNecessary(), 1, 1,
129 views::GridLayout::FILL, 109 views::GridLayout::FILL, views::GridLayout::FILL,
130 views::GridLayout::FILL, kTableViewWidth, kTableViewHeight); 110 kTableViewWidth, kTableViewHeight);
131 111
132 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 112 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
133 113
134 StartObserving();
135
136 constrained_window::ShowWebModalDialogViews(this, web_contents_); 114 constrained_window::ShowWebModalDialogViews(this, web_contents_);
137 115
138 // Select the first row automatically. This must be done after the dialog has 116 // Select the first row automatically. This must be done after the dialog has
139 // been created. 117 // been created.
140 table_->Select(0); 118 table_->Select(0);
141 } 119 }
142 120
143 net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() const { 121 net::X509Certificate* CertificateSelector::GetSelectedCert() const {
144 int selected = table_->FirstSelectedRow(); 122 const int selected = table_->FirstSelectedRow();
145 if (selected >= 0 && 123 if (selected >= 0 && static_cast<size_t>(selected) < certificates_.size())
msw 2015/02/19 19:53:53 We should be able to [D]CHECK_LT(selected, certifi
pneubeck (no reviews) 2015/02/19 20:43:49 A call before Init() will crash because of table_
146 selected < static_cast<int>(cert_request_info()->client_certs.size())) 124 return certificates_[selected].get();
147 return cert_request_info()->client_certs[selected].get(); 125 return nullptr;
148 return NULL;
149 } 126 }
150 127
151 /////////////////////////////////////////////////////////////////////////////// 128 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; 129 return true;
164 } 130 }
165 131
166 base::string16 SSLClientCertificateSelector::GetWindowTitle() const { 132 base::string16 CertificateSelector::GetWindowTitle() const {
167 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE); 133 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE);
168 } 134 }
169 135
170 void SSLClientCertificateSelector::DeleteDelegate() { 136 void CertificateSelector::DeleteDelegate() {
171 DVLOG(1) << __FUNCTION__; 137 DVLOG(1) << __FUNCTION__;
bartfab (slow) 2015/02/19 17:53:06 Do we expect crashes around this line?
pneubeck (no reviews) 2015/02/19 19:43:51 I don't know, kept this from the SSLClientCertific
msw 2015/02/19 19:53:53 If not, this override isn't needed. DialogDelegate
pneubeck (no reviews) 2015/02/19 20:43:49 good point. removed.
172 delete this; 138 delete this;
173 } 139 }
174 140
175 bool SSLClientCertificateSelector::IsDialogButtonEnabled( 141 bool CertificateSelector::IsDialogButtonEnabled(ui::DialogButton button) const {
176 ui::DialogButton button) const {
177 if (button == ui::DIALOG_BUTTON_OK) 142 if (button == ui::DIALOG_BUTTON_OK)
msw 2015/02/19 19:53:53 nit: return button != ui::DIALOG_BUTTON_OK || GetS
pneubeck (no reviews) 2015/02/19 20:43:49 Done.
178 return !!GetSelectedCert(); 143 return GetSelectedCert() != nullptr;
179 return true; 144 return true;
180 } 145 }
181 146
182 bool SSLClientCertificateSelector::Cancel() { 147 views::View* CertificateSelector::GetInitiallyFocusedView() {
183 DVLOG(1) << __FUNCTION__; 148 DCHECK(table_);
184 StopObserving();
185 CertificateSelected(NULL);
186 return true;
187 }
188
189 bool SSLClientCertificateSelector::Accept() {
190 DVLOG(1) << __FUNCTION__;
191 scoped_refptr<net::X509Certificate> cert = GetSelectedCert();
192 if (cert.get()) {
193 // Remove the observer before we try unlocking, otherwise we might act on a
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
212 return false;
213 }
214
215 views::View* SSLClientCertificateSelector::GetInitiallyFocusedView() {
216 return table_; 149 return table_;
217 } 150 }
218 151
219 views::View* SSLClientCertificateSelector::CreateExtraView() { 152 views::View* CertificateSelector::CreateExtraView() {
220 DCHECK(!view_cert_button_); 153 DCHECK(!view_cert_button_);
221 view_cert_button_ = new views::LabelButton(this, 154 view_cert_button_ = new views::LabelButton(
bartfab (slow) 2015/02/19 17:53:06 Nit: Use a |scoped_ptr| while you are holding owne
pneubeck (no reviews) 2015/02/19 19:43:51 Done.
222 l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)); 155 this, l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON));
223 view_cert_button_->SetStyle(views::Button::STYLE_BUTTON); 156 view_cert_button_->SetStyle(views::Button::STYLE_BUTTON);
224 return view_cert_button_; 157 return view_cert_button_;
225 } 158 }
226 159
227 ui::ModalType SSLClientCertificateSelector::GetModalType() const { 160 ui::ModalType CertificateSelector::GetModalType() const {
228 return ui::MODAL_TYPE_CHILD; 161 return ui::MODAL_TYPE_CHILD;
229 } 162 }
230 163
231 /////////////////////////////////////////////////////////////////////////////// 164 void CertificateSelector::ButtonPressed(views::Button* sender,
232 // views::ButtonListener implementation: 165 const ui::Event& event) {
233
234 void SSLClientCertificateSelector::ButtonPressed(
235 views::Button* sender, const ui::Event& event) {
236 if (sender == view_cert_button_) { 166 if (sender == view_cert_button_) {
237 net::X509Certificate* cert = GetSelectedCert(); 167 net::X509Certificate* const cert = GetSelectedCert();
238 if (cert) 168 if (cert)
239 ShowCertificateViewer(web_contents_, 169 ShowCertificateViewer(web_contents_,
240 web_contents_->GetTopLevelNativeWindow(), 170 web_contents_->GetTopLevelNativeWindow(), cert);
241 cert);
242 } 171 }
243 } 172 }
244 173
245 /////////////////////////////////////////////////////////////////////////////// 174 void CertificateSelector::OnSelectionChanged() {
246 // views::TableViewObserver implementation: 175 GetDialogClientView()->ok_button()->SetEnabled(GetSelectedCert() != nullptr);
247 void SSLClientCertificateSelector::OnSelectionChanged() {
248 GetDialogClientView()->ok_button()->SetEnabled(!!GetSelectedCert());
249 } 176 }
250 177
251 void SSLClientCertificateSelector::OnDoubleClick() { 178 void CertificateSelector::OnDoubleClick() {
252 if (Accept()) 179 if (Accept())
253 GetWidget()->Close(); 180 GetWidget()->Close();
254 } 181 }
255 182
256 /////////////////////////////////////////////////////////////////////////////// 183 views::TableView* CertificateSelector::CreateCertTable() {
257 // SSLClientCertificateSelector private methods:
258
259 void SSLClientCertificateSelector::CreateCertTable() {
260 std::vector<ui::TableColumn> columns; 184 std::vector<ui::TableColumn> columns;
261 columns.push_back(ui::TableColumn()); 185 columns.push_back(ui::TableColumn());
262 table_ = new views::TableView(model_.get(), columns, views::TEXT_ONLY, 186 views::TableView* const table = new views::TableView(
bartfab (slow) 2015/02/19 17:53:06 Nit: Use a |scoped_ptr| while you are holding owne
pneubeck (no reviews) 2015/02/19 19:43:51 Done.
msw 2015/02/19 19:53:53 Why not assign directly to table_, as this code us
pneubeck (no reviews) 2015/02/19 20:43:49 The old one was weird with respect to ownership an
263 true /* single_selection */); 187 model_.get(), columns, views::TEXT_ONLY, true /* single_selection */);
264 table_->SetObserver(this); 188 table->SetObserver(this);
265 } 189 return table;
266
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 } 190 }
284 191
285 } // namespace chrome 192 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698