Add wxWebCredentials and use it in SetCredentials()

Prefer using a class encapsulating both the user name and the password
to using a pair of variables.
This commit is contained in:
Vadim Zeitlin
2021-01-10 01:22:40 +01:00
parent fe197d7527
commit 1e6d6be8bb
9 changed files with 87 additions and 24 deletions

View File

@@ -53,7 +53,7 @@ public:
bool Init(); bool Init();
void SetCredentials(const wxString& user, const wxString& password) wxOVERRIDE; void SetCredentials(const wxWebCredentials& cred) wxOVERRIDE;
private: private:
wxWebRequestWinHTTP& m_request; wxWebRequestWinHTTP& m_request;

View File

@@ -27,8 +27,7 @@ public:
wxWebAuthChallenge::Source GetSource() const { return m_source; } wxWebAuthChallenge::Source GetSource() const { return m_source; }
virtual void virtual void SetCredentials(const wxWebCredentials& cred) = 0;
SetCredentials(const wxString& user, const wxString& password) = 0;
protected: protected:
explicit wxWebAuthChallengeImpl(wxWebAuthChallenge::Source source) explicit wxWebAuthChallengeImpl(wxWebAuthChallenge::Source source)

View File

@@ -31,7 +31,7 @@ public:
bool Init(); bool Init();
void SetCredentials(const wxString& user, const wxString& password) wxOVERRIDE; void SetCredentials(const wxWebCredentials& cred) wxOVERRIDE;
private: private:
wxWebRequestCURL& m_request; wxWebRequestCURL& m_request;

View File

@@ -16,6 +16,7 @@
#include "wx/event.h" #include "wx/event.h"
#include "wx/object.h" #include "wx/object.h"
#include "wx/secretstore.h"
#include "wx/stream.h" #include "wx/stream.h"
#include "wx/versioninfo.h" #include "wx/versioninfo.h"
@@ -33,6 +34,22 @@ typedef wxObjectDataPtr<wxWebRequestImpl> wxWebRequestImplPtr;
typedef wxObjectDataPtr<wxWebResponseImpl> wxWebResponseImplPtr; typedef wxObjectDataPtr<wxWebResponseImpl> wxWebResponseImplPtr;
typedef wxObjectDataPtr<wxWebSessionImpl> wxWebSessionImplPtr; typedef wxObjectDataPtr<wxWebSessionImpl> 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 class WXDLLIMPEXP_NET wxWebAuthChallenge
{ {
public: public:
@@ -51,7 +68,7 @@ public:
Source GetSource() const; Source GetSource() const;
void SetCredentials(const wxString& user, const wxString& password); void SetCredentials(const wxWebCredentials& cred);
private: private:
// Ctor is used by wxWebRequest only. // Ctor is used by wxWebRequest only.

View File

@@ -372,7 +372,14 @@ public:
Authentication challenge information available via Authentication challenge information available via
wxWebRequest::GetAuthChallenge(). 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 class wxWebAuthChallenge
{ {
@@ -394,12 +401,41 @@ public:
/** /**
Used to provide user credentials to the authentication challenge. Used to provide user credentials to the authentication challenge.
@param user @see wxWebCredentials
User name.
@param password
The users password.
*/ */
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;
}; };
/** /**

View File

@@ -504,12 +504,11 @@ wxWebAuthChallenge::Source wxWebAuthChallenge::GetSource() const
} }
void void
wxWebAuthChallenge::SetCredentials(const wxString& user, wxWebAuthChallenge::SetCredentials(const wxWebCredentials& cred)
const wxString& password)
{ {
wxCHECK_IMPL_VOID(); wxCHECK_IMPL_VOID();
m_impl->SetCredentials(user, password); m_impl->SetCredentials(cred);
} }
// //

View File

@@ -319,9 +319,15 @@ bool wxWebAuthChallengeCURL::Init()
return true; 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<const wxString&>(wxSecretString(cred.GetPassword()))
);
curl_easy_setopt(m_request.GetHandle(), curl_easy_setopt(m_request.GetHandle(),
(GetSource() == wxWebAuthChallenge::Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD, (GetSource() == wxWebAuthChallenge::Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD,
static_cast<const char*>(authStr.mb_str())); static_cast<const char*>(authStr.mb_str()));

View File

@@ -505,16 +505,15 @@ bool wxWebAuthChallengeWinHTTP::Init()
} }
void void
wxWebAuthChallengeWinHTTP::SetCredentials(const wxString& user, wxWebAuthChallengeWinHTTP::SetCredentials(const wxWebCredentials& cred)
const wxString& password)
{ {
if ( !::WinHttpSetCredentials if ( !::WinHttpSetCredentials
( (
m_request.GetHandle(), m_request.GetHandle(),
m_target, m_target,
m_selectedScheme, m_selectedScheme,
user.wc_str(), cred.GetUser().wc_str(),
password.wc_str(), wxSecretString(cred.GetPassword()).wc_str(),
wxRESERVED_PARAM wxRESERVED_PARAM
) ) ) )
{ {

View File

@@ -108,6 +108,13 @@ public:
REQUIRE( request.GetResponse().GetStatus() == requiredStatus ); 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; wxString baseURL;
wxEventLoop loop; wxEventLoop loop;
wxWebRequest request; wxWebRequest request;
@@ -200,7 +207,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
SECTION("Good password") SECTION("Good password")
{ {
request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets"); UseCredentials("wxtest", "wxwidgets");
loop.Run(); loop.Run();
CHECK( request.GetResponse().GetStatus() == 200 ); CHECK( request.GetResponse().GetStatus() == 200 );
CHECK( request.GetState() == wxWebRequest::State_Completed ); CHECK( request.GetState() == wxWebRequest::State_Completed );
@@ -208,7 +215,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
SECTION("Bad password") SECTION("Bad password")
{ {
request.GetAuthChallenge().SetCredentials("wxtest", "foobar"); UseCredentials("wxtest", "foobar");
loop.Run(); loop.Run();
CHECK( request.GetResponse().GetStatus() == 401 ); CHECK( request.GetResponse().GetStatus() == 401 );
CHECK( request.GetState() == wxWebRequest::State_Unauthorized ); CHECK( request.GetState() == wxWebRequest::State_Unauthorized );
@@ -229,7 +236,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
SECTION("Good password") SECTION("Good password")
{ {
request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets"); UseCredentials("wxtest", "wxwidgets");
loop.Run(); loop.Run();
CHECK( request.GetResponse().GetStatus() == 200 ); CHECK( request.GetResponse().GetStatus() == 200 );
CHECK( request.GetState() == wxWebRequest::State_Completed ); CHECK( request.GetState() == wxWebRequest::State_Completed );
@@ -237,7 +244,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
SECTION("Bad password") SECTION("Bad password")
{ {
request.GetAuthChallenge().SetCredentials("foo", "bar"); UseCredentials("foo", "bar");
loop.Run(); loop.Run();
CHECK( request.GetResponse().GetStatus() == 401 ); CHECK( request.GetResponse().GetStatus() == 401 );
CHECK( request.GetState() == wxWebRequest::State_Unauthorized ); CHECK( request.GetState() == wxWebRequest::State_Unauthorized );