Skip to content

Commit 88c2526

Browse files
committed
Initial SSL info support
1 parent 14928ec commit 88c2526

File tree

10 files changed

+188
-31
lines changed

10 files changed

+188
-31
lines changed

src/browser_widget.cc

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ BrowserWidget::BrowserWidget(const Cef& cef,
3434
forward_button_->setDisabled(true);
3535
connect(forward_button_, &QToolButton::clicked, [=](bool) { Forward(); });
3636

37+
ssl_button_ = new QToolButton;
38+
ssl_button_->setAutoRaise(true);
39+
ssl_button_->setDisabled(true);
40+
connect(ssl_button_, &QToolButton::clicked, [=](bool) { ShowSslInfo(); });
41+
3742
url_edit_ = new UrlEdit(this);
3843
connect(url_edit_, &UrlEdit::returnPressed, [=]() {
3944
cef_widg_->LoadUrl(url_edit_->text());
@@ -60,6 +65,7 @@ BrowserWidget::BrowserWidget(const Cef& cef,
6065
top_layout->setMargin(0);
6166
top_layout->addWidget(back_button_);
6267
top_layout->addWidget(forward_button_);
68+
top_layout->addWidget(ssl_button_);
6369
top_layout->addWidget(url_edit_, 1);
6470
top_layout->addWidget(stop_button_);
6571
top_layout->addWidget(refresh_button_);
@@ -356,13 +362,13 @@ void BrowserWidget::RecreateCefWidget(const QString& url) {
356362
PageIndex::MarkVisit(CurrentUrl(), current_title_,
357363
current_favicon_url_, current_favicon_);
358364
}
359-
// Reset the URL edit stylesheet if we're not in error mode
360-
if (loading_) {
361-
if (next_load_is_error_) {
362-
next_load_is_error_ = false;
363-
} else {
364-
url_edit_->setStyleSheet("");
365-
}
365+
366+
// Reset the stylesheet and update SSL status when not errored
367+
if (number_of_load_completes_are_error_ <= 0) {
368+
UpdateSslStatus(false);
369+
url_edit_->setStyleSheet("");
370+
} else if (!loading_) {
371+
number_of_load_completes_are_error_--;
366372
}
367373
});
368374
connect(cef_widg_, &CefWidget::LoadError,
@@ -371,19 +377,20 @@ void BrowserWidget::RecreateCefWidget(const QString& url) {
371377
const QString& error_text,
372378
const QString& failed_url) {
373379
// Some error codes we are ok with
374-
if (error_code == ERR_NONE || error_code == ERR_ABORTED) {
375-
return;
376-
}
377-
if (frame->IsMain()) {
378-
url_edit_->setStyleSheet("QLineEdit { background-color: pink; }");
379-
next_load_is_error_ = true;
380+
if (error_code != ERR_NONE && error_code != ERR_ABORTED) {
381+
ShowError(failed_url, error_text, frame);
380382
}
381-
auto new_html =
382-
QString("<html><body style=\"background-color: pink;\">"
383-
"Error loading page: <strong>%1</strong>"
384-
"</body></html>").arg(error_text);
385-
frame->LoadString(CefString(new_html.toStdString()),
386-
CefString(failed_url.toStdString()));
383+
});
384+
connect(cef_widg_, &CefWidget::CertificateError,
385+
[=](cef_errorcode_t,
386+
const QString& request_url,
387+
CefRefPtr<CefSSLInfo> ssl_info,
388+
CefRefPtr<CefRequestCallback> callback) {
389+
// TODO(cretz): Check if this is the main frame please
390+
errored_ssl_info_ = ssl_info;
391+
errored_ssl_callback_ = callback;
392+
ShowError(request_url, "Invalid Certificate");
393+
UpdateSslStatus(true);
387394
});
388395
connect(cef_widg_, &CefWidget::PageOpen,
389396
[=](CefHandler::WindowOpenType type,
@@ -536,6 +543,8 @@ void BrowserWidget::RebuildNavMenu() {
536543
void BrowserWidget::ShowAsSuspendedScreenshot() {
537544
auto grid_layout = qobject_cast<QGridLayout*>(layout());
538545
if (Suspended()) {
546+
// Have to disable the SSL button
547+
ssl_button_->setDisabled(true);
539548
// Remove the cef widg and add screenshot
540549
grid_layout->removeWidget(cef_widg_);
541550
cef_widg_->hide();
@@ -642,4 +651,65 @@ void BrowserWidget::HandleContextMenuCommand(
642651
}
643652
}
644653

654+
void BrowserWidget::ShowError(const QString& failed_url,
655+
const QString& error_text,
656+
CefRefPtr<CefFrame> frame) {
657+
if (!frame || frame->IsMain()) {
658+
url_edit_->setStyleSheet("QLineEdit { background-color: pink; }");
659+
number_of_load_completes_are_error_ = 2;
660+
}
661+
auto new_html =
662+
QString("<html><body style=\"background-color: pink;\">"
663+
"Error loading page: <strong>%1</strong>"
664+
"</body></html>").arg(error_text);
665+
cef_widg_->ShowStringPage(failed_url, new_html, frame);
666+
}
667+
668+
void BrowserWidget::UpdateSslStatus(bool check_errored) {
669+
if (check_errored && errored_ssl_info_) {
670+
ssl_button_->setDisabled(false);
671+
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
672+
":/res/images/fontawesome/unlock.png", "red")));
673+
ssl_button_->setToolTip("Invalid Certificate");
674+
} else if (loading_) {
675+
ssl_button_->setDisabled(true);
676+
ssl_button_->setIcon(QIcon());
677+
ssl_button_->setToolTip("");
678+
} else {
679+
errored_ssl_info_ = nullptr;
680+
errored_ssl_callback_ = nullptr;
681+
ssl_status_ = cef_widg_->CurrentSSLStatus();
682+
// If the SSL status is not there or there is no SSL, we mark
683+
// it as unlocked and disable the button
684+
if (!ssl_status_ || !ssl_status_->IsSecureConnection()) {
685+
ssl_button_->setIcon(Util::CachedIconLighterDisabled(
686+
":/res/images/fontawesome/unlock-alt.png"));
687+
ssl_button_->setDisabled(true);
688+
ssl_button_->setToolTip("Not secure");
689+
} else {
690+
ssl_button_->setDisabled(false);
691+
// Red when there is a cert error, orange for content error,
692+
// green otherwise
693+
if (ssl_status_->GetCertStatus() != CERT_STATUS_NONE) {
694+
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
695+
":/res/images/fontawesome/unlock.png", "red")));
696+
ssl_button_->setToolTip("Invalid Certificate");
697+
} else if (ssl_status_->GetContentStatus() !=
698+
SSL_CONTENT_NORMAL_CONTENT) {
699+
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
700+
":/res/images/fontawesome/unlock.png", "orange")));
701+
ssl_button_->setToolTip("Insecure Page Contents");
702+
} else {
703+
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
704+
":/res/images/fontawesome/lock.png", "green")));
705+
ssl_button_->setToolTip("Secure");
706+
}
707+
}
708+
}
709+
}
710+
711+
void BrowserWidget::ShowSslInfo() const {
712+
// TODO
713+
}
714+
645715
} // namespace doogie

src/browser_widget.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,17 @@ class BrowserWidget : public QWidget {
9797
void HandleContextMenuCommand(CefRefPtr<CefContextMenuParams> params,
9898
int command_id,
9999
CefContextMenuHandler::EventFlags event_flags);
100+
void ShowError(const QString& failed_url,
101+
const QString& error_text,
102+
CefRefPtr<CefFrame> frame = nullptr);
103+
void UpdateSslStatus(bool check_errored);
104+
void ShowSslInfo() const;
100105

101106
const Cef& cef_;
102107
Bubble bubble_;
103108
QToolButton* back_button_ = nullptr;
104109
QToolButton* forward_button_ = nullptr;
110+
QToolButton* ssl_button_ = nullptr;
105111
QMenu* nav_menu_ = nullptr;
106112
UrlEdit* url_edit_ = nullptr;
107113
QToolButton* refresh_button_ = nullptr;
@@ -118,7 +124,10 @@ class BrowserWidget : public QWidget {
118124
bool suspended_ = false;
119125
QString suspended_url_;
120126
QPixmap suspended_screenshot_;
121-
bool next_load_is_error_ = true;
127+
int number_of_load_completes_are_error_ = 0;
128+
CefRefPtr<CefSSLInfo> errored_ssl_info_;
129+
CefRefPtr<CefRequestCallback> errored_ssl_callback_;
130+
CefRefPtr<CefSSLStatus> ssl_status_;
122131
};
123132

124133
} // namespace doogie

src/cef/cef_handler.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,17 @@ bool CefHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
195195
return false;
196196
}
197197

198+
bool CefHandler::OnCertificateError(CefRefPtr<CefBrowser> browser,
199+
cef_errorcode_t cert_error,
200+
const CefString& request_url,
201+
CefRefPtr<CefSSLInfo> ssl_info,
202+
CefRefPtr<CefRequestCallback> callback) {
203+
emit CertificateError(cert_error,
204+
QString::fromStdString(request_url.ToString()),
205+
ssl_info, callback);
206+
return true;
207+
}
208+
198209
bool CefHandler::OnOpenURLFromTab(
199210
CefRefPtr<CefBrowser> browser,
200211
CefRefPtr<CefFrame> frame,

src/cef/cef_handler.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ class CefHandler :
191191
CefRefPtr<CefFrame> frame,
192192
CefRefPtr<CefRequest> request,
193193
bool is_redirect) override;
194+
bool OnCertificateError(CefRefPtr<CefBrowser> browser,
195+
cef_errorcode_t cert_error,
196+
const CefString& request_url,
197+
CefRefPtr<CefSSLInfo> ssl_info,
198+
CefRefPtr<CefRequestCallback> callback) override;
194199
bool OnOpenURLFromTab(
195200
CefRefPtr<CefBrowser> browser,
196201
CefRefPtr<CefFrame> frame,
@@ -234,6 +239,11 @@ class CefHandler :
234239
ErrorCode error_code,
235240
const QString& error_text,
236241
const QString& failed_url);
242+
void CertificateError(
243+
cef_errorcode_t cert_error,
244+
const QString& request_url,
245+
CefRefPtr<CefSSLInfo> ssl_info,
246+
CefRefPtr<CefRequestCallback> callback);
237247
void PageOpen(WindowOpenType type, const QString& url, bool user_gesture);
238248
void BrowserLog(const QString& str);
239249

src/cef/cef_widget.cc

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ CefWidget::CefWidget(const Cef& cef,
4949
this, &CefWidget::LoadStart);
5050
connect(handler_, &CefHandler::LoadError,
5151
this, &CefWidget::LoadError);
52+
connect(handler_, &CefHandler::CertificateError,
53+
this, &CefWidget::CertificateError);
5254
connect(handler_, &CefHandler::PageOpen,
5355
this, &CefWidget::PageOpen);
5456
connect(handler_, &CefHandler::FindResult,
@@ -70,13 +72,22 @@ CefWidget::~CefWidget() {
7072

7173
std::vector<CefWidget::NavEntry> CefWidget::NavEntries() const {
7274
CefRefPtr<CefWidget::NavEntryVisitor> visitor =
73-
new CefWidget::NavEntryVisitor;
75+
new CefWidget::NavEntryVisitor();
7476
if (browser_) {
7577
browser_->GetHost()->GetNavigationEntries(visitor, false);
7678
}
7779
return visitor->Entries();
7880
}
7981

82+
CefRefPtr<CefSSLStatus> CefWidget::CurrentSSLStatus() const {
83+
CefRefPtr<CefWidget::NavEntryCurrentSslVisitor> visitor =
84+
new CefWidget::NavEntryCurrentSslVisitor();
85+
if (browser_ && !browser_->IsLoading() && browser_->HasDocument()) {
86+
browser_->GetHost()->GetNavigationEntries(visitor, true);
87+
}
88+
return visitor->SslStatus();
89+
}
90+
8091
QPointer<QWidget> CefWidget::OverrideWidget() const {
8192
return override_widget_;
8293
}
@@ -87,6 +98,16 @@ void CefWidget::LoadUrl(const QString& url) {
8798
}
8899
}
89100

101+
void CefWidget::ShowStringPage(const QString& url,
102+
const QString& contents,
103+
CefRefPtr<CefFrame> frame) {
104+
if (browser_) {
105+
auto f = frame ? frame : browser_->GetMainFrame();
106+
f->LoadString(CefString(contents.toStdString()),
107+
CefString(url.toStdString()));
108+
}
109+
}
110+
90111
QString CefWidget::CurrentUrl() const {
91112
if (browser_) {
92113
return QString::fromStdString(
@@ -262,4 +283,24 @@ void CefWidget::FaviconDownloadCallback::OnDownloadImageFinished(
262283
icon);
263284
}
264285

286+
bool CefWidget::NavEntryVisitor::Visit(CefRefPtr<CefNavigationEntry> entry,
287+
bool current,
288+
int, int) {
289+
NavEntry nav_entry = {
290+
QString::fromStdString(entry->GetURL().ToString()),
291+
QString::fromStdString(entry->GetTitle().ToString()),
292+
current
293+
};
294+
entries_.push_back(nav_entry);
295+
return true;
296+
}
297+
298+
bool CefWidget::NavEntryCurrentSslVisitor::Visit(
299+
CefRefPtr<CefNavigationEntry> entry,
300+
bool current,
301+
int, int) {
302+
if (entry->IsValid() && current) ssl_status_ = entry->GetSSLStatus();
303+
return false;
304+
}
305+
265306
} // namespace doogie

src/cef/cef_widget.h

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ class CefWidget : public CefBaseWidget {
2727
~CefWidget();
2828

2929
std::vector<NavEntry> NavEntries() const;
30+
CefRefPtr<CefSSLStatus> CurrentSSLStatus() const;
3031
// If result is non-null, it needs to replace this widget
3132
QPointer<QWidget> OverrideWidget() const;
3233
void LoadUrl(const QString& url);
34+
// No frame means main frame
35+
void ShowStringPage(const QString& url,
36+
const QString& contents,
37+
CefRefPtr<CefFrame> frame = nullptr);
3338
QString CurrentUrl() const;
3439
bool HasDocument() const;
3540
void TryClose();
@@ -81,6 +86,11 @@ class CefWidget : public CefBaseWidget {
8186
CefLoadHandler::ErrorCode error_code,
8287
const QString& error_text,
8388
const QString& failed_url);
89+
void CertificateError(
90+
cef_errorcode_t cert_error,
91+
const QString& request_url,
92+
CefRefPtr<CefSSLInfo> ssl_info,
93+
CefRefPtr<CefRequestCallback> callback);
8494
void PageOpen(CefHandler::WindowOpenType type,
8595
const QString& url,
8696
bool user_gesture);
@@ -113,22 +123,25 @@ class CefWidget : public CefBaseWidget {
113123
class NavEntryVisitor : public CefNavigationEntryVisitor {
114124
public:
115125
bool Visit(CefRefPtr<CefNavigationEntry> entry,
116-
bool current, int, int) override {
117-
NavEntry nav_entry = {
118-
QString::fromStdString(entry->GetURL().ToString()),
119-
QString::fromStdString(entry->GetTitle().ToString()),
120-
current
121-
};
122-
entries_.push_back(nav_entry);
123-
return true;
124-
}
125-
std::vector<NavEntry> Entries() { return entries_; }
126+
bool current, int, int) override;
127+
std::vector<NavEntry> Entries() const { return entries_; }
126128

127129
private:
128130
std::vector<NavEntry> entries_;
129131
IMPLEMENT_REFCOUNTING(NavEntryVisitor)
130132
};
131133

134+
class NavEntryCurrentSslVisitor : public CefNavigationEntryVisitor {
135+
public:
136+
bool Visit(CefRefPtr<CefNavigationEntry> entry,
137+
bool current, int, int) override;
138+
CefRefPtr<CefSSLStatus> SslStatus() const { return ssl_status_; }
139+
140+
private:
141+
CefRefPtr<CefSSLStatus> ssl_status_;
142+
IMPLEMENT_REFCOUNTING(NavEntryCurrentSslVisitor)
143+
};
144+
132145
void InitBrowser(const Bubble& bubble, const QString& url);
133146

134147
CefRefPtr<CefHandler> handler_;

src/doogie.qrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
<file>images/fontawesome/circle.png</file>
1010
<file>images/fontawesome/file-o.png</file>
1111
<file>images/fontawesome/folder-open-o.png</file>
12+
<file>images/fontawesome/lock.png</file>
1213
<file>images/fontawesome/pause.png</file>
1314
<file>images/fontawesome/play.png</file>
1415
<file>images/fontawesome/repeat.png</file>
1516
<file>images/fontawesome/times.png</file>
1617
<file>images/fontawesome/times-circle.png</file>
18+
<file>images/fontawesome/unlock.png</file>
19+
<file>images/fontawesome/unlock-alt.png</file>
1720

1821
<file>schema.sql</file>
1922
</qresource>

src/images/fontawesome/lock.png

313 Bytes
Loading
315 Bytes
Loading

src/images/fontawesome/unlock.png

326 Bytes
Loading

0 commit comments

Comments
 (0)