From cadf7272df671c0f7f03075a4cae02da534fb3f3 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 3 Aug 2016 12:34:49 +0200 Subject: [PATCH] Credential UI revised to honor read-only, allow-save, and config/prompt mode correctly --- lib/EAPBase_UI/include/EAP_UI.h | 158 ++++++++++++++++++++++++++------ lib/EAPBase_UI/src/EAP_UI.cpp | 67 -------------- lib/PAP_UI/include/PAP_UI.h | 4 +- lib/TLS_UI/include/TLS_UI.h | 7 +- lib/TLS_UI/res/wxTLS_UI.cpp | 6 -- lib/TLS_UI/res/wxTLS_UI.fbp | 2 +- lib/TLS_UI/res/wxTLS_UI.h | 4 - lib/TLS_UI/src/TLS_UI.cpp | 36 +++++--- lib/TTLS_UI/src/TTLS_UI.cpp | 4 +- 9 files changed, 162 insertions(+), 126 deletions(-) diff --git a/lib/EAPBase_UI/include/EAP_UI.h b/lib/EAPBase_UI/include/EAP_UI.h index 16e54f0..9217f1a 100644 --- a/lib/EAPBase_UI/include/EAP_UI.h +++ b/lib/EAPBase_UI/include/EAP_UI.h @@ -52,12 +52,12 @@ template class wxEAPCredentialsConfigPanel; /// /// Base template for all credential entry panels /// -template class wxEAPCredentialsPanelBase; +template class wxEAPCredentialsPanelBase; /// /// Generic password credential entry panel /// -class wxPasswordCredentialsPanel; +template 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() : _("")); - 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 +template 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 +template +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 +const wxStringCharType *wxPasswordCredentialsPanel<_Tcred, _Tbase>::s_dummy_password = wxT("dummypass"); + inline bool wxSetIconFromResource(wxStaticBitmap *bmp, wxIcon &icon, HINSTANCE hinst, PCWSTR pszName) { diff --git a/lib/EAPBase_UI/src/EAP_UI.cpp b/lib/EAPBase_UI/src/EAP_UI.cpp index c679262..951824e 100644 --- a/lib/EAPBase_UI/src/EAP_UI.cpp +++ b/lib/EAPBase_UI/src/EAP_UI.cpp @@ -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(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::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::TransferDataFromWindow(); -} - - -const wxStringCharType *wxPasswordCredentialsPanel::s_dummy_password = wxT("dummypass"); diff --git a/lib/PAP_UI/include/PAP_UI.h b/lib/PAP_UI/include/PAP_UI.h index 9db7488..8d25707 100644 --- a/lib/PAP_UI/include/PAP_UI.h +++ b/lib/PAP_UI/include/PAP_UI.h @@ -25,7 +25,7 @@ /// /// PAP credential configuration panel /// -typedef wxEAPCredentialsConfigPanel wxPAPCredentialsConfigPanel; +typedef wxEAPCredentialsConfigPanel > wxPAPCredentialsConfigPanel; /// /// PAP configuration panel @@ -35,7 +35,7 @@ class wxPAPConfigPanel; /// /// PAP credential entry panel /// -typedef wxPasswordCredentialsPanel wxPAPCredentialsPanel; +typedef wxPasswordCredentialsPanel wxPAPCredentialsPanel; #pragma once diff --git a/lib/TLS_UI/include/TLS_UI.h b/lib/TLS_UI/include/TLS_UI.h index 128f2bc..59f36cc 100644 --- a/lib/TLS_UI/include/TLS_UI.h +++ b/lib/TLS_UI/include/TLS_UI.h @@ -248,7 +248,7 @@ protected: }; -class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase +class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase { 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 &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 }; diff --git a/lib/TLS_UI/res/wxTLS_UI.cpp b/lib/TLS_UI/res/wxTLS_UI.cpp index 66ea0d4..87e2cf3 100644 --- a/lib/TLS_UI/res/wxTLS_UI.cpp +++ b/lib/TLS_UI/res/wxTLS_UI.cpp @@ -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 ); - } diff --git a/lib/TLS_UI/res/wxTLS_UI.fbp b/lib/TLS_UI/res/wxTLS_UI.fbp index 7cfe90d..dfeba30 100644 --- a/lib/TLS_UI/res/wxTLS_UI.fbp +++ b/lib/TLS_UI/res/wxTLS_UI.fbp @@ -1426,7 +1426,7 @@ - OnCertSelect + diff --git a/lib/TLS_UI/res/wxTLS_UI.h b/lib/TLS_UI/res/wxTLS_UI.h index 6b05d42..c991754 100644 --- a/lib/TLS_UI/res/wxTLS_UI.h +++ b/lib/TLS_UI/res/wxTLS_UI.h @@ -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: diff --git a/lib/TLS_UI/src/TLS_UI.cpp b/lib/TLS_UI/src/TLS_UI.cpp index 710c892..3ccd850 100644 --- a/lib/TLS_UI/src/TLS_UI.cpp +++ b/lib/TLS_UI/src/TLS_UI.cpp @@ -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(prov, cfg, cred, pszCredTarget, parent, is_config) +wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) : + wxEAPCredentialsPanelBase(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::TransferDataToWindow(); + return wxEAPCredentialsPanelBase::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::TransferDataFromWindow(); + return wxEAPCredentialsPanelBase::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::OnUpdateUI(event); } diff --git a/lib/TTLS_UI/src/TTLS_UI.cpp b/lib/TTLS_UI/src/TTLS_UI.cpp index 4e9f6f2..c55332c 100644 --- a/lib/TTLS_UI/src/TTLS_UI.cpp +++ b/lib/TTLS_UI/src/TTLS_UI.cpp @@ -231,7 +231,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_pap *cfg_inner_pap = dynamic_cast(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);