Update wxCredentialEntryDialog to use wxWebCredentials

As a side effect, make wxWebCredentials default-constructible.

Also demonstrate using wxCredentialEntryDialog in the sample.
This commit is contained in:
Vadim Zeitlin
2021-01-10 01:53:32 +01:00
parent 31a441e814
commit abcc31c6b2
6 changed files with 120 additions and 44 deletions

View File

@@ -15,6 +15,7 @@
#if wxUSE_CREDENTIALDLG #if wxUSE_CREDENTIALDLG
#include "wx/dialog.h" #include "wx/dialog.h"
#include "wx/webrequest.h"
class WXDLLIMPEXP_CORE wxGenericCredentialEntryDialog : public wxDialog class WXDLLIMPEXP_CORE wxGenericCredentialEntryDialog : public wxDialog
{ {
@@ -23,28 +24,23 @@ public:
wxGenericCredentialEntryDialog(wxWindow* parent, const wxString& message, wxGenericCredentialEntryDialog(wxWindow* parent, const wxString& message,
const wxString& title, const wxString& title,
const wxString& user = "", const wxWebCredentials& cred = wxWebCredentials());
const wxString& password = "");
bool Create(wxWindow* parent, const wxString& message, bool Create(wxWindow* parent, const wxString& message,
const wxString& title, const wxString& title,
const wxString& user = "", const wxWebCredentials& cred = wxWebCredentials());
const wxString& password = "");
wxString GetUser() const { return m_userTextCtrl->GetValue(); }
void SetUser(const wxString& user) { m_userTextCtrl->SetValue(user); } void SetUser(const wxString& user) { m_userTextCtrl->SetValue(user); }
wxString GetPassword() const { return m_passwordTextCtrl->GetValue(); }
void SetPassword(const wxString& password) void SetPassword(const wxString& password)
{ m_passwordTextCtrl->SetValue(password); } { m_passwordTextCtrl->SetValue(password); }
wxWebCredentials GetCredentials() const;
private: private:
wxTextCtrl* m_userTextCtrl; wxTextCtrl* m_userTextCtrl;
wxTextCtrl* m_passwordTextCtrl; wxTextCtrl* m_passwordTextCtrl;
void Init(const wxString& message, void Init(const wxString& message, const wxWebCredentials& cred);
const wxString& user,
const wxString& password);
wxDECLARE_NO_COPY_CLASS(wxGenericCredentialEntryDialog); wxDECLARE_NO_COPY_CLASS(wxGenericCredentialEntryDialog);
}; };

View File

@@ -37,7 +37,8 @@ typedef wxObjectDataPtr<wxWebSessionImpl> wxWebSessionImplPtr;
class wxWebCredentials class wxWebCredentials
{ {
public: public:
wxWebCredentials(const wxString& user, const wxSecretValue& password) wxWebCredentials(const wxString& user = wxString(),
const wxSecretValue& password = wxSecretValue())
: m_user(user), m_password(password) : m_user(user), m_password(password)
{ {
} }

View File

@@ -9,8 +9,37 @@
@class wxCredentialEntryDialog @class wxCredentialEntryDialog
This class represents a dialog that requests a user name and a password This class represents a dialog that requests a user name and a password
from the user. It is implemented as a generic wxWidgets dialog on all from the user.
platforms.
Currently it is implemented as a generic wxWidgets dialog on all platforms.
Simple example of using this dialog assuming @c MyFrame object has a member
@c m_request of wxWebRequest type:
@code
void MyFrame::OnWebRequestState(wxWebRequestEvent& evt)
{
if ( evt.GetState() == wxWebRequest::State_Unauthorized )
{
wxCredentialEntryDialog dialog
(
this,
wxString::Format
(
"Please enter credentials for accessing "
"the web page at %s",
evt.GetResponse().GetURL()
),
"My Application Title"
);
if ( dialog.ShowModal() == wxID_OK )
{
m_request.GetAuthChallenge().
SetCredentials(dialog.GetCredentials());
}
//else: the dialog was cancelled
}
}
@endcode
@note For secure saving and loading users and passwords, have a look at @note For secure saving and loading users and passwords, have a look at
wxSecretStore. wxSecretStore.
@@ -41,8 +70,7 @@ public:
*/ */
wxCredentialEntryDialog(wxWindow* parent, const wxString& message, wxCredentialEntryDialog(wxWindow* parent, const wxString& message,
const wxString& title, const wxString& title,
const wxString& user = "", const wxWebCredentials& cred = wxWebCredentials());
const wxString& password = "");
/** /**
Create the dialog constructed using the default constructor. Create the dialog constructed using the default constructor.
@@ -53,20 +81,19 @@ public:
Message to show on the dialog. Message to show on the dialog.
@param title @param title
The title of the dialog. The title of the dialog.
@param user @param cred
The default user value. The default username and password to use (optional).
@param password
The default password.
*/ */
bool Create(wxWindow* parent, const wxString& message, bool Create(wxWindow* parent, const wxString& message,
const wxString& title, const wxString& title,
const wxString& user = "", const wxWebCredentials& cred = wxWebCredentials());
const wxString& password = "");
/** /**
Returns the entered user name. Returns the credentials entered by the user.
This should be called if ShowModal() returned ::wxID_OK.
*/ */
wxString GetUser() const; wxWebCredentials GetCredentials() const;
/** /**
Sets the current user name. Sets the current user name.
@@ -77,11 +104,6 @@ public:
*/ */
void SetUser(const wxString& user); void SetUser(const wxString& user);
/**
Returns the entered password.
*/
wxString GetPassword() const;
/** /**
Sets the current password. Sets the current password.

View File

@@ -425,7 +425,8 @@ public:
Note that the password is a wxSecretValue object, to construct it from Note that the password is a wxSecretValue object, to construct it from
a string you need to explicitly use wxSecretValue ctor. a string you need to explicitly use wxSecretValue ctor.
*/ */
wxWebCredentials(const wxString& user, const wxSecretValue& password); wxWebCredentials(const wxString& user = wxString(),
const wxSecretValue& password = wxSecretValue());
/// Return the user. /// Return the user.
const wxString& GetUser() const; const wxString& GetUser() const;

View File

@@ -20,6 +20,7 @@
#include "wx/notebook.h" #include "wx/notebook.h"
#include "wx/artprov.h" #include "wx/artprov.h"
#include "wx/creddlg.h"
#include "wx/webrequest.h" #include "wx/webrequest.h"
#include "wx/filedlg.h" #include "wx/filedlg.h"
#include "wx/image.h" #include "wx/image.h"
@@ -252,11 +253,7 @@ public:
m_startButton->Enable(evt.GetState() != wxWebRequest::State_Active); m_startButton->Enable(evt.GetState() != wxWebRequest::State_Active);
m_cancelButton->Enable(evt.GetState() == wxWebRequest::State_Active); m_cancelButton->Enable(evt.GetState() == wxWebRequest::State_Active);
if ( evt.GetState() != wxWebRequest::State_Active ) bool stillActive = false;
{
m_currentRequest = wxWebRequest();
m_downloadProgressTimer.Stop();
}
switch (evt.GetState()) switch (evt.GetState())
{ {
@@ -315,9 +312,53 @@ public:
wxLogStatus(this, "Cancelled"); wxLogStatus(this, "Cancelled");
break; break;
default: case wxWebRequest::State_Unauthorized:
{
wxWebAuthChallenge
auth = m_currentRequest.GetAuthChallenge();
if ( !auth.IsOk() )
{
wxLogStatus("Unexpectedly missing auth challenge");
break; break;
} }
wxCredentialEntryDialog dialog
(
this,
wxString::Format
(
"Please enter credentials for accessing\n"
"%s",
evt.GetResponse().GetURL()
),
"wxWidgets web request sample",
m_credentials
);
if ( dialog.ShowModal() == wxID_OK )
{
m_credentials = dialog.GetCredentials();
auth.SetCredentials(m_credentials);
wxLogStatus("Trying to authenticate...");
stillActive = true;
}
}
break;
case wxWebRequest::State_Active:
stillActive = true;
break;
case wxWebRequest::State_Idle:
// Nothing special to do for this state.
break;
}
if ( !stillActive )
{
m_currentRequest = wxWebRequest();
m_downloadProgressTimer.Stop();
}
} }
void OnRequestData(wxWebRequestEvent& evt) void OnRequestData(wxWebRequestEvent& evt)
@@ -438,6 +479,11 @@ private:
wxStaticText* m_advCountStaticText; wxStaticText* m_advCountStaticText;
wxLongLong m_advCount; wxLongLong m_advCount;
// Normally it would be a bad idea to permanently store credentials like
// this, we should use wxSecretStore to load them as needed, but let's keep
// things simple in this example.
wxWebCredentials m_credentials;
}; };
class WebRequestApp : public wxApp class WebRequestApp : public wxApp

View File

@@ -29,25 +29,25 @@ wxGenericCredentialEntryDialog::wxGenericCredentialEntryDialog()
wxGenericCredentialEntryDialog::wxGenericCredentialEntryDialog( wxGenericCredentialEntryDialog::wxGenericCredentialEntryDialog(
wxWindow* parent, const wxString& message, const wxString& title, wxWindow* parent, const wxString& message, const wxString& title,
const wxString& user, const wxString& password): const wxWebCredentials& cred) :
wxDialog(parent, wxID_ANY, title) wxDialog(parent, wxID_ANY, title)
{ {
Init(message, user, password); Init(message, cred);
} }
bool wxGenericCredentialEntryDialog::Create(wxWindow* parent, bool wxGenericCredentialEntryDialog::Create(wxWindow* parent,
const wxString& message, const wxString& title, const wxString& user, const wxString& message, const wxString& title,
const wxString& password) const wxWebCredentials& cred)
{ {
if ( !wxDialog::Create(parent, wxID_ANY, title) ) if ( !wxDialog::Create(parent, wxID_ANY, title) )
return false; return false;
Init(message, user, password); Init(message, cred);
return true; return true;
} }
void wxGenericCredentialEntryDialog::Init(const wxString& message, void wxGenericCredentialEntryDialog::Init(const wxString& message,
const wxString& user, const wxString& password) const wxWebCredentials& cred)
{ {
wxSizer* topsizer = new wxBoxSizer(wxVERTICAL); wxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
@@ -55,13 +55,17 @@ void wxGenericCredentialEntryDialog::Init(const wxString& message,
topsizer->Add(new wxStaticText(this, wxID_ANY, _("Username:")), topsizer->Add(new wxStaticText(this, wxID_ANY, _("Username:")),
wxSizerFlags().HorzBorder()); wxSizerFlags().HorzBorder());
m_userTextCtrl = new wxTextCtrl(this, wxID_ANY, user, wxDefaultPosition, wxSize(FromDIP(300), wxDefaultCoord)); m_userTextCtrl = new wxTextCtrl(this, wxID_ANY, cred.GetUser(),
wxDefaultPosition,
wxSize(FromDIP(300), wxDefaultCoord));
topsizer->Add(m_userTextCtrl, wxSizerFlags().Expand().Border()); topsizer->Add(m_userTextCtrl, wxSizerFlags().Expand().Border());
topsizer->Add(new wxStaticText(this, wxID_ANY, _("Password:")), topsizer->Add(new wxStaticText(this, wxID_ANY, _("Password:")),
wxSizerFlags().HorzBorder()); wxSizerFlags().HorzBorder());
m_passwordTextCtrl = new wxTextCtrl(this, wxID_ANY, password, m_passwordTextCtrl = new wxTextCtrl(this, wxID_ANY,
wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); wxSecretString(cred.GetPassword()),
wxDefaultPosition, wxDefaultSize,
wxTE_PASSWORD);
topsizer->Add(m_passwordTextCtrl, wxSizerFlags().Expand().Border()); topsizer->Add(m_passwordTextCtrl, wxSizerFlags().Expand().Border());
topsizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border()); topsizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border());
@@ -70,4 +74,10 @@ void wxGenericCredentialEntryDialog::Init(const wxString& message,
m_userTextCtrl->SetFocus(); m_userTextCtrl->SetFocus();
} }
wxWebCredentials wxGenericCredentialEntryDialog::GetCredentials() const
{
return wxWebCredentials(m_userTextCtrl->GetValue(),
wxSecretValue(m_passwordTextCtrl->GetValue()));
}
#endif // wxUSE_CREDENTIALDLG #endif // wxUSE_CREDENTIALDLG