diff --git a/include/wx/msw/private/webrequest_winhttp.h b/include/wx/msw/private/webrequest_winhttp.h index dca28f6ce5..044da9a9e5 100644 --- a/include/wx/msw/private/webrequest_winhttp.h +++ b/include/wx/msw/private/webrequest_winhttp.h @@ -53,7 +53,7 @@ public: bool Init(); - void SetCredentials(const wxString& user, const wxString& password) wxOVERRIDE; + void SetCredentials(const wxWebCredentials& cred) wxOVERRIDE; private: wxWebRequestWinHTTP& m_request; diff --git a/include/wx/private/webrequest.h b/include/wx/private/webrequest.h index fca59cf843..69e94d8dbb 100644 --- a/include/wx/private/webrequest.h +++ b/include/wx/private/webrequest.h @@ -27,8 +27,7 @@ public: wxWebAuthChallenge::Source GetSource() const { return m_source; } - virtual void - SetCredentials(const wxString& user, const wxString& password) = 0; + virtual void SetCredentials(const wxWebCredentials& cred) = 0; protected: explicit wxWebAuthChallengeImpl(wxWebAuthChallenge::Source source) diff --git a/include/wx/private/webrequest_curl.h b/include/wx/private/webrequest_curl.h index 42669a5530..f31adb806f 100644 --- a/include/wx/private/webrequest_curl.h +++ b/include/wx/private/webrequest_curl.h @@ -31,7 +31,7 @@ public: bool Init(); - void SetCredentials(const wxString& user, const wxString& password) wxOVERRIDE; + void SetCredentials(const wxWebCredentials& cred) wxOVERRIDE; private: wxWebRequestCURL& m_request; diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index 98bd71f3fd..4433d218ab 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -16,6 +16,7 @@ #include "wx/event.h" #include "wx/object.h" +#include "wx/secretstore.h" #include "wx/stream.h" #include "wx/versioninfo.h" @@ -33,6 +34,22 @@ typedef wxObjectDataPtr wxWebRequestImplPtr; typedef wxObjectDataPtr wxWebResponseImplPtr; typedef wxObjectDataPtr wxWebSessionImplPtr; +class wxWebCredentials +{ +public: + wxWebCredentials(const wxString& user, const wxSecretValue& password) + : m_user(user), m_password(password) + { + } + + const wxString& GetUser() const { return m_user; } + const wxSecretValue& GetPassword() const { return m_password; } + +private: + wxString m_user; + wxSecretValue m_password; +}; + class WXDLLIMPEXP_NET wxWebAuthChallenge { public: @@ -51,7 +68,7 @@ public: Source GetSource() const; - void SetCredentials(const wxString& user, const wxString& password); + void SetCredentials(const wxWebCredentials& cred); private: // Ctor is used by wxWebRequest only. diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index 90f3b16db1..54db0b1529 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -372,7 +372,14 @@ public: Authentication challenge information available via wxWebRequest::GetAuthChallenge(). - Use SetCredentials() to provide user credentials. + Use SetCredentials() to provide user credentials, e.g. + @code + if ( request.GetState() == wxWebRequest::State_Unauthorized ) + { + wxWebCredentials cred("me", wxSecretValue("s3krit")); + request.GetAuthChallenge().SetCredentials(cred); + } + @endcode */ class wxWebAuthChallenge { @@ -394,12 +401,41 @@ public: /** Used to provide user credentials to the authentication challenge. - @param user - User name. - @param password - The users password. + @see wxWebCredentials */ - void SetCredentials(const wxString& user, const wxString& password); + void SetCredentials(const wxWebCredentials& cred); +}; + +/** + Simple class containing the username and password to use for authenticating. + + @since 3.1.5 + + @library{wxnet} + @category{net} + + @see wxWebAuthChallenge + */ +class wxWebCredentials +{ +public: + /** + Create the new credentials object. + + 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); + + /// Return the user. + const wxString& GetUser() const; + + /** + Return the password. + + @see wxSecretString + */ + const wxSecretValue& GetPassword() const; }; /** diff --git a/src/common/webrequest.cpp b/src/common/webrequest.cpp index f5b9c40e3b..12d78039bf 100644 --- a/src/common/webrequest.cpp +++ b/src/common/webrequest.cpp @@ -504,12 +504,11 @@ wxWebAuthChallenge::Source wxWebAuthChallenge::GetSource() const } void -wxWebAuthChallenge::SetCredentials(const wxString& user, - const wxString& password) +wxWebAuthChallenge::SetCredentials(const wxWebCredentials& cred) { wxCHECK_IMPL_VOID(); - m_impl->SetCredentials(user, password); + m_impl->SetCredentials(cred); } // diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp index f9014ef7bd..73f4e4c1c8 100644 --- a/src/common/webrequest_curl.cpp +++ b/src/common/webrequest_curl.cpp @@ -319,9 +319,15 @@ bool wxWebAuthChallengeCURL::Init() return true; } -void wxWebAuthChallengeCURL::SetCredentials(const wxString& user, const wxString& password) +void wxWebAuthChallengeCURL::SetCredentials(const wxWebCredentials& cred) { - wxString authStr = wxString::Format("%s:%s", user, password); + const wxSecretString authStr = + wxString::Format + ( + "%s:%s", + cred.GetUser(), + static_cast(wxSecretString(cred.GetPassword())) + ); curl_easy_setopt(m_request.GetHandle(), (GetSource() == wxWebAuthChallenge::Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD, static_cast(authStr.mb_str())); diff --git a/src/msw/webrequest_winhttp.cpp b/src/msw/webrequest_winhttp.cpp index 654866cd39..a097f5d144 100644 --- a/src/msw/webrequest_winhttp.cpp +++ b/src/msw/webrequest_winhttp.cpp @@ -505,16 +505,15 @@ bool wxWebAuthChallengeWinHTTP::Init() } void -wxWebAuthChallengeWinHTTP::SetCredentials(const wxString& user, - const wxString& password) +wxWebAuthChallengeWinHTTP::SetCredentials(const wxWebCredentials& cred) { if ( !::WinHttpSetCredentials ( m_request.GetHandle(), m_target, m_selectedScheme, - user.wc_str(), - password.wc_str(), + cred.GetUser().wc_str(), + wxSecretString(cred.GetPassword()).wc_str(), wxRESERVED_PARAM ) ) { diff --git a/tests/net/webrequest.cpp b/tests/net/webrequest.cpp index d5ed0a5958..7356789d46 100644 --- a/tests/net/webrequest.cpp +++ b/tests/net/webrequest.cpp @@ -108,6 +108,13 @@ public: REQUIRE( request.GetResponse().GetStatus() == requiredStatus ); } + // Precondition: we must have an auth challenge. + void UseCredentials(const wxString& user, const wxString& password) + { + request.GetAuthChallenge().SetCredentials( + wxWebCredentials(user, wxSecretValue(password))); + } + wxString baseURL; wxEventLoop loop; wxWebRequest request; @@ -200,7 +207,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") SECTION("Good password") { - request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets"); + UseCredentials("wxtest", "wxwidgets"); loop.Run(); CHECK( request.GetResponse().GetStatus() == 200 ); CHECK( request.GetState() == wxWebRequest::State_Completed ); @@ -208,7 +215,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") SECTION("Bad password") { - request.GetAuthChallenge().SetCredentials("wxtest", "foobar"); + UseCredentials("wxtest", "foobar"); loop.Run(); CHECK( request.GetResponse().GetStatus() == 401 ); CHECK( request.GetState() == wxWebRequest::State_Unauthorized ); @@ -229,7 +236,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") SECTION("Good password") { - request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets"); + UseCredentials("wxtest", "wxwidgets"); loop.Run(); CHECK( request.GetResponse().GetStatus() == 200 ); CHECK( request.GetState() == wxWebRequest::State_Completed ); @@ -237,7 +244,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") SECTION("Bad password") { - request.GetAuthChallenge().SetCredentials("foo", "bar"); + UseCredentials("foo", "bar"); loop.Run(); CHECK( request.GetResponse().GetStatus() == 401 ); CHECK( request.GetState() == wxWebRequest::State_Unauthorized );