Skip to content

Commit

Permalink
Initial SSL info support
Browse files Browse the repository at this point in the history
  • Loading branch information
cretz committed Aug 17, 2017
1 parent 14928ec commit 88c2526
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 31 deletions.
108 changes: 89 additions & 19 deletions src/browser_widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ BrowserWidget::BrowserWidget(const Cef& cef,
forward_button_->setDisabled(true);
connect(forward_button_, &QToolButton::clicked, [=](bool) { Forward(); });

ssl_button_ = new QToolButton;
ssl_button_->setAutoRaise(true);
ssl_button_->setDisabled(true);
connect(ssl_button_, &QToolButton::clicked, [=](bool) { ShowSslInfo(); });

url_edit_ = new UrlEdit(this);
connect(url_edit_, &UrlEdit::returnPressed, [=]() {
cef_widg_->LoadUrl(url_edit_->text());
Expand All @@ -60,6 +65,7 @@ BrowserWidget::BrowserWidget(const Cef& cef,
top_layout->setMargin(0);
top_layout->addWidget(back_button_);
top_layout->addWidget(forward_button_);
top_layout->addWidget(ssl_button_);
top_layout->addWidget(url_edit_, 1);
top_layout->addWidget(stop_button_);
top_layout->addWidget(refresh_button_);
Expand Down Expand Up @@ -356,13 +362,13 @@ void BrowserWidget::RecreateCefWidget(const QString& url) {
PageIndex::MarkVisit(CurrentUrl(), current_title_,
current_favicon_url_, current_favicon_);
}
// Reset the URL edit stylesheet if we're not in error mode
if (loading_) {
if (next_load_is_error_) {
next_load_is_error_ = false;
} else {
url_edit_->setStyleSheet("");
}

// Reset the stylesheet and update SSL status when not errored
if (number_of_load_completes_are_error_ <= 0) {
UpdateSslStatus(false);
url_edit_->setStyleSheet("");
} else if (!loading_) {
number_of_load_completes_are_error_--;
}
});
connect(cef_widg_, &CefWidget::LoadError,
Expand All @@ -371,19 +377,20 @@ void BrowserWidget::RecreateCefWidget(const QString& url) {
const QString& error_text,
const QString& failed_url) {
// Some error codes we are ok with
if (error_code == ERR_NONE || error_code == ERR_ABORTED) {
return;
}
if (frame->IsMain()) {
url_edit_->setStyleSheet("QLineEdit { background-color: pink; }");
next_load_is_error_ = true;
if (error_code != ERR_NONE && error_code != ERR_ABORTED) {
ShowError(failed_url, error_text, frame);
}
auto new_html =
QString("<html><body style=\"background-color: pink;\">"
"Error loading page: <strong>%1</strong>"
"</body></html>").arg(error_text);
frame->LoadString(CefString(new_html.toStdString()),
CefString(failed_url.toStdString()));
});
connect(cef_widg_, &CefWidget::CertificateError,
[=](cef_errorcode_t,
const QString& request_url,
CefRefPtr<CefSSLInfo> ssl_info,
CefRefPtr<CefRequestCallback> callback) {
// TODO(cretz): Check if this is the main frame please
errored_ssl_info_ = ssl_info;
errored_ssl_callback_ = callback;
ShowError(request_url, "Invalid Certificate");
UpdateSslStatus(true);
});
connect(cef_widg_, &CefWidget::PageOpen,
[=](CefHandler::WindowOpenType type,
Expand Down Expand Up @@ -536,6 +543,8 @@ void BrowserWidget::RebuildNavMenu() {
void BrowserWidget::ShowAsSuspendedScreenshot() {
auto grid_layout = qobject_cast<QGridLayout*>(layout());
if (Suspended()) {
// Have to disable the SSL button
ssl_button_->setDisabled(true);
// Remove the cef widg and add screenshot
grid_layout->removeWidget(cef_widg_);
cef_widg_->hide();
Expand Down Expand Up @@ -642,4 +651,65 @@ void BrowserWidget::HandleContextMenuCommand(
}
}

void BrowserWidget::ShowError(const QString& failed_url,
const QString& error_text,
CefRefPtr<CefFrame> frame) {
if (!frame || frame->IsMain()) {
url_edit_->setStyleSheet("QLineEdit { background-color: pink; }");
number_of_load_completes_are_error_ = 2;
}
auto new_html =
QString("<html><body style=\"background-color: pink;\">"
"Error loading page: <strong>%1</strong>"
"</body></html>").arg(error_text);
cef_widg_->ShowStringPage(failed_url, new_html, frame);
}

void BrowserWidget::UpdateSslStatus(bool check_errored) {
if (check_errored && errored_ssl_info_) {
ssl_button_->setDisabled(false);
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
":/res/images/fontawesome/unlock.png", "red")));
ssl_button_->setToolTip("Invalid Certificate");
} else if (loading_) {
ssl_button_->setDisabled(true);
ssl_button_->setIcon(QIcon());
ssl_button_->setToolTip("");
} else {
errored_ssl_info_ = nullptr;
errored_ssl_callback_ = nullptr;
ssl_status_ = cef_widg_->CurrentSSLStatus();
// If the SSL status is not there or there is no SSL, we mark
// it as unlocked and disable the button
if (!ssl_status_ || !ssl_status_->IsSecureConnection()) {
ssl_button_->setIcon(Util::CachedIconLighterDisabled(
":/res/images/fontawesome/unlock-alt.png"));
ssl_button_->setDisabled(true);
ssl_button_->setToolTip("Not secure");
} else {
ssl_button_->setDisabled(false);
// Red when there is a cert error, orange for content error,
// green otherwise
if (ssl_status_->GetCertStatus() != CERT_STATUS_NONE) {
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
":/res/images/fontawesome/unlock.png", "red")));
ssl_button_->setToolTip("Invalid Certificate");
} else if (ssl_status_->GetContentStatus() !=
SSL_CONTENT_NORMAL_CONTENT) {
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
":/res/images/fontawesome/unlock.png", "orange")));
ssl_button_->setToolTip("Insecure Page Contents");
} else {
ssl_button_->setIcon(QIcon(*Util::CachedPixmapColorOverlay(
":/res/images/fontawesome/lock.png", "green")));
ssl_button_->setToolTip("Secure");
}
}
}
}

void BrowserWidget::ShowSslInfo() const {
// TODO
}

} // namespace doogie
11 changes: 10 additions & 1 deletion src/browser_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,17 @@ class BrowserWidget : public QWidget {
void HandleContextMenuCommand(CefRefPtr<CefContextMenuParams> params,
int command_id,
CefContextMenuHandler::EventFlags event_flags);
void ShowError(const QString& failed_url,
const QString& error_text,
CefRefPtr<CefFrame> frame = nullptr);
void UpdateSslStatus(bool check_errored);
void ShowSslInfo() const;

const Cef& cef_;
Bubble bubble_;
QToolButton* back_button_ = nullptr;
QToolButton* forward_button_ = nullptr;
QToolButton* ssl_button_ = nullptr;
QMenu* nav_menu_ = nullptr;
UrlEdit* url_edit_ = nullptr;
QToolButton* refresh_button_ = nullptr;
Expand All @@ -118,7 +124,10 @@ class BrowserWidget : public QWidget {
bool suspended_ = false;
QString suspended_url_;
QPixmap suspended_screenshot_;
bool next_load_is_error_ = true;
int number_of_load_completes_are_error_ = 0;
CefRefPtr<CefSSLInfo> errored_ssl_info_;
CefRefPtr<CefRequestCallback> errored_ssl_callback_;
CefRefPtr<CefSSLStatus> ssl_status_;
};

} // namespace doogie
Expand Down
11 changes: 11 additions & 0 deletions src/cef/cef_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,17 @@ bool CefHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
return false;
}

bool CefHandler::OnCertificateError(CefRefPtr<CefBrowser> browser,
cef_errorcode_t cert_error,
const CefString& request_url,
CefRefPtr<CefSSLInfo> ssl_info,
CefRefPtr<CefRequestCallback> callback) {
emit CertificateError(cert_error,
QString::fromStdString(request_url.ToString()),
ssl_info, callback);
return true;
}

bool CefHandler::OnOpenURLFromTab(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
Expand Down
10 changes: 10 additions & 0 deletions src/cef/cef_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ class CefHandler :
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_redirect) override;
bool OnCertificateError(CefRefPtr<CefBrowser> browser,
cef_errorcode_t cert_error,
const CefString& request_url,
CefRefPtr<CefSSLInfo> ssl_info,
CefRefPtr<CefRequestCallback> callback) override;
bool OnOpenURLFromTab(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
Expand Down Expand Up @@ -234,6 +239,11 @@ class CefHandler :
ErrorCode error_code,
const QString& error_text,
const QString& failed_url);
void CertificateError(
cef_errorcode_t cert_error,
const QString& request_url,
CefRefPtr<CefSSLInfo> ssl_info,
CefRefPtr<CefRequestCallback> callback);
void PageOpen(WindowOpenType type, const QString& url, bool user_gesture);
void BrowserLog(const QString& str);

Expand Down
43 changes: 42 additions & 1 deletion src/cef/cef_widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ CefWidget::CefWidget(const Cef& cef,
this, &CefWidget::LoadStart);
connect(handler_, &CefHandler::LoadError,
this, &CefWidget::LoadError);
connect(handler_, &CefHandler::CertificateError,
this, &CefWidget::CertificateError);
connect(handler_, &CefHandler::PageOpen,
this, &CefWidget::PageOpen);
connect(handler_, &CefHandler::FindResult,
Expand All @@ -70,13 +72,22 @@ CefWidget::~CefWidget() {

std::vector<CefWidget::NavEntry> CefWidget::NavEntries() const {
CefRefPtr<CefWidget::NavEntryVisitor> visitor =
new CefWidget::NavEntryVisitor;
new CefWidget::NavEntryVisitor();
if (browser_) {
browser_->GetHost()->GetNavigationEntries(visitor, false);
}
return visitor->Entries();
}

CefRefPtr<CefSSLStatus> CefWidget::CurrentSSLStatus() const {
CefRefPtr<CefWidget::NavEntryCurrentSslVisitor> visitor =
new CefWidget::NavEntryCurrentSslVisitor();
if (browser_ && !browser_->IsLoading() && browser_->HasDocument()) {
browser_->GetHost()->GetNavigationEntries(visitor, true);
}
return visitor->SslStatus();
}

QPointer<QWidget> CefWidget::OverrideWidget() const {
return override_widget_;
}
Expand All @@ -87,6 +98,16 @@ void CefWidget::LoadUrl(const QString& url) {
}
}

void CefWidget::ShowStringPage(const QString& url,
const QString& contents,
CefRefPtr<CefFrame> frame) {
if (browser_) {
auto f = frame ? frame : browser_->GetMainFrame();
f->LoadString(CefString(contents.toStdString()),
CefString(url.toStdString()));
}
}

QString CefWidget::CurrentUrl() const {
if (browser_) {
return QString::fromStdString(
Expand Down Expand Up @@ -262,4 +283,24 @@ void CefWidget::FaviconDownloadCallback::OnDownloadImageFinished(
icon);
}

bool CefWidget::NavEntryVisitor::Visit(CefRefPtr<CefNavigationEntry> entry,
bool current,
int, int) {
NavEntry nav_entry = {
QString::fromStdString(entry->GetURL().ToString()),
QString::fromStdString(entry->GetTitle().ToString()),
current
};
entries_.push_back(nav_entry);
return true;
}

bool CefWidget::NavEntryCurrentSslVisitor::Visit(
CefRefPtr<CefNavigationEntry> entry,
bool current,
int, int) {
if (entry->IsValid() && current) ssl_status_ = entry->GetSSLStatus();
return false;
}

} // namespace doogie
33 changes: 23 additions & 10 deletions src/cef/cef_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ class CefWidget : public CefBaseWidget {
~CefWidget();

std::vector<NavEntry> NavEntries() const;
CefRefPtr<CefSSLStatus> CurrentSSLStatus() const;
// If result is non-null, it needs to replace this widget
QPointer<QWidget> OverrideWidget() const;
void LoadUrl(const QString& url);
// No frame means main frame
void ShowStringPage(const QString& url,
const QString& contents,
CefRefPtr<CefFrame> frame = nullptr);
QString CurrentUrl() const;
bool HasDocument() const;
void TryClose();
Expand Down Expand Up @@ -81,6 +86,11 @@ class CefWidget : public CefBaseWidget {
CefLoadHandler::ErrorCode error_code,
const QString& error_text,
const QString& failed_url);
void CertificateError(
cef_errorcode_t cert_error,
const QString& request_url,
CefRefPtr<CefSSLInfo> ssl_info,
CefRefPtr<CefRequestCallback> callback);
void PageOpen(CefHandler::WindowOpenType type,
const QString& url,
bool user_gesture);
Expand Down Expand Up @@ -113,22 +123,25 @@ class CefWidget : public CefBaseWidget {
class NavEntryVisitor : public CefNavigationEntryVisitor {
public:
bool Visit(CefRefPtr<CefNavigationEntry> entry,
bool current, int, int) override {
NavEntry nav_entry = {
QString::fromStdString(entry->GetURL().ToString()),
QString::fromStdString(entry->GetTitle().ToString()),
current
};
entries_.push_back(nav_entry);
return true;
}
std::vector<NavEntry> Entries() { return entries_; }
bool current, int, int) override;
std::vector<NavEntry> Entries() const { return entries_; }

private:
std::vector<NavEntry> entries_;
IMPLEMENT_REFCOUNTING(NavEntryVisitor)
};

class NavEntryCurrentSslVisitor : public CefNavigationEntryVisitor {
public:
bool Visit(CefRefPtr<CefNavigationEntry> entry,
bool current, int, int) override;
CefRefPtr<CefSSLStatus> SslStatus() const { return ssl_status_; }

private:
CefRefPtr<CefSSLStatus> ssl_status_;
IMPLEMENT_REFCOUNTING(NavEntryCurrentSslVisitor)
};

void InitBrowser(const Bubble& bubble, const QString& url);

CefRefPtr<CefHandler> handler_;
Expand Down
3 changes: 3 additions & 0 deletions src/doogie.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
<file>images/fontawesome/circle.png</file>
<file>images/fontawesome/file-o.png</file>
<file>images/fontawesome/folder-open-o.png</file>
<file>images/fontawesome/lock.png</file>
<file>images/fontawesome/pause.png</file>
<file>images/fontawesome/play.png</file>
<file>images/fontawesome/repeat.png</file>
<file>images/fontawesome/times.png</file>
<file>images/fontawesome/times-circle.png</file>
<file>images/fontawesome/unlock.png</file>
<file>images/fontawesome/unlock-alt.png</file>

<file>schema.sql</file>
</qresource>
Expand Down
Binary file added src/images/fontawesome/lock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/fontawesome/unlock-alt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/fontawesome/unlock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 88c2526

Please sign in to comment.