mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-01-31 18:07:14 +01:00
4a6bfc086c
Switched to POCO library for unified platform/library interface. Deprecated the external module API. It was creating more problems than solving. Removed most built-in libraries in favor of system libraries for easier maintenance. Cleaned and secured code with help from static analyzers.
275 lines
9.5 KiB
C++
275 lines
9.5 KiB
C++
//
|
|
// OAuth10Credentials.h
|
|
//
|
|
// Library: Net
|
|
// Package: OAuth
|
|
// Module: OAuth10Credentials
|
|
//
|
|
// Definition of the OAuth10Credentials class.
|
|
//
|
|
// Copyright (c) 2014, Applied Informatics Software Engineering GmbH.
|
|
// and Contributors.
|
|
//
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
//
|
|
|
|
|
|
#ifndef Net_OAuth10Credentials_INCLUDED
|
|
#define Net_OAuth10Credentials_INCLUDED
|
|
|
|
|
|
#include "Poco/Net/Net.h"
|
|
#include "Poco/URI.h"
|
|
|
|
|
|
namespace Poco {
|
|
namespace Net {
|
|
|
|
|
|
class HTTPRequest;
|
|
class HTMLForm;
|
|
|
|
|
|
class Net_API OAuth10Credentials
|
|
/// This class implements OAuth 1.0A authentication for HTTP requests,
|
|
/// according to RFC 5849.
|
|
///
|
|
/// Only PLAINTEXT and HMAC-SHA1 signature methods are
|
|
/// supported. The RSA-SHA1 signature method is not supported.
|
|
///
|
|
/// The OAuth10Credentials can be used to sign a client request, as
|
|
/// well as to verify the signature of a request on the server.
|
|
///
|
|
/// To sign a client request, using a known consumer (client) key, consumer (client) secret,
|
|
/// OAuth token and token secret:
|
|
///
|
|
/// 1. Create an OAuth10Credentials object using all four credentials, either using
|
|
/// the four argument constructor, or by using the default constructor and setting
|
|
/// the credentials using the setter methods.
|
|
/// 2. Create a URI containing the full request URI.
|
|
/// 3. Create an appropriate HTTPRequest object.
|
|
/// 4. Optionally, create a HTMLForm object containing additional parameters to sign.
|
|
/// 5. Sign the request by calling authenticate(). This will add an OAuth
|
|
/// Authorization header to the request.
|
|
/// 6. Send the request using a HTTPClientSession.
|
|
///
|
|
/// To request the OAuth request token from a server, using only the consumer (client) key
|
|
/// and consumer (client) secret:
|
|
///
|
|
/// 1. Create an OAuth10Credentials object using the two consumer credentials, either using
|
|
/// the two argument constructor, or by using the default constructor and setting
|
|
/// the credentials using the setter methods.
|
|
/// 2. Specify the callback URI using setCallback().
|
|
/// 3. Create a URI containing the full request URI to obtain the token.
|
|
/// 4. Create an appropriate HTTPRequest object.
|
|
/// 5. Sign the request by calling authenticate(). This will add an OAuth
|
|
/// Authorization header to the request.
|
|
/// 6. Send the request using a HTTPClientSession.
|
|
/// 7. The response will contain the request token and request token secret.
|
|
/// These can be extracted from the response body using a HTMLForm object.
|
|
///
|
|
/// Requesting the access token and secret (temporary credentials) from the server
|
|
/// is analogous to signing a client request using consumer key, consumer secret,
|
|
/// request token and request token secret.
|
|
/// The server response will contain the access token and access token secret,
|
|
/// which can again be extracted from the response body using a HTMLForm object.
|
|
///
|
|
/// To verify a request on the server:
|
|
///
|
|
/// 1. Create an OAuth10Credentials object using the constructor taking a
|
|
/// HTTPRequest object. This will extract the consumer key and token (if
|
|
/// provided).
|
|
/// 2. Provide the consumer secret and token secret (if required) matching the
|
|
/// consumer key and token to the OAuth10Credentials object using the
|
|
/// setter methods.
|
|
/// 3. Create an URI object containing the full request URI.
|
|
/// 4. Call verify() to verify the signature.
|
|
/// 5. If verification was successful, and the request was a request for
|
|
/// a request (temporary) token, call getCallback() to
|
|
/// obtain the callback URI provided by the client.
|
|
{
|
|
public:
|
|
enum SignatureMethod
|
|
/// OAuth 1.0A Signature Method.
|
|
{
|
|
SIGN_PLAINTEXT, /// OAuth 1.0A PLAINTEXT signature method
|
|
SIGN_HMAC_SHA1 /// OAuth 1.0A HMAC-SHA1 signature method
|
|
};
|
|
|
|
OAuth10Credentials();
|
|
/// Creates an empty OAuth10Credentials object.
|
|
|
|
OAuth10Credentials(const std::string& consumerKey, const std::string& consumerSecret);
|
|
/// Creates an OAuth10Credentials object with the given consumer key and consumer secret.
|
|
///
|
|
/// The token and tokenSecret will be left empty.
|
|
|
|
OAuth10Credentials(const std::string& consumerKey, const std::string& consumerSecret, const std::string& token, const std::string& tokenSecret);
|
|
/// Creates an OAuth10Credentials object with the given consumer key and
|
|
/// consumer secret, as well as token and token secret.
|
|
|
|
explicit OAuth10Credentials(const HTTPRequest& request);
|
|
/// Creates an OAuth10Credentials object from a HTTPRequest object.
|
|
///
|
|
/// Extracts consumer key and token (if available) from the Authorization header.
|
|
///
|
|
/// Throws a NotAuthenticatedException if the request does
|
|
/// not contain OAuth 1.0 credentials.
|
|
|
|
~OAuth10Credentials();
|
|
/// Destroys the OAuth10Credentials.
|
|
|
|
void setConsumerKey(const std::string& consumerKey);
|
|
/// Sets the consumer key.
|
|
|
|
const std::string& getConsumerKey() const;
|
|
/// Returns the consumer key.
|
|
|
|
void setConsumerSecret(const std::string& consumerSecret);
|
|
/// Sets the consumer secret.
|
|
|
|
const std::string& getConsumerSecret() const;
|
|
/// Returns the consumer secret.
|
|
|
|
void setToken(const std::string& token);
|
|
/// Sets the token.
|
|
|
|
const std::string& getToken() const;
|
|
/// Returns the token.
|
|
|
|
void setTokenSecret(const std::string& tokenSecret);
|
|
/// Sets the token.
|
|
|
|
const std::string& getTokenSecret() const;
|
|
/// Returns the token secret.
|
|
|
|
void setRealm(const std::string& realm);
|
|
/// Sets the optional realm to be included in the Authorization header.
|
|
|
|
const std::string& getRealm() const;
|
|
/// Returns the optional realm to be included in the Authorization header.
|
|
|
|
void setCallback(const std::string& uri);
|
|
/// Sets the callback URI.
|
|
|
|
const std::string& getCallback() const;
|
|
/// Returns the callback URI.
|
|
|
|
void authenticate(HTTPRequest& request, const Poco::URI& uri, SignatureMethod method = SIGN_HMAC_SHA1);
|
|
/// Adds an OAuth 1.0A Authentication header to the given request, using
|
|
/// the given signature method.
|
|
|
|
void authenticate(HTTPRequest& request, const Poco::URI& uri, const Poco::Net::HTMLForm& params, SignatureMethod method = SIGN_HMAC_SHA1);
|
|
/// Adds an OAuth 1.0A Authentication header to the given request, using
|
|
/// the given signature method.
|
|
|
|
bool verify(const HTTPRequest& request, const Poco::URI& uri);
|
|
/// Verifies the signature of the given request.
|
|
///
|
|
/// The consumer key, consumer secret, token and token secret must have been set.
|
|
///
|
|
/// Returns true if the signature is valid, otherwise false.
|
|
///
|
|
/// Throws a NotAuthenticatedException if the request does not contain OAuth
|
|
/// credentials, or in case of an unsupported OAuth version or signature method.
|
|
|
|
bool verify(const HTTPRequest& request, const Poco::URI& uri, const Poco::Net::HTMLForm& params);
|
|
/// Verifies the signature of the given request.
|
|
///
|
|
/// The consumer key, consumer secret, token and token secret must have been set.
|
|
///
|
|
/// Returns true if the signature is valid, otherwise false.
|
|
///
|
|
/// Throws a NotAuthenticatedException if the request does not contain OAuth
|
|
/// credentials, or in case of an unsupported OAuth version or signature method.
|
|
|
|
void nonceAndTimestampForTesting(const std::string& nonce, const std::string& timestamp);
|
|
/// Sets the nonce and timestamp to a wellknown value.
|
|
///
|
|
/// For use by testsuite only, to test the signature
|
|
/// algorithm with wellknown inputs.
|
|
///
|
|
/// In normal operation, the nonce is a random value
|
|
/// computed by createNonce() and the timestamp is taken
|
|
/// from the system time.
|
|
|
|
static const std::string SCHEME;
|
|
|
|
protected:
|
|
void signPlaintext(Poco::Net::HTTPRequest& request) const;
|
|
/// Signs the given HTTP request according to OAuth 1.0A PLAINTEXT signature method.
|
|
|
|
void signHMACSHA1(Poco::Net::HTTPRequest& request, const std::string& uri, const Poco::Net::HTMLForm& params) const;
|
|
/// Signs the given HTTP request according to OAuth 1.0A HMAC-SHA1 signature method.
|
|
|
|
std::string createNonce() const;
|
|
/// Creates a nonce, which is basically a Base64-encoded 32 character random
|
|
/// string, with non-alphanumeric characters removed.
|
|
|
|
std::string createSignature(const Poco::Net::HTTPRequest& request, const std::string& uri, const Poco::Net::HTMLForm& params, const std::string& nonce, const std::string& timestamp) const;
|
|
/// Creates a OAuth signature for the given request and its parameters, according
|
|
/// to <https://dev.twitter.com/docs/auth/creating-signature>.
|
|
|
|
static std::string percentEncode(const std::string& str);
|
|
/// Percent-encodes the given string according to Twitter API's rules,
|
|
/// given in <https://dev.twitter.com/docs/auth/percent-encoding-parameters>.
|
|
|
|
private:
|
|
OAuth10Credentials(const OAuth10Credentials&);
|
|
OAuth10Credentials& operator = (const OAuth10Credentials&);
|
|
|
|
std::string _consumerKey;
|
|
std::string _consumerSecret;
|
|
std::string _token;
|
|
std::string _tokenSecret;
|
|
std::string _callback;
|
|
std::string _realm;
|
|
std::string _nonce;
|
|
std::string _timestamp;
|
|
};
|
|
|
|
|
|
//
|
|
// inlines
|
|
//
|
|
inline const std::string& OAuth10Credentials::getConsumerKey() const
|
|
{
|
|
return _consumerKey;
|
|
}
|
|
|
|
|
|
inline const std::string& OAuth10Credentials::getConsumerSecret() const
|
|
{
|
|
return _consumerSecret;
|
|
}
|
|
|
|
|
|
inline const std::string& OAuth10Credentials::getToken() const
|
|
{
|
|
return _token;
|
|
}
|
|
|
|
|
|
inline const std::string& OAuth10Credentials::getTokenSecret() const
|
|
{
|
|
return _tokenSecret;
|
|
}
|
|
|
|
|
|
inline const std::string& OAuth10Credentials::getRealm() const
|
|
{
|
|
return _realm;
|
|
}
|
|
|
|
|
|
inline const std::string& OAuth10Credentials::getCallback() const
|
|
{
|
|
return _callback;
|
|
}
|
|
|
|
|
|
} } // namespace Poco::Net
|
|
|
|
|
|
#endif // Net_OAuth10Credentials_INCLUDED
|