From 35394bd0eae4454696267834665120783311ae7f Mon Sep 17 00:00:00 2001 From: keita Date: Wed, 17 Feb 2021 00:03:57 +0900 Subject: [PATCH] =?UTF-8?q?=E3=81=A8=E3=82=8A=E3=81=82=E3=81=88=E3=81=9AcU?= =?UTF-8?q?RL=E3=82=92=E4=BD=BF=E3=81=A3=E3=81=A6=E6=8A=95=E3=81=92?= =?UTF-8?q?=E3=82=89=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AA=E3=83=87?= =?UTF-8?q?=E3=83=BC=E3=82=BF=E3=81=AF=E4=BD=9C=E6=88=90=E3=81=A7=E3=81=8D?= =?UTF-8?q?=E3=81=9F(#47)(#48)(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/cocoatweet/api/api.cc | 18 +-- src/cocoatweet/api/api.h | 19 +-- src/cocoatweet/api/groupInterface.h | 8 +- src/cocoatweet/api/interface.cc | 12 +- src/cocoatweet/api/interface.h | 18 ++- src/cocoatweet/api/status/status.cc | 20 +-- src/cocoatweet/api/status/status.h | 17 +- src/cocoatweet/api/status/update.cc | 167 +++++++++---------- src/cocoatweet/api/status/update.h | 16 +- src/cocoatweet/oauth/key.h | 59 ++++--- src/cocoatweet/oauth/oauth.cc | 239 +++++++++++++++------------- src/cocoatweet/oauth/oauth.h | 38 ++--- 13 files changed, 333 insertions(+), 299 deletions(-) diff --git a/.gitignore b/.gitignore index bbbf928..4d4e37c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ *.swp +src/main.cc diff --git a/src/cocoatweet/api/api.cc b/src/cocoatweet/api/api.cc index f765ad1..80037b4 100644 --- a/src/cocoatweet/api/api.cc +++ b/src/cocoatweet/api/api.cc @@ -1,12 +1,12 @@ #include -namespace CocoaTweet::API{ - API::API(CocoaTweet::OAuth::Key _key){ - oauth_ = std::make_shared(_key); - status_ = Statuses::Status(oauth_); - } +namespace CocoaTweet::API { +API::API(CocoaTweet::OAuth::Key _key) { + oauth_ = std::make_shared(_key); + status_ = Statuses::Status(oauth_); +} - Statuses::Status API::status() const{ - return status_; - } -} \ No newline at end of file +Statuses::Status API::status() const { + return status_; +} +} // namespace CocoaTweet::API \ No newline at end of file diff --git a/src/cocoatweet/api/api.h b/src/cocoatweet/api/api.h index e0dff24..9ae16d0 100644 --- a/src/cocoatweet/api/api.h +++ b/src/cocoatweet/api/api.h @@ -4,15 +4,16 @@ #include "cocoatweet/api/status/status.h" #include "cocoatweet/oauth/oauth.h" -namespace CocoaTweet::API{ -class API{ - public: - API(CocoaTweet::OAuth::Key _key); - Statuses::Status status() const; - private: - Statuses::Status status_; - std::shared_ptr oauth_; +namespace CocoaTweet::API { +class API { +public: + API(CocoaTweet::OAuth::Key _key); + Statuses::Status status() const; + +private: + Statuses::Status status_; + std::shared_ptr oauth_; }; -} +} // namespace CocoaTweet::API #endif diff --git a/src/cocoatweet/api/groupInterface.h b/src/cocoatweet/api/groupInterface.h index 38ddd79..af28e0b 100644 --- a/src/cocoatweet/api/groupInterface.h +++ b/src/cocoatweet/api/groupInterface.h @@ -4,11 +4,11 @@ #include #include "cocoatweet/oauth/oauth.h" -namespace CocoaTweet::API{ -class groupInterface{ +namespace CocoaTweet::API { +class groupInterface { protected: - std::weak_ptr oauth_; + std::weak_ptr oauth_; }; -} +} // namespace CocoaTweet::API #endif diff --git a/src/cocoatweet/api/interface.cc b/src/cocoatweet/api/interface.cc index 4e87bf5..4edff8f 100644 --- a/src/cocoatweet/api/interface.cc +++ b/src/cocoatweet/api/interface.cc @@ -1,9 +1,9 @@ #include -namespace CocoaTweet::API{ - size_t Interface::curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream){ - int realsize = _size * _nmemb; - _stream->append(_ptr, realsize); - return realsize; - } +namespace CocoaTweet::API { +size_t Interface::curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream) { + int realsize = _size * _nmemb; + _stream->append(_ptr, realsize); + return realsize; } +} // namespace CocoaTweet::API diff --git a/src/cocoatweet/api/interface.h b/src/cocoatweet/api/interface.h index 7680563..dffe0d4 100644 --- a/src/cocoatweet/api/interface.h +++ b/src/cocoatweet/api/interface.h @@ -4,16 +4,18 @@ #include #include "cocoatweet/oauth/oauth.h" -namespace CocoaTweet::API{ -class Interface{ +namespace CocoaTweet::API { +class Interface { public: - virtual void process(std::weak_ptr _oauth, std::function _callback) = 0; + virtual void process(std::weak_ptr _oauth, + std::function _callback) = 0; + protected: - std::weak_ptr oauth_; - std::map param_; - std::string url_; - static size_t curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream); + std::weak_ptr oauth_; + std::map param_; + std::string url_; + static size_t curlCallback_(char* _ptr, size_t _size, size_t _nmemb, std::string* _stream); }; -} +} // namespace CocoaTweet::API #endif diff --git a/src/cocoatweet/api/status/status.cc b/src/cocoatweet/api/status/status.cc index eaf9e90..928a30c 100644 --- a/src/cocoatweet/api/status/status.cc +++ b/src/cocoatweet/api/status/status.cc @@ -3,14 +3,14 @@ #include "cocoatweet/api/status/status.h" #include "cocoatweet/api/status/update.h" -namespace CocoaTweet::API::Statuses{ - Status::Status(std::shared_ptr _oauth){ - oauth_ = _oauth; - } - - void Status::Update(const std::string& _status)const{ - CocoaTweet::API::Statuses::Update update; - update.status(_status); - update.process(oauth_, [](std::string _rcv){std::cout << _rcv << std::endl;}); - } +namespace CocoaTweet::API::Statuses { +Status::Status(std::shared_ptr _oauth) { + oauth_ = _oauth; } + +void Status::Update(const std::string& _status) const { + CocoaTweet::API::Statuses::Update update; + update.status(_status); + update.process(oauth_, [](std::string _rcv) { std::cout << _rcv << std::endl; }); +} +} // namespace CocoaTweet::API::Statuses diff --git a/src/cocoatweet/api/status/status.h b/src/cocoatweet/api/status/status.h index 7db7de5..464628e 100644 --- a/src/cocoatweet/api/status/status.h +++ b/src/cocoatweet/api/status/status.h @@ -4,14 +4,15 @@ #include "cocoatweet/api/groupInterface.h" #include "cocoatweet/oauth/oauth.h" -namespace CocoaTweet::API::Statuses{ -class Status : public groupInterface{ - public: - Status() = default; - Status(std::shared_ptr _oauth); - void Update(const std::string& _status) const; - private: +namespace CocoaTweet::API::Statuses { +class Status : public groupInterface { +public: + Status() = default; + Status(std::shared_ptr _oauth); + void Update(const std::string& _status) const; + +private: }; -} +} // namespace CocoaTweet::API::Statuses #endif diff --git a/src/cocoatweet/api/status/update.cc b/src/cocoatweet/api/status/update.cc index ad4fc82..adeec9d 100644 --- a/src/cocoatweet/api/status/update.cc +++ b/src/cocoatweet/api/status/update.cc @@ -1,4 +1,5 @@ #include "cocoatweet/api/status/update.h" +#include "cocoatweet/util/util.h" #include #include #include @@ -8,87 +9,87 @@ extern "C" { #include } -namespace CocoaTweet::API::Statuses{ - Update::Update(){ - url_ = "https://api.twitter.com/1.1/statuses/update.json"; - } - void Update::status(const std::string _status){ - status_ = _status; - param_.insert_or_assign("status", status_); - } - - void Update::process(std::weak_ptr _oauth, std::function _callback){ - // エンドポイントへのパラメータにOAuthパラメータを付加して署名作成 - auto oauth = _oauth.lock(); - param_.merge(oauth->oauthParam()); - auto signature = oauth->signature(param_, "POST", url_); - - // 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録 - param_.insert_or_assign("oauth_signature", signature["oauth_signature"]); - auto header = oauth->oauthParam(); - std::cout << "signature : " << signature["oauth_signature"] << std::endl; - header.insert_or_assign("oauth_signature", signature["oauth_signature"]); - - // リクエストボディの構築 - std::string requestBody = ""; - { - std::vector tmp; - for(const auto& [key, value] : param_){ - tmp.push_back(key + "=" + value); - } - std::stringstream os; - std::copy(tmp.begin(), tmp.end(), std::ostream_iterator(os, "&")); - requestBody = os.str(); - requestBody.erase(requestBody.size() - std::char_traits::length("&")); - } - std::cout << "Body : " << requestBody << std::endl; - - // ヘッダの構築 - std::string oauthHeader = "Authorization: OAuth "; - { - std::vector tmp; - for(const auto& [key, value] : header){ - tmp.push_back(key + "=" + value); - } - std::stringstream os; - std::copy(tmp.begin(), tmp.end(), std::ostream_iterator(os, ",")); - oauthHeader += os.str(); - oauthHeader.erase(oauthHeader.size() - std::char_traits::length(",")); - } - std::cout << "OAuth Header : " << oauthHeader << std::endl; - - - - - // do post - CURL *curl; - CURLcode res; - std::string rcv; - curl = curl_easy_init(); - std::cout << "URL : " << url_ << std::endl; - if (curl){ - curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); - curl_easy_setopt(curl, CURLOPT_POST, 1); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestBody.length()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv); - curl_easy_setopt(curl, CURLOPT_PROXY, ""); - //Headerを保持するcurl_slist*を初期化 - struct curl_slist *headers = NULL; - //Authorizationをヘッダに追加 - headers = curl_slist_append(headers, oauthHeader.c_str()); - curl_easy_setopt(curl, CURLOPT_HEADER, headers); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - } - if (res != CURLE_OK) { - std::cout << "curl error : " << res << std::endl; - exit (1); - } - - if(_callback){ - _callback(rcv); - } - } +namespace CocoaTweet::API::Statuses { +Update::Update() { + url_ = "https://api.twitter.com/1.1/statuses/update.json"; } +void Update::status(const std::string _status) { + status_ = _status; + param_.insert_or_assign("status", status_); +} + +void Update::process(std::weak_ptr _oauth, + std::function _callback) { + // エンドポイントへのパラメータにOAuthパラメータを付加して署名作成 + auto oauth = _oauth.lock(); + param_.merge(oauth->oauthParam()); + auto signature = oauth->signature(param_, "POST", url_); + + // 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録 + param_.insert_or_assign("oauth_signature", signature["oauth_signature"]); + auto header = oauth->oauthParam(); + std::cout << "signature : " << signature["oauth_signature"] << std::endl; + header.insert_or_assign("oauth_signature", signature["oauth_signature"]); + + // リクエストボディの構築 + std::string requestBody = ""; + { + std::vector tmp; + for (const auto& [key, value] : param_) { + tmp.push_back(key + "=" + value); + } + std::stringstream os; + std::copy(tmp.begin(), tmp.end(), std::ostream_iterator(os, "&")); + requestBody = os.str(); + requestBody.erase(requestBody.size() - std::char_traits::length("&")); + } + requestBody += (std::string("&") + "oauth_signature=" + signature["oauth_signature"]); + std::cout << "request Body -> " << requestBody << std::endl; + + // ヘッダの構築 + std::string oauthHeader = "Authorization: OAuth "; + { + std::vector tmp; + for (const auto& [key, value] : header) { + tmp.push_back(key + "=" + value); + } + std::stringstream os; + std::copy(tmp.begin(), tmp.end(), std::ostream_iterator(os, ",")); + oauthHeader += os.str(); + oauthHeader.erase(oauthHeader.size() - std::char_traits::length(",")); + } + //oauthHeader += (std::string(",") + "oauth_signature=" + signature["oauth_signature"]); + std::cout << "OAuth Header -> " << oauthHeader << std::endl; + + // do post + CURL* curl; + CURLcode res; + std::string rcv; + curl = curl_easy_init(); + std::cout << "URL : " << url_ << std::endl; + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); + curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestBody.length()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv); + curl_easy_setopt(curl, CURLOPT_PROXY, ""); + // Headerを保持するcurl_slist*を初期化 + struct curl_slist* headers = NULL; + // Authorizationをヘッダに追加 + headers = curl_slist_append(headers, oauthHeader.c_str()); + curl_easy_setopt(curl, CURLOPT_HEADER, headers); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } + if (res != CURLE_OK) { + std::cout << "curl error : " << res << std::endl; + exit(1); + } + + if (_callback) { + _callback(rcv); + } +} +} // namespace CocoaTweet::API::Statuses diff --git a/src/cocoatweet/api/status/update.h b/src/cocoatweet/api/status/update.h index b3bdfd3..3aeec8d 100644 --- a/src/cocoatweet/api/status/update.h +++ b/src/cocoatweet/api/status/update.h @@ -6,15 +6,17 @@ #include "cocoatweet/api/interface.h" //#include "cocoatweet/oauth/oauth.h" -namespace CocoaTweet::API::Statuses{ -class Update :public Interface{ +namespace CocoaTweet::API::Statuses { +class Update : public Interface { public: - Update(); - void status(const std::string _status); - void process(std::weak_ptr _oauth, std::function _callback); + Update(); + void status(const std::string _status); + void process(std::weak_ptr _oauth, + std::function _callback); + private: - std::string status_; + std::string status_; }; -} +} // namespace CocoaTweet::API::Statuses #endif diff --git a/src/cocoatweet/oauth/key.h b/src/cocoatweet/oauth/key.h index e77dfb1..536dce8 100644 --- a/src/cocoatweet/oauth/key.h +++ b/src/cocoatweet/oauth/key.h @@ -2,33 +2,42 @@ #define COCOATWEET_OAUTH_KEY_H_ #include -namespace CocoaTweet::OAuth{ -class Key{ -const std::string consumerKey_; -const std::string consumerSecret_; -const std::string accessToken_; -const std::string accessTokenSecret_; +namespace CocoaTweet::OAuth { +class Key { + const std::string consumerKey_; + const std::string consumerSecret_; + const std::string accessToken_; + const std::string accessTokenSecret_; public: -Key() = default; -Key(const std::string& _consumerKey, const std::string& _consumerSecret, const std::string& _accessToken, const std::string& _accessTokenSecret):consumerKey_(_consumerKey), consumerSecret_(_consumerSecret), accessToken_(_accessToken), accessTokenSecret_(_accessTokenSecret){} -const std::string& consumerKey() const{return consumerKey_;} -const std::string& consumerSecret() const{return consumerSecret_;} -const std::string& accessToken() const{return accessToken_;} -const std::string& accessTokenSecret() const{return accessTokenSecret_;} -std::map noSecret()const{ - return std::map{ - {"oauth_consumer_key", consumerKey_}, - {"oauth_token", accessToken_} - }; -} -const std::map secret()const{ - return std::map{ - {"oauth_consumer_key", consumerSecret_}, - {"oauth_token", accessTokenSecret_} - }; -} + Key() = default; + Key(const std::string& _consumerKey, const std::string& _consumerSecret, + const std::string& _accessToken, const std::string& _accessTokenSecret) + : consumerKey_(_consumerKey), + consumerSecret_(_consumerSecret), + accessToken_(_accessToken), + accessTokenSecret_(_accessTokenSecret) {} + const std::string& consumerKey() const { + return consumerKey_; + } + const std::string& consumerSecret() const { + return consumerSecret_; + } + const std::string& accessToken() const { + return accessToken_; + } + const std::string& accessTokenSecret() const { + return accessTokenSecret_; + } + std::map noSecret() const { + return std::map{{"oauth_consumer_key", consumerKey_}, + {"oauth_token", accessToken_}}; + } + const std::map secret() const { + return std::map{{"oauth_consumer_key", consumerSecret_}, + {"oauth_token", accessTokenSecret_}}; + } }; -} +} // namespace CocoaTweet::OAuth #endif diff --git a/src/cocoatweet/oauth/oauth.cc b/src/cocoatweet/oauth/oauth.cc index 49cf1a8..cff6f74 100644 --- a/src/cocoatweet/oauth/oauth.cc +++ b/src/cocoatweet/oauth/oauth.cc @@ -1,131 +1,146 @@ #include "oauth.h" - +#include "cocoatweet/util/util.h" #include #include #include #include #include +#include #include #include -extern "C"{ +extern "C" { #include #include +#include } -namespace CocoaTweet::OAuth{ - OAuth1::OAuth1(){ +namespace CocoaTweet::OAuth { +OAuth1::OAuth1() {} - } +OAuth1::OAuth1(const Key _key) : key_(_key) {} - OAuth1::OAuth1(const Key _key):key_(_key){ +std::map OAuth1::signature( + const std::map& _param, const std::string& _method, + const std::string& _url) { + std::vector tmp; + for (const auto& [key, value] : _param) { + tmp.push_back(key + "=" + value); + std::cout << (key + "=" + value) << std::endl; + } + std::ostringstream os; + std::copy(tmp.begin(), tmp.end(), std::ostream_iterator(os, "&")); + std::string query = os.str(); + query.erase(query.size() - std::char_traits::length("&")); - } + auto significateKey = key().consumerSecret() + "&" + key().accessTokenSecret(); + auto significateBase = _method + "&" + CocoaTweet::Util::urlEncode(_url) + "&" + CocoaTweet::Util::urlEncode(query); + auto k64Sha1 = hmacSha1(significateKey, significateBase); - std::map OAuth1::signature(const std::map& _param, const std::string& _method, const std::string& _url){ - std::vector tmp; - for(const auto& [key, value] : _param){ - tmp.push_back(key + "=" + value); - } - std::ostringstream os; - std::copy(tmp.begin(), tmp.end(), std::ostream_iterator(os, "&")); - std::string query = os.str(); - query.erase(query.size() - std::char_traits::length("&")); - - auto significateKey = key().consumerSecret() + "&" + key().accessTokenSecret(); - auto significateBase = _method + "&" + _url + "&" + query; - auto result = hmacSha1(significateKey, significateBase); - - std::cout << "significate key : " << significateKey << std::endl; - std::cout << "significate base : " << significateBase << std::endl; - std::cout << "hmac-sha1 : " << base64(result) << std::endl; - - auto ret = std::map{ - {"oauth_signature", base64(result)} - }; - return ret; - } - - const std::string OAuth1::nonce()const{ - std::random_device engine; - std::string nonceTable = "abcdefghijklmnopqrstuvwxyz0123456789"; - std::uniform_int_distribution dist(0, nonceTable.length() - 1); - std::string nonce; - - for (auto i = 0; i < 32; ++i) { - nonce += nonceTable[dist(engine)]; - } - - return nonce; - } - - - const std::string OAuth1::timestamp() const{ - return std::to_string(time(nullptr)); - } - - const std::string OAuth1::method() const{ - return SIGNATURE_METHOD_; - } - - const std::string OAuth1::version() const{ - return OAUTH_VERSION_; - } - - const Key OAuth1::key() const{ - return key_; - } - - std::map OAuth1::oauthParam() const{ - auto tmp = std::map{ - {"oauth_nonce", nonce()}, - {"oauth_signature_method", method()}, - {"oauth_timestamp", timestamp()}, - {"oauth_version", version()} - }; - tmp.merge(key().noSecret()); - - return tmp; - } - - const std::string OAuth1::base64(const std::string& _raw){ - auto base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - std::stringstream ss; - for(auto r : _raw){ - ss << std::bitset<8>(r); - } - - - if(_raw.length() % 3 == 1){ - ss << "0000"; - }else if(_raw.length() % 3 == 2){ - ss << "00"; - } - - auto bin = ss.str(); - std::string base64 = ""; - for(auto i = 0;i < bin.length() / 6;i++){ - base64 += base64Table[std::stoi(bin.substr(i * 6, 6), nullptr, 2)]; - } - - if(base64.length() % 4 == 3){ - base64 += "="; - }else if(base64.length() % 4 == 2){ - base64 += "=="; - }else if(base64.length() % 4 == 1){ - base64 += "==="; - } - - return base64; - } - - std::string OAuth1::hmacSha1(std::string _key, std::string _data){ - unsigned char result[255]; - unsigned int length = 255; - - HMAC(EVP_sha1(), reinterpret_cast(_key.c_str()), _key.length(), reinterpret_cast(_data.c_str()), _data.length(), result, &length); - - return std::string(reinterpret_cast(result)); - } + std::cout << "significate key : " << significateKey << std::endl; + std::cout << "significate base : " << significateBase << std::endl; + std::cout << "hmac-sha1 : " << k64Sha1 << std::endl; + auto ret = std::map{{"oauth_signature", CocoaTweet::Util::urlEncode(k64Sha1)}}; + return ret; } + +const std::string OAuth1::nonce() const { + std::random_device engine; + std::string nonceTable = "abcdefghijklmnopqrstuvwxyz0123456789"; + std::uniform_int_distribution dist(0, nonceTable.length() - 1); + std::string nonce; + + for (auto i = 0; i < 32; ++i) { + nonce += nonceTable[dist(engine)]; + } + + return nonce; +} + +const std::string OAuth1::timestamp() const { + return std::to_string(time(nullptr)); +} + +const std::string OAuth1::method() const { + return SIGNATURE_METHOD_; +} + +const std::string OAuth1::version() const { + return OAUTH_VERSION_; +} + +const Key OAuth1::key() const { + return key_; +} + +std::map OAuth1::oauthParam() const { + auto tmp = std::map{{"oauth_nonce", nonce()}, + {"oauth_signature_method", method()}, + {"oauth_timestamp", timestamp()}, + {"oauth_version", version()}}; + tmp.merge(key().noSecret()); + + return tmp; +} + +const std::string OAuth1::base64(const std::string& _raw) { + auto base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + std::stringstream ss; + for (auto r : _raw) { + ss << std::bitset<8>(r); + } + + if (_raw.length() % 3 == 1) { + ss << "0000"; + } else if (_raw.length() % 3 == 2) { + ss << "00"; + } + + auto bin = ss.str(); + std::string base64 = ""; + for (auto i = 0; i < bin.length() / 6; i++) { + base64 += base64Table[std::stoi(bin.substr(i * 6, 6), nullptr, 2)]; + } + + if (base64.length() % 4 == 3) { + base64 += "="; + } else if (base64.length() % 4 == 2) { + base64 += "=="; + } else if (base64.length() % 4 == 1) { + base64 += "==="; + } + + return base64; +} + +std::string OAuth1::hmacSha1(std::string _key, std::string _data) { + unsigned char result[255]; + unsigned int length = 255; + + HMAC(EVP_sha1(), reinterpret_cast(_key.c_str()), _key.length(), + reinterpret_cast(_data.c_str()), _data.length(), result, &length); + + auto sha1 = std::string(reinterpret_cast(result), length); + + + // base64 encodeもやっちゃえ日産 + BIO *encoder = BIO_new(BIO_f_base64()); + BIO *bmem = BIO_new(BIO_s_mem()); + encoder = BIO_push(encoder,bmem); + BIO_write(encoder, sha1.c_str(), sha1.length()); + BIO_flush(encoder); + + BUF_MEM *bptr; + BIO_get_mem_ptr(encoder,&bptr); + + char *k64 = (char *)std::malloc(bptr->length); + std::memcpy(k64, bptr->data, bptr->length-1); + k64[bptr->length-1] = 0; + + BIO_free_all(encoder); + + return static_cast(k64); +} + +} // namespace CocoaTweet::OAuth diff --git a/src/cocoatweet/oauth/oauth.h b/src/cocoatweet/oauth/oauth.h index 41a945b..d30dbad 100644 --- a/src/cocoatweet/oauth/oauth.h +++ b/src/cocoatweet/oauth/oauth.h @@ -5,26 +5,28 @@ #include #include "key.h" -namespace CocoaTweet::OAuth{ -class OAuth1{ +namespace CocoaTweet::OAuth { +class OAuth1 { public: -OAuth1(); -OAuth1(const Key _key); -std::map signature(const std::map& _param, const std::string& _method, const std::string& _url); -const std::string nonce()const; -const std::string timestamp()const; -const std::string method()const; -const std::string version()const; -const Key key()const; -std::map oauthParam()const; -std::string hmacSha1(std::string _key, std::string _data); -const std::string base64(const std::string& _raw); -private: -Key key_; -const std::string SIGNATURE_METHOD_ = "HMAC-SHA1"; -const std::string OAUTH_VERSION_ = "1.0"; + OAuth1(); + OAuth1(const Key _key); + std::map signature(const std::map& _param, + const std::string& _method, + const std::string& _url); + const std::string nonce() const; + const std::string timestamp() const; + const std::string method() const; + const std::string version() const; + const Key key() const; + std::map oauthParam() const; + std::string hmacSha1(std::string _key, std::string _data); + const std::string base64(const std::string& _raw); +private: + Key key_; + const std::string SIGNATURE_METHOD_ = "HMAC-SHA1"; + const std::string OAUTH_VERSION_ = "1.0"; }; -} +} // namespace CocoaTweet::OAuth #endif