blob: 42fc76d13ac0717f64c72298bf38e077a9d205f5 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/crypto_module_password_dialog.h"
#include <gtk/gtk.h>
#include "base/basictypes.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "crypto/crypto_module_blocking_password_delegate.h"
#include "grit/generated_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
namespace {
// TODO(mattm): change into a constrained dialog.
class CryptoModulePasswordDialog {
public:
CryptoModulePasswordDialog(
const std::string& slot_name,
bool retry,
chrome::CryptoModulePasswordReason reason,
const std::string& server,
const chrome::CryptoModulePasswordCallback& callback);
~CryptoModulePasswordDialog() {}
void Show();
private:
CHROMEGTK_CALLBACK_1(CryptoModulePasswordDialog, void, OnResponse, int);
CHROMEGTK_CALLBACK_0(CryptoModulePasswordDialog, void, OnWindowDestroy);
chrome::CryptoModulePasswordCallback callback_;
GtkWidget* dialog_;
GtkWidget* password_entry_;
DISALLOW_COPY_AND_ASSIGN(CryptoModulePasswordDialog);
};
CryptoModulePasswordDialog::CryptoModulePasswordDialog(
const std::string& slot_name,
bool retry,
chrome::CryptoModulePasswordReason reason,
const std::string& server,
const chrome::CryptoModulePasswordCallback& callback)
: callback_(callback) {
dialog_ = gtk_dialog_new_with_buttons(
l10n_util::GetStringUTF8(IDS_CRYPTO_MODULE_AUTH_DIALOG_TITLE).c_str(),
NULL,
GTK_DIALOG_NO_SEPARATOR,
NULL); // Populate the buttons later, for control over the OK button.
gtk_dialog_add_button(GTK_DIALOG(dialog_),
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
GtkWidget* ok_button = gtk_util::AddButtonToDialog(
dialog_,
l10n_util::GetStringUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_OK_BUTTON_LABEL).c_str(),
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT);
gtk_widget_set_can_default(ok_button, TRUE);
gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
// Select an appropriate text for the reason.
std::string text;
const string16& server16 = UTF8ToUTF16(server);
const string16& slot16 = UTF8ToUTF16(slot_name);
switch (reason) {
case chrome::kCryptoModulePasswordKeygen:
text = l10n_util::GetStringFUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_KEYGEN, slot16, server16);
break;
case chrome::kCryptoModulePasswordCertEnrollment:
text = l10n_util::GetStringFUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_ENROLLMENT, slot16, server16);
break;
case chrome::kCryptoModulePasswordClientAuth:
text = l10n_util::GetStringFUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CLIENT_AUTH, slot16, server16);
break;
case chrome::kCryptoModulePasswordListCerts:
text = l10n_util::GetStringFUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_LIST_CERTS, slot16);
break;
case chrome::kCryptoModulePasswordCertImport:
text = l10n_util::GetStringFUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_IMPORT, slot16);
break;
case chrome::kCryptoModulePasswordCertExport:
text = l10n_util::GetStringFUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_EXPORT, slot16);
break;
default:
NOTREACHED();
}
GtkWidget* label = gtk_label_new(text.c_str());
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_util::LeftAlignMisc(label);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), label,
FALSE, FALSE, 0);
password_entry_ = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(password_entry_), TRUE);
gtk_entry_set_visibility(GTK_ENTRY(password_entry_), FALSE);
GtkWidget* password_box = gtk_hbox_new(FALSE, ui::kLabelSpacing);
gtk_box_pack_start(GTK_BOX(password_box),
gtk_label_new(l10n_util::GetStringUTF8(
IDS_CRYPTO_MODULE_AUTH_DIALOG_PASSWORD_FIELD).c_str()),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(password_box), password_entry_,
TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), password_box,
FALSE, FALSE, 0);
g_signal_connect(dialog_, "response",
G_CALLBACK(OnResponseThunk), this);
g_signal_connect(dialog_, "destroy",
G_CALLBACK(OnWindowDestroyThunk), this);
}
void CryptoModulePasswordDialog::Show() {
gtk_util::ShowDialog(dialog_);
}
void CryptoModulePasswordDialog::OnResponse(GtkWidget* dialog,
int response_id) {
if (response_id == GTK_RESPONSE_ACCEPT)
callback_.Run(gtk_entry_get_text(GTK_ENTRY(password_entry_)));
else
callback_.Run(static_cast<const char*>(NULL));
// This will cause gtk to zero out the buffer. (see
// gtk_entry_buffer_normal_delete_text:
// http://git.gnome.org/browse/gtk+/tree/gtk/gtkentrybuffer.c#n187)
gtk_editable_delete_text(GTK_EDITABLE(password_entry_), 0, -1);
gtk_widget_destroy(dialog_);
}
void CryptoModulePasswordDialog::OnWindowDestroy(GtkWidget* widget) {
delete this;
}
} // namespace
namespace chrome {
void ShowCryptoModulePasswordDialog(
const std::string& slot_name,
bool retry,
CryptoModulePasswordReason reason,
const std::string& server,
const CryptoModulePasswordCallback& callback) {
(new CryptoModulePasswordDialog(slot_name, retry, reason, server,
callback))->Show();
}
} // namespace chrome