Token Token::extract(const KeyValuePairs& response) { std::string token_key, token_secret; KeyValuePairs::const_iterator it = response.find(Defaults::TOKEN_KEY); if (it == response.end()) throw MissingKeyError("Couldn't find oauth_token in response"); token_key = it->second; it = response.find(Defaults::TOKENSECRET_KEY); if (it == response.end()) throw MissingKeyError("Couldn't find oauth_token_secret in response"); token_secret = it->second; return Token(token_key, token_secret); }
// Helper for parameters in key-value pair lists that should only appear // once. Either replaces an existing entry or adds a new entry. static void ReplaceOrInsertKeyValuePair(KeyValuePairs& kvp, const std::string& key, const std::string& value) { assert(kvp.count(key) <= 1); KeyValuePairs::iterator it = kvp.find(key); if (it != kvp.end()) it->second = value; else kvp.insert(KeyValuePairs::value_type(key, value)); }
/*++ * @method: Client::getStringFromOAuthKeyValuePairs * * @description: this method builds a sorted string from key-value pairs * * @input: rawParamMap - key-value pairs map * paramsSeperator - sepearator, either & or , * * @output: rawParams - sorted string of OAuth parameters * * @remarks: internal method * *--*/ bool Client::getStringFromOAuthKeyValuePairs( const KeyValuePairs& rawParamMap, std::string& rawParams, const std::string& paramsSeperator ) { rawParams.assign( "" ); if( rawParamMap.size() ) { KeyValueList keyValueList; std::string dummyStr; /* Push key-value pairs to a list of strings */ keyValueList.clear(); KeyValuePairs::const_iterator itMap = rawParamMap.begin(); for( ; itMap != rawParamMap.end(); itMap++ ) { dummyStr.assign( itMap->first ); dummyStr.append( "=" ); if( paramsSeperator == "," ) { dummyStr.append( "\"" ); } dummyStr.append( itMap->second ); if( paramsSeperator == "," ) { dummyStr.append( "\"" ); } keyValueList.push_back( dummyStr ); } /* Sort key-value pairs based on key name */ keyValueList.sort(); /* Now, form a string */ dummyStr.assign( "" ); KeyValueList::iterator itKeyValue = keyValueList.begin(); for( ; itKeyValue != keyValueList.end(); itKeyValue++ ) { if( dummyStr.length() ) { dummyStr.append( paramsSeperator ); } dummyStr.append( itKeyValue->c_str() ); } rawParams.assign( dummyStr ); } return ( rawParams.length() ) ? true : false; }
std::string Client::buildOAuthParameterString( ParameterStringType string_type, const Http::RequestType eType, const std::string& rawUrl, const std::string& rawData, const bool includeOAuthVerifierPin) { KeyValuePairs rawKeyValuePairs; std::string rawParams; std::string oauthSignature; std::string paramsSeperator; std::string pureUrl( rawUrl ); std::string separator; bool do_urlencode; if (string_type == AuthorizationHeaderString) { separator = ","; do_urlencode = false; } else { /*if (string_type == QueryStringString)*/ separator = "&"; do_urlencode = true; } /* Clear header string initially */ rawKeyValuePairs.clear(); /* If URL itself contains ?key=value, then extract and put them in map */ size_t nPos = rawUrl.find_first_of( "?" ); if( std::string::npos != nPos ) { /* Get only URL */ pureUrl = rawUrl.substr( 0, nPos ); /* Get only key=value data part */ std::string dataPart = rawUrl.substr( nPos + 1 ); rawKeyValuePairs = ParseKeyValuePairs(dataPart); } // We always request URL encoding on the first pass so that the // signature generation works properly. This *relies* on // buildOAuthTokenKeyValuePairs overwriting values when we do the second // pass to get the values in the form we actually want. The signature and // rawdata are the only things that change, but the signature is only used // in the second pass and the rawdata is already encoded, regardless of // request type. /* Build key-value pairs needed for OAuth request token, without signature */ buildOAuthTokenKeyValuePairs( includeOAuthVerifierPin, rawData, std::string( "" ), rawKeyValuePairs, true, true ); /* Get url encoded base64 signature using request type, url and parameters */ getSignature( eType, pureUrl, rawKeyValuePairs, oauthSignature ); /* Now, again build key-value pairs with signature this time */ buildOAuthTokenKeyValuePairs( includeOAuthVerifierPin, std::string( "" ), oauthSignature, rawKeyValuePairs, do_urlencode, false ); /* Get OAuth header in string format. If we're getting the Authorization * header, we need to filter out other parameters. */ if (string_type == AuthorizationHeaderString) { KeyValuePairs oauthKeyValuePairs; std::vector<std::string> oauth_keys; oauth_keys.push_back(Defaults::CONSUMERKEY_KEY); oauth_keys.push_back(Defaults::NONCE_KEY); oauth_keys.push_back(Defaults::SIGNATURE_KEY); oauth_keys.push_back(Defaults::SIGNATUREMETHOD_KEY); oauth_keys.push_back(Defaults::TIMESTAMP_KEY); oauth_keys.push_back(Defaults::TOKEN_KEY); oauth_keys.push_back(Defaults::VERIFIER_KEY); oauth_keys.push_back(Defaults::VERSION_KEY); for(size_t i = 0; i < oauth_keys.size(); i++) { assert(rawKeyValuePairs.count(oauth_keys[i]) <= 1); KeyValuePairs::iterator oauth_key_it = rawKeyValuePairs.find(oauth_keys[i]); if (oauth_key_it != rawKeyValuePairs.end()) ReplaceOrInsertKeyValuePair(oauthKeyValuePairs, oauth_keys[i], oauth_key_it->second); } getStringFromOAuthKeyValuePairs( oauthKeyValuePairs, rawParams, separator ); } else if (string_type == QueryStringString) { getStringFromOAuthKeyValuePairs( rawKeyValuePairs, rawParams, separator ); } /* Build authorization header */ return rawParams; }