diff --git a/include/wx/generic/creddlgg.h b/include/wx/generic/creddlgg.h index d2f58d6a1b..9f99cb8b48 100644 --- a/include/wx/generic/creddlgg.h +++ b/include/wx/generic/creddlgg.h @@ -15,6 +15,7 @@ #if wxUSE_CREDENTIALDLG #include "wx/dialog.h" +#include "wx/webrequest.h" class WXDLLIMPEXP_CORE wxGenericCredentialEntryDialog : public wxDialog { @@ -23,28 +24,23 @@ public: wxGenericCredentialEntryDialog(wxWindow* parent, const wxString& message, const wxString& title, - const wxString& user = "", - const wxString& password = ""); + const wxWebCredentials& cred = wxWebCredentials()); bool Create(wxWindow* parent, const wxString& message, const wxString& title, - const wxString& user = "", - const wxString& password = ""); + const wxWebCredentials& cred = wxWebCredentials()); - wxString GetUser() const { return m_userTextCtrl->GetValue(); } void SetUser(const wxString& user) { m_userTextCtrl->SetValue(user); } - - wxString GetPassword() const { return m_passwordTextCtrl->GetValue(); } void SetPassword(const wxString& password) { m_passwordTextCtrl->SetValue(password); } + wxWebCredentials GetCredentials() const; + private: wxTextCtrl* m_userTextCtrl; wxTextCtrl* m_passwordTextCtrl; - void Init(const wxString& message, - const wxString& user, - const wxString& password); + void Init(const wxString& message, const wxWebCredentials& cred); wxDECLARE_NO_COPY_CLASS(wxGenericCredentialEntryDialog); }; diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index 4433d218ab..73ab9641d7 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -37,7 +37,8 @@ typedef wxObjectDataPtr wxWebSessionImplPtr; class wxWebCredentials { public: - wxWebCredentials(const wxString& user, const wxSecretValue& password) + wxWebCredentials(const wxString& user = wxString(), + const wxSecretValue& password = wxSecretValue()) : m_user(user), m_password(password) { } diff --git a/interface/wx/creddlg.h b/interface/wx/creddlg.h index 37b2b59646..e80d274ba5 100644 --- a/interface/wx/creddlg.h +++ b/interface/wx/creddlg.h @@ -9,8 +9,37 @@ @class wxCredentialEntryDialog 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 - platforms. + from the user. + + 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 wxSecretStore. @@ -41,8 +70,7 @@ public: */ wxCredentialEntryDialog(wxWindow* parent, const wxString& message, const wxString& title, - const wxString& user = "", - const wxString& password = ""); + const wxWebCredentials& cred = wxWebCredentials()); /** Create the dialog constructed using the default constructor. @@ -53,20 +81,19 @@ public: Message to show on the dialog. @param title The title of the dialog. - @param user - The default user value. - @param password - The default password. + @param cred + The default username and password to use (optional). */ bool Create(wxWindow* parent, const wxString& message, const wxString& title, - const wxString& user = "", - const wxString& password = ""); + const wxWebCredentials& cred = wxWebCredentials()); /** - 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. @@ -77,11 +104,6 @@ public: */ void SetUser(const wxString& user); - /** - Returns the entered password. - */ - wxString GetPassword() const; - /** Sets the current password. diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index 54db0b1529..61fe2e6b03 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -425,7 +425,8 @@ public: Note that the password is a wxSecretValue object, to construct it from 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. const wxString& GetUser() const; diff --git a/samples/webrequest/webrequest.cpp b/samples/webrequest/webrequest.cpp index 5b0bb505e2..837754347d 100644 --- a/samples/webrequest/webrequest.cpp +++ b/samples/webrequest/webrequest.cpp @@ -20,6 +20,7 @@ #include "wx/notebook.h" #include "wx/artprov.h" +#include "wx/creddlg.h" #include "wx/webrequest.h" #include "wx/filedlg.h" #include "wx/image.h" @@ -252,11 +253,7 @@ public: m_startButton->Enable(evt.GetState() != wxWebRequest::State_Active); m_cancelButton->Enable(evt.GetState() == wxWebRequest::State_Active); - if ( evt.GetState() != wxWebRequest::State_Active ) - { - m_currentRequest = wxWebRequest(); - m_downloadProgressTimer.Stop(); - } + bool stillActive = false; switch (evt.GetState()) { @@ -315,8 +312,52 @@ public: wxLogStatus(this, "Cancelled"); break; - default: + case wxWebRequest::State_Unauthorized: + { + wxWebAuthChallenge + auth = m_currentRequest.GetAuthChallenge(); + if ( !auth.IsOk() ) + { + wxLogStatus("Unexpectedly missing auth challenge"); + 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(); } } @@ -438,6 +479,11 @@ private: wxStaticText* m_advCountStaticText; 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 diff --git a/src/generic/creddlgg.cpp b/src/generic/creddlgg.cpp index b290670869..87376bad72 100644 --- a/src/generic/creddlgg.cpp +++ b/src/generic/creddlgg.cpp @@ -29,25 +29,25 @@ wxGenericCredentialEntryDialog::wxGenericCredentialEntryDialog() wxGenericCredentialEntryDialog::wxGenericCredentialEntryDialog( wxWindow* parent, const wxString& message, const wxString& title, - const wxString& user, const wxString& password): + const wxWebCredentials& cred) : wxDialog(parent, wxID_ANY, title) { - Init(message, user, password); + Init(message, cred); } bool wxGenericCredentialEntryDialog::Create(wxWindow* parent, - const wxString& message, const wxString& title, const wxString& user, - const wxString& password) + const wxString& message, const wxString& title, + const wxWebCredentials& cred) { if ( !wxDialog::Create(parent, wxID_ANY, title) ) return false; - Init(message, user, password); + Init(message, cred); return true; } void wxGenericCredentialEntryDialog::Init(const wxString& message, - const wxString& user, const wxString& password) + const wxWebCredentials& cred) { wxSizer* topsizer = new wxBoxSizer(wxVERTICAL); @@ -55,13 +55,17 @@ void wxGenericCredentialEntryDialog::Init(const wxString& message, topsizer->Add(new wxStaticText(this, wxID_ANY, _("Username:")), 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(new wxStaticText(this, wxID_ANY, _("Password:")), wxSizerFlags().HorzBorder()); - m_passwordTextCtrl = new wxTextCtrl(this, wxID_ANY, password, - wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); + m_passwordTextCtrl = new wxTextCtrl(this, wxID_ANY, + wxSecretString(cred.GetPassword()), + wxDefaultPosition, wxDefaultSize, + wxTE_PASSWORD); topsizer->Add(m_passwordTextCtrl, wxSizerFlags().Expand().Border()); topsizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border()); @@ -70,4 +74,10 @@ void wxGenericCredentialEntryDialog::Init(const wxString& message, m_userTextCtrl->SetFocus(); } +wxWebCredentials wxGenericCredentialEntryDialog::GetCredentials() const +{ + return wxWebCredentials(m_userTextCtrl->GetValue(), + wxSecretValue(m_passwordTextCtrl->GetValue())); +} + #endif // wxUSE_CREDENTIALDLG