Merge pull request #1941 from deepak1556/certificate_api_patch
app: event to pass client certificate data
This commit is contained in:
commit
09c2317ae6
7 changed files with 132 additions and 7 deletions
|
@ -16,15 +16,18 @@
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "brightray/browser/brightray_paths.h"
|
#include "brightray/browser/brightray_paths.h"
|
||||||
|
#include "content/public/browser/client_certificate_delegate.h"
|
||||||
#include "native_mate/callback.h"
|
#include "native_mate/callback.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
|
#include "net/ssl/ssl_cert_request_info.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
@ -57,6 +60,21 @@ struct Converter<Browser::UserTask> {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<scoped_refptr<net::X509Certificate>> {
|
||||||
|
static v8::Local<v8::Value> ToV8(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
const scoped_refptr<net::X509Certificate>& val) {
|
||||||
|
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||||
|
std::string encoded_data;
|
||||||
|
net::X509Certificate::GetPEMEncoded(
|
||||||
|
val->os_cert_handle(), &encoded_data);
|
||||||
|
dict.Set("data", encoded_data);
|
||||||
|
dict.Set("issuerName", val->issuer().GetDisplayName());
|
||||||
|
return dict.GetHandle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,6 +108,29 @@ int GetPathConstant(const std::string& name) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnClientCertificateSelected(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
||||||
|
mate::Arguments* args) {
|
||||||
|
v8::Locker locker(isolate);
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
mate::Dictionary cert_data;
|
||||||
|
if (!(args->Length() == 1 && args->GetNext(&cert_data))) {
|
||||||
|
args->ThrowError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string encoded_data;
|
||||||
|
cert_data.Get("data", &encoded_data);
|
||||||
|
|
||||||
|
auto certs =
|
||||||
|
net::X509Certificate::CreateCertificateListFromBytes(
|
||||||
|
encoded_data.data(), encoded_data.size(),
|
||||||
|
net::X509Certificate::FORMAT_AUTO);
|
||||||
|
|
||||||
|
delegate->ContinueWithCertificate(certs[0].get());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
App::App() {
|
App::App() {
|
||||||
|
@ -144,6 +185,27 @@ void App::OnFinishLaunching() {
|
||||||
Emit("ready");
|
Emit("ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::OnSelectCertificate(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
|
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||||
|
std::shared_ptr<content::ClientCertificateDelegate>
|
||||||
|
shared_delegate(delegate.release());
|
||||||
|
bool prevent_default =
|
||||||
|
Emit("select-certificate",
|
||||||
|
api::WebContents::CreateFrom(isolate(), web_contents),
|
||||||
|
cert_request_info->host_and_port.ToString(),
|
||||||
|
cert_request_info->client_certs,
|
||||||
|
base::Bind(&OnClientCertificateSelected,
|
||||||
|
isolate(),
|
||||||
|
shared_delegate));
|
||||||
|
|
||||||
|
// Default to first certificate from the platform store.
|
||||||
|
if (!prevent_default)
|
||||||
|
shared_delegate->ContinueWithCertificate(
|
||||||
|
cert_request_info->client_certs[0].get());
|
||||||
|
}
|
||||||
|
|
||||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||||
bool succeed = false;
|
bool succeed = false;
|
||||||
base::FilePath path;
|
base::FilePath path;
|
||||||
|
|
|
@ -42,6 +42,10 @@ class App : public mate::EventEmitter,
|
||||||
void OnActivateWithNoOpenWindows() override;
|
void OnActivateWithNoOpenWindows() override;
|
||||||
void OnWillFinishLaunching() override;
|
void OnWillFinishLaunching() override;
|
||||||
void OnFinishLaunching() override;
|
void OnFinishLaunching() override;
|
||||||
|
void OnSelectCertificate(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
|
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||||
|
|
||||||
// mate::Wrappable:
|
// mate::Wrappable:
|
||||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/browser/atom_quota_permission_context.h"
|
#include "atom/browser/atom_quota_permission_context.h"
|
||||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||||
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/native_window.h"
|
#include "atom/browser/native_window.h"
|
||||||
#include "atom/browser/web_view_manager.h"
|
#include "atom/browser/web_view_manager.h"
|
||||||
#include "atom/browser/window_list.h"
|
#include "atom/browser/window_list.h"
|
||||||
|
@ -231,15 +232,13 @@ void AtomBrowserClient::SelectClientCertificate(
|
||||||
auto cert_path = command_line->GetSwitchValueNative(
|
auto cert_path = command_line->GetSwitchValueNative(
|
||||||
switches::kClientCertificate);
|
switches::kClientCertificate);
|
||||||
|
|
||||||
// TODO(zcbenz): allow users to select certificate from
|
|
||||||
// client_cert list. Right now defaults to first certificate
|
|
||||||
// in the list.
|
|
||||||
scoped_refptr<net::X509Certificate> certificate;
|
scoped_refptr<net::X509Certificate> certificate;
|
||||||
if (cert_path.empty()) {
|
if (!cert_path.empty()) {
|
||||||
if (!cert_request_info->client_certs.empty())
|
|
||||||
certificate = cert_request_info->client_certs[0];
|
|
||||||
} else {
|
|
||||||
certificate = ImportCertFromFile(base::FilePath(cert_path));
|
certificate = ImportCertFromFile(base::FilePath(cert_path));
|
||||||
|
} else if (!cert_request_info->client_certs.empty()) {
|
||||||
|
Browser::Get()->ClientCertificateSelector(web_contents,
|
||||||
|
cert_request_info,
|
||||||
|
delegate.Pass());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (certificate.get())
|
if (certificate.get())
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/browser/window_list.h"
|
#include "atom/browser/window_list.h"
|
||||||
#include "base/message_loop/message_loop.h"
|
#include "base/message_loop/message_loop.h"
|
||||||
|
#include "content/public/browser/client_certificate_delegate.h"
|
||||||
|
#include "net/ssl/ssl_cert_request_info.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -104,6 +106,17 @@ void Browser::DidFinishLaunching() {
|
||||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::ClientCertificateSelector(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
|
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||||
|
FOR_EACH_OBSERVER(BrowserObserver,
|
||||||
|
observers_,
|
||||||
|
OnSelectCertificate(web_contents,
|
||||||
|
cert_request_info,
|
||||||
|
delegate.Pass()));
|
||||||
|
}
|
||||||
|
|
||||||
void Browser::NotifyAndShutdown() {
|
void Browser::NotifyAndShutdown() {
|
||||||
bool prevent_default = false;
|
bool prevent_default = false;
|
||||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillQuit(&prevent_default));
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillQuit(&prevent_default));
|
||||||
|
|
|
@ -115,6 +115,12 @@ class Browser : public WindowListObserver {
|
||||||
void WillFinishLaunching();
|
void WillFinishLaunching();
|
||||||
void DidFinishLaunching();
|
void DidFinishLaunching();
|
||||||
|
|
||||||
|
// Called when client certificate is required.
|
||||||
|
void ClientCertificateSelector(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
|
scoped_ptr<content::ClientCertificateDelegate> delegate);
|
||||||
|
|
||||||
void AddObserver(BrowserObserver* obs) {
|
void AddObserver(BrowserObserver* obs) {
|
||||||
observers_.AddObserver(obs);
|
observers_.AddObserver(obs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,17 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class ClientCertificateDelegate;
|
||||||
|
class WebContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace net {
|
||||||
|
class SSLCertRequestInfo;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class BrowserObserver {
|
class BrowserObserver {
|
||||||
|
@ -40,6 +51,12 @@ class BrowserObserver {
|
||||||
virtual void OnWillFinishLaunching() {}
|
virtual void OnWillFinishLaunching() {}
|
||||||
virtual void OnFinishLaunching() {}
|
virtual void OnFinishLaunching() {}
|
||||||
|
|
||||||
|
// The browser requires client certificate.
|
||||||
|
virtual void OnSelectCertificate(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
|
scoped_ptr<content::ClientCertificateDelegate> delegate) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~BrowserObserver() {}
|
virtual ~BrowserObserver() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,6 +101,30 @@ Emitted when a [browserWindow](browser-window.md) gets blurred.
|
||||||
|
|
||||||
Emitted when a [browserWindow](browser-window.md) gets focused.
|
Emitted when a [browserWindow](browser-window.md) gets focused.
|
||||||
|
|
||||||
|
### Event: 'select-certificate'
|
||||||
|
|
||||||
|
Emitted when client certificate is requested.
|
||||||
|
|
||||||
|
* `event` Event
|
||||||
|
* `webContents` [WebContents](browser-window.md#class-webcontents)
|
||||||
|
* `url` String
|
||||||
|
* `certificateList` [Objects]
|
||||||
|
* `data` PEM encoded data
|
||||||
|
* `issuerName` Issuer's Common Name
|
||||||
|
* `callback` Function
|
||||||
|
|
||||||
|
```
|
||||||
|
app.on('select-certificate', function(event, host, url, list, callback) {
|
||||||
|
event.preventDefault();
|
||||||
|
callback(list[0]);
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
`url` corresponds to the navigation entry requesting the client certificate,
|
||||||
|
`callback` needs to be called with an entry filtered from the list.
|
||||||
|
`event.preventDefault()` prevents from using the first certificate from
|
||||||
|
the store.
|
||||||
|
|
||||||
## app.quit()
|
## app.quit()
|
||||||
|
|
||||||
Try to close all windows. The `before-quit` event will first be emitted. If all
|
Try to close all windows. The `before-quit` event will first be emitted. If all
|
||||||
|
|
Loading…
Reference in a new issue