Credential UI revised to honor read-only, allow-save, and config/prompt mode correctly

This commit is contained in:
Simon Rozman 2016-08-03 12:34:49 +02:00
parent 2868fd3848
commit cadf7272df
9 changed files with 162 additions and 126 deletions

View File

@ -52,12 +52,12 @@ template <class _Tcred, class _wxT> class wxEAPCredentialsConfigPanel;
///
/// Base template for all credential entry panels
///
template <class _Tbase> class wxEAPCredentialsPanelBase;
template <class _Tcred, class _Tbase> class wxEAPCredentialsPanelBase;
///
/// Generic password credential entry panel
///
class wxPasswordCredentialsPanel;
template <class _Tcred, class _Tbase> class wxPasswordCredentialsPanel;
///
/// Sets icon from resource
@ -245,14 +245,6 @@ protected:
virtual bool TransferDataToWindow()
{
if (m_prov.m_read_only) {
// This is provider-locked configuration. Disable controls.
m_own ->Enable(false);
m_preshared ->Enable(false);
m_preshared_identity->Enable(false);
m_preshared_set ->Enable(false);
}
if (!m_cfg.m_use_preshared)
m_own->SetValue(true);
else
@ -316,8 +308,22 @@ protected:
m_preshared_identity->SetValue(!m_cred.empty() ? m_cred.get_name() : _("<blank>"));
if (!m_prov.m_read_only) {
if (m_prov.m_read_only) {
// This is provider-locked configuration. Disable controls.
// To avoid run-away selection of radio buttons, disable the selected one last.
if (m_own->GetValue()) {
m_preshared->Enable(false);
m_own ->Enable(false);
} else {
m_own ->Enable(false);
m_preshared->Enable(false);
}
m_preshared_identity->Enable(false);
m_preshared_set ->Enable(false);
} else {
// This is not a provider-locked configuration. Selectively enable/disable controls.
m_own ->Enable(true);
m_preshared ->Enable(true);
if (m_own->GetValue()) {
m_preshared_identity->Enable(false);
m_preshared_set ->Enable(false);
@ -378,9 +384,14 @@ private:
};
template <class _Tbase>
template <class _Tcred, class _Tbase>
class wxEAPCredentialsPanelBase : public _Tbase
{
private:
/// \cond internal
typedef wxEAPCredentialsPanelBase<_Tcred, _Tbase> _Tthis;
/// \endcond
public:
///
/// Constructs a credentials panel
@ -392,7 +403,7 @@ public:
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxEAPCredentialsPanelBase(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
wxEAPCredentialsPanelBase(const eap::config_provider &prov, const eap::config_method_with_cred<_Tcred> &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
m_prov(prov),
m_cfg(cfg),
m_cred(cred),
@ -400,11 +411,12 @@ public:
m_is_config(is_config),
_Tbase(parent)
{
if (m_is_config) {
// In configuration mode, always store credentials (somewhere).
m_remember->SetValue(true);
m_remember->Enable(false);
}
this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(_Tthis::OnUpdateUI));
}
virtual ~wxEAPCredentialsPanelBase()
{
this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(_Tthis::OnUpdateUI));
}
protected:
@ -450,18 +462,39 @@ protected:
return true;
}
virtual void OnUpdateUI(wxUpdateUIEvent& event)
{
UNREFERENCED_PARAMETER(event);
if (m_is_config) {
// Configuration mode
// Always store credentials (somewhere).
m_remember->SetValue(true);
m_remember->Enable(false);
} else if (m_cfg.m_use_preshared) {
// Credential prompt mode & Using pre-shared credentials
m_remember->SetValue(false);
m_remember->Enable(false);
} else if (!m_cfg.m_allow_save) {
// Credential prompt mode & using own credentials & saving is not allowed
m_remember->SetValue(false);
m_remember->Enable(false);
}
}
/// \endcond
protected:
const eap::config_provider &m_prov; ///< Provider configuration
const eap::config_method &m_cfg; ///< Method configuration
eap::credentials &m_cred; ///< Generic credentials
winstd::tstring m_target; ///< Credential Manager target
bool m_is_config; ///< Is this a configuration dialog?
const eap::config_provider &m_prov; ///< Provider configuration
const eap::config_method_with_cred<_Tcred> &m_cfg; ///< Method configuration
_Tcred &m_cred; ///< Credentials
winstd::tstring m_target; ///< Credential Manager target
bool m_is_config; ///< Is this a configuration dialog?
};
class wxPasswordCredentialsPanel : public wxEAPCredentialsPanelBase<wxEAPCredentialsPanelPassBase>
template <class _Tcred, class _Tbase>
class wxPasswordCredentialsPanel : public wxEAPCredentialsPanelBase<_Tcred, _Tbase>
{
public:
///
@ -474,16 +507,82 @@ public:
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred<_Tcred> &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
wxEAPCredentialsPanelBase<_Tcred, _Tbase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{
// Load and set icon.
if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
wxSetIconFromResource(m_credentials_icon, m_icon, m_shell32, MAKEINTRESOURCE(269));
bool layout = false;
if (!m_prov.m_lbl_alt_credential.empty()) {
m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential);
m_credentials_label->Wrap( 446 );
layout = true;
}
if (!m_prov.m_lbl_alt_identity.empty()) {
m_identity_label->SetLabel(m_prov.m_lbl_alt_identity);
layout = true;
}
if (!m_prov.m_lbl_alt_password.empty()) {
m_password_label->SetLabel(m_prov.m_lbl_alt_password);
layout = true;
}
if (layout)
this->Layout();
}
protected:
/// \cond internal
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
virtual bool TransferDataToWindow()
{
// Inherited TransferDataToWindow() calls m_cred.retrieve().
// Therefore, call it now, to set m_cred.
if (!wxEAPCredentialsPanelBase<_Tcred, wxEAPCredentialsPanelPassBase>::TransferDataToWindow())
return false;
m_identity->SetValue(m_cred.m_identity);
m_identity->SetSelection(0, -1);
m_password->SetValue(m_cred.m_password.empty() ? wxEmptyString : s_dummy_password);
return true;
}
virtual bool TransferDataFromWindow()
{
m_cred.m_identity = m_identity->GetValue();
wxString pass = m_password->GetValue();
if (pass.compare(s_dummy_password) != 0) {
m_cred.m_password = pass;
pass.assign(pass.length(), wxT('*'));
}
// Inherited TransferDataFromWindow() calls m_cred.store().
// Therefore, call it only now, that m_cred is set.
return wxEAPCredentialsPanelBase<_Tcred, wxEAPCredentialsPanelPassBase>::TransferDataFromWindow();
}
virtual void OnUpdateUI(wxUpdateUIEvent& event)
{
if (!m_is_config && m_cfg.m_use_preshared) {
// Credential prompt mode & Using pre-shared credentials
m_identity_label->Enable(false);
m_identity ->Enable(false);
m_password_label->Enable(false);
m_password ->Enable(false);
}
wxEAPCredentialsPanelBase<_Tcred, wxEAPCredentialsPanelPassBase>::OnUpdateUI(event);
}
/// \endcond
protected:
eap::credentials_pass &m_cred; ///< Password credentials
winstd::library m_shell32; ///< shell32.dll resource library reference
wxIcon m_icon; ///< Panel icon
@ -491,6 +590,9 @@ private:
static const wxStringCharType *s_dummy_password;
};
template <class _Tcred, class _Tbase>
const wxStringCharType *wxPasswordCredentialsPanel<_Tcred, _Tbase>::s_dummy_password = wxT("dummypass");
inline bool wxSetIconFromResource(wxStaticBitmap *bmp, wxIcon &icon, HINSTANCE hinst, PCWSTR pszName)
{

View File

@ -149,70 +149,3 @@ bool wxEAPProviderLockedPanel::AcceptsFocusFromKeyboard() const
{
return !m_prov.m_help_email.empty() || !m_prov.m_help_web.empty() || !m_prov.m_help_phone.empty();
}
//////////////////////////////////////////////////////////////////////
// wxPasswordCredentialsPanel
//////////////////////////////////////////////////////////////////////
wxPasswordCredentialsPanel::wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
m_cred((eap::credentials_pass&)cred),
wxEAPCredentialsPanelBase<wxEAPCredentialsPanelPassBase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{
// Load and set icon.
if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
wxSetIconFromResource(m_credentials_icon, m_icon, m_shell32, MAKEINTRESOURCE(269));
bool layout = false;
if (!m_prov.m_lbl_alt_credential.empty()) {
m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential);
m_credentials_label->Wrap( 446 );
layout = true;
}
if (!m_prov.m_lbl_alt_identity.empty()) {
m_identity_label->SetLabel(m_prov.m_lbl_alt_identity);
layout = true;
}
if (!m_prov.m_lbl_alt_password.empty()) {
m_password_label->SetLabel(m_prov.m_lbl_alt_password);
layout = true;
}
if (layout)
this->Layout();
}
bool wxPasswordCredentialsPanel::TransferDataToWindow()
{
// Inherited TransferDataToWindow() calls m_cred.retrieve().
// Therefore, call it now, to set m_cred.
wxCHECK(wxEAPCredentialsPanelBase<wxEAPCredentialsPanelPassBase>::TransferDataToWindow(), false);
m_identity->SetValue(m_cred.m_identity);
m_identity->SetSelection(0, -1);
m_password->SetValue(m_cred.m_password.empty() ? wxEmptyString : s_dummy_password);
return true;
}
bool wxPasswordCredentialsPanel::TransferDataFromWindow()
{
m_cred.m_identity = m_identity->GetValue();
wxString pass = m_password->GetValue();
if (pass.compare(s_dummy_password) != 0) {
m_cred.m_password = pass;
pass.assign(pass.length(), wxT('*'));
}
// Inherited TransferDataFromWindow() calls m_cred.store().
// Therefore, call it only now, that m_cred is set.
return wxEAPCredentialsPanelBase<wxEAPCredentialsPanelPassBase>::TransferDataFromWindow();
}
const wxStringCharType *wxPasswordCredentialsPanel::s_dummy_password = wxT("dummypass");

View File

@ -25,7 +25,7 @@
///
/// PAP credential configuration panel
///
typedef wxEAPCredentialsConfigPanel<eap::credentials_pap, wxPasswordCredentialsPanel> wxPAPCredentialsConfigPanel;
typedef wxEAPCredentialsConfigPanel<eap::credentials_pap, wxPasswordCredentialsPanel<eap::credentials_pap, wxEAPCredentialsPanelPassBase> > wxPAPCredentialsConfigPanel;
///
/// PAP configuration panel
@ -35,7 +35,7 @@ class wxPAPConfigPanel;
///
/// PAP credential entry panel
///
typedef wxPasswordCredentialsPanel wxPAPCredentialsPanel;
typedef wxPasswordCredentialsPanel<eap::credentials_pap, wxEAPCredentialsPanelPassBase> wxPAPCredentialsPanel;
#pragma once

View File

@ -248,7 +248,7 @@ protected:
};
class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase<wxTLSCredentialsPanelBase>
class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>
{
public:
///
@ -261,17 +261,16 @@ public:
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred<eap::credentials_tls> &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
protected:
/// \cond internal
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
virtual void OnCertSelect(wxCommandEvent& event);
virtual void OnUpdateUI(wxUpdateUIEvent& event);
/// \endcond
protected:
eap::credentials_tls &m_cred; ///< TLS credentials
winstd::library m_shell32; ///< shell32.dll resource library reference
wxIcon m_icon; ///< Panel icon
};

View File

@ -175,14 +175,8 @@ wxTLSCredentialsPanelBase::wxTLSCredentialsPanelBase( wxWindow* parent, wxWindow
this->SetSizer( sb_credentials );
this->Layout();
// Connect Events
m_cert_select->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( wxTLSCredentialsPanelBase::OnCertSelect ), NULL, this );
}
wxTLSCredentialsPanelBase::~wxTLSCredentialsPanelBase()
{
// Disconnect Events
m_cert_select->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( wxTLSCredentialsPanelBase::OnCertSelect ), NULL, this );
}

View File

@ -1426,7 +1426,7 @@
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRadioButton">OnCertSelect</event>
<event name="OnRadioButton"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>

View File

@ -81,10 +81,6 @@ class wxTLSCredentialsPanelBase : public wxPanel
wxRadioButton* m_cert_select;
wxChoice* m_cert_select_val;
wxCheckBox* m_remember;
// Virtual event handlers, overide them in your derived class
virtual void OnCertSelect( wxCommandEvent& event ) { event.Skip(); }
public:

View File

@ -311,9 +311,8 @@ bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i
// wxTLSCredentialsPanel
//////////////////////////////////////////////////////////////////////
wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
m_cred((eap::credentials_tls&)cred),
wxEAPCredentialsPanelBase<wxTLSCredentialsPanelBase>(prov, cfg, cred, pszCredTarget, parent, is_config)
wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred<eap::credentials_tls> &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{
// Load and set icon.
if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
@ -352,16 +351,14 @@ bool wxTLSCredentialsPanel::TransferDataToWindow()
}
if (is_found) {
m_cert_select ->SetValue(true);
m_cert_select_val->Enable(true);
m_cert_select->SetValue(true);
} else {
m_cert_none ->SetValue(true);
m_cert_select_val->Enable(false);
m_cert_none->SetValue(true);
if (!m_cert_select_val->IsEmpty())
m_cert_select_val->SetSelection(0);
}
return wxEAPCredentialsPanelBase<wxTLSCredentialsPanelBase>::TransferDataToWindow();
return wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>::TransferDataToWindow();
}
@ -379,14 +376,29 @@ bool wxTLSCredentialsPanel::TransferDataFromWindow()
// Inherited TransferDataFromWindow() calls m_cred.store().
// Therefore, call it only now, that m_cred is set.
return wxEAPCredentialsPanelBase<wxTLSCredentialsPanelBase>::TransferDataFromWindow();
return wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>::TransferDataFromWindow();
}
void wxTLSCredentialsPanel::OnCertSelect(wxCommandEvent& event)
void wxTLSCredentialsPanel::OnUpdateUI(wxUpdateUIEvent& event)
{
UNREFERENCED_PARAMETER(event);
m_cert_select_val->Enable(m_cert_select->GetValue());
if (!m_is_config && m_cfg.m_use_preshared) {
// Credential prompt mode & Using pre-shared credentials
// To avoid run-away selection of radio buttons, disable the selected one last.
if (m_cert_none->GetValue()) {
m_cert_select->Enable(false);
m_cert_none ->Enable(false);
} else {
m_cert_none ->Enable(false);
m_cert_select->Enable(false);
}
m_cert_select_val->Enable(false);
} else {
// Configuration mode or using own credentials. Selectively enable/disable controls.
m_cert_select_val->Enable(m_cert_select->GetValue());
}
wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>::OnUpdateUI(event);
}

View File

@ -231,7 +231,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov,
const eap::config_method_pap *cfg_inner_pap = dynamic_cast<const eap::config_method_pap*>(m_cfg.m_inner.get());
if (cfg_inner_pap) {
if (!((eap::credentials_ttls&)cred).m_inner) ((eap::credentials_ttls&)cred).m_inner.reset(new eap::credentials_pap(cred.m_module));
m_inner_cred = new wxPAPCredentialsPanel(m_prov, *cfg_inner_pap, *((eap::credentials_ttls&)cred).m_inner.get(), pszCredTarget, this, is_config);
m_inner_cred = new wxPAPCredentialsPanel(m_prov, *cfg_inner_pap, *(eap::credentials_pap*)((eap::credentials_ttls&)cred).m_inner.get(), pszCredTarget, this, is_config);
sb_content->Add(m_inner_cred, 0, wxALL|wxEXPAND, 5);
} else
assert(0); // Unsupported inner authentication method type.
@ -243,7 +243,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov,
m_outer_title->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) );
sb_content->Add(m_outer_title, 0, wxALL|wxALIGN_RIGHT, 5);
m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, (eap::credentials_tls&)cred, pszCredTarget, this, is_config);
m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, ((eap::credentials_ttls&)cred).m_outer, pszCredTarget, this, is_config);
sb_content->Add(m_outer_cred, 0, wxALL|wxEXPAND, 5);
this->SetSizer(sb_content);