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

Unified Diff: chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm

Issue 859213006: Cancel client auth requests when not promptable. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@client-auth-cancel-1
Patch Set: worker_common.js was missing a license header (also a rebase) Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
index a8d7912f5204808919e499b1910929f09ab09571..54ff89123d38624b0cf371dea480cbe7c67dc412 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
@@ -14,7 +14,9 @@
#include "chrome/browser/ssl/ssl_client_auth_observer.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
#include "chrome/grit/generated_resources.h"
+#include "components/web_modal/popup_manager.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/web_contents.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_mac.h"
@@ -42,11 +44,12 @@ class SSLClientAuthObserverCocoaBridge : public SSLClientAuthObserver,
SSLClientAuthObserverCocoaBridge(
const content::BrowserContext* browser_context,
net::SSLCertRequestInfo* cert_request_info,
- const chrome::SelectCertificateCallback& callback,
+ scoped_ptr<content::ClientCertificateDelegate> delegate,
SSLClientCertificateSelectorCocoa* controller)
- : SSLClientAuthObserver(browser_context, cert_request_info, callback),
- controller_(controller) {
- }
+ : SSLClientAuthObserver(browser_context,
+ cert_request_info,
+ delegate.Pass()),
+ controller_(controller) {}
// SSLClientAuthObserver implementation:
void OnCertSelectedByNotification() override {
@@ -72,14 +75,22 @@ namespace chrome {
void ShowSSLClientCertificateSelector(
content::WebContents* contents,
net::SSLCertRequestInfo* cert_request_info,
- const SelectCertificateCallback& callback) {
+ scoped_ptr<content::ClientCertificateDelegate> delegate) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Not all WebContentses can show modal dialogs.
+ //
+ // TODO(davidben): Move this hook to the WebContentsDelegate and only try to
+ // show a dialog in Browser's implementation. https://crbug.com/456255
+ if (web_modal::PopupManager::FromWebContents(contents) == nullptr)
+ return;
+
// The dialog manages its own lifetime.
SSLClientCertificateSelectorCocoa* selector =
[[SSLClientCertificateSelectorCocoa alloc]
initWithBrowserContext:contents->GetBrowserContext()
certRequestInfo:cert_request_info
- callback:callback];
+ delegate:delegate.Pass()];
[selector displayForWebContents:contents];
}
@@ -88,13 +99,14 @@ void ShowSSLClientCertificateSelector(
@implementation SSLClientCertificateSelectorCocoa
- (id)initWithBrowserContext:(const content::BrowserContext*)browserContext
- certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo
- callback:(const chrome::SelectCertificateCallback&)callback {
+ certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo
+ delegate:(scoped_ptr<content::ClientCertificateDelegate>)
+ delegate {
DCHECK(browserContext);
DCHECK(certRequestInfo);
if ((self = [super init])) {
observer_.reset(new SSLClientAuthObserverCocoaBridge(
- browserContext, certRequestInfo, callback, self));
+ browserContext, certRequestInfo, delegate.Pass(), self));
}
return self;
}
@@ -113,12 +125,16 @@ void ShowSSLClientCertificateSelector(
NOTREACHED();
}
- // Finally, tell the backend which identity (or none) the user selected.
- observer_->StopObserving();
- observer_->CertificateSelected(cert);
+ if (!closePending_) {
+ // If |closePending_| is already set, |closeSheetWithAnimation:| was called
+ // already to cancel the selection rather than continue with no
+ // certificate. Otherwise, tell the backend which identity (or none) the
+ // user selected.
+ userResponded_ = YES;
+ observer_->CertificateSelected(cert);
- if (!closePending_)
constrainedWindow_->CloseWebContentsModalDialog();
+ }
}
- (void)displayForWebContents:(content::WebContents*)webContents {
@@ -184,6 +200,14 @@ void ShowSSLClientCertificateSelector(
}
- (void)closeSheetWithAnimation:(BOOL)withAnimation {
+ if (!userResponded_) {
+ // If the sheet is closed by closing the tab rather than the user explicitly
+ // hitting Cancel, |closeSheetWithAnimation:| gets called before
+ // |sheetDidEnd:|. In this case, the selection should be canceled rather
+ // than continue with no certificate. The |returnCode| parameter to
+ // |sheetDidEnd:| is the same in both cases.
+ observer_->CancelCertificateSelection();
+ }
closePending_ = YES;
overlayWindow_.reset();
// Closing the sheet using -[NSApp endSheet:] doesn't work so use the private

Powered by Google App Engine
This is Rietveld 408576698