יום חמישי, מרץ 05, 2015

קוד בדיקה מול term.ie

אתמול הייתי צריך לבדוק מערכת שמתקשרת ע"י שימוש ב rest מול שרת בדיקה, להפתעתי גיליתי ששירות ההזדהות עבר להשתמש ב oauth  במקום שירותי ההזדהות על בסיס זיהוי NTLM.

גיגול מהיר נתן לי את liboauthcpp מכיוון שלא יכלתי להתקין אותו הייתי צריך לעבוד קצת עקום - בניתי מקומית את הספרייה, לאחר מכן בשביל לבדוק התלנקקתי מול boost  וliboauthcpp עם מסלול מדוייק.
שמתי את ספריית ההזדהות ב /opt/oauth/libauthcpp

mkdir -p /opt/oauth/myauth/src
cp -r ~/myauth/* /opt/oauth/myauth/src/

בתוכה יצרתי קובץ CMakeFiles.txt:


cmake_minimum_required(VERSION 2.8 FATAL_ERROR) 

find_package(Boost 1.49 COMPONENTS system filesystem REQUIRED)

IF(NOT MYAUTH_TOP_LEVEL)
        SET(MYAUTH_TOP_LEVEL ${CMAKE_CURRENT_SOURCE_DIR}/)
endif()
GET_FILENAME_COMPONENT(MYAUTH_TOP_LEVEL ${MYAUTH_TOP_LEVEL} ABSOLUTE)
SET (MYAUTHCPP_SRC ${MYAUTH_TOP_LEVEL}/src)

add_executable (myauth 
                ${MYAUTHCPP_SRC}/main.cc)

include_directories(myauth /opt/oauth/liboauthcpp/include/)
target_link_libraries(
        myauth /opt/oauth/liboauthcpp/build/liboauthcpp.a
        boost_system
        pthread
       ) 

אני צריך את בוסט כי הקוד שלי כבר משתמש בו, לצערי שרפתי קצת זמן על שגיאת כתיב בשם של הספרייה b קטנה לעומת B גדולה השורה השגוייה :

Find_package(boost 1.49 COMPONENTS system filesystem REQUIRED)


 יצרה את :

CMake Error at CMakeLists.txt:4 (find_package):
  By not providing "Findboost.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "boost", but
  CMake did not find one.

  Could not find a package configuration file provided by "boost" (requested
  version 1.49) with any of the following names:

    boostConfig.cmake
    boost-config.cmake

התוכן של src/main.cc (מתוך liboauthcpp עם מספר שינויים קטנים שלי)  בשביל לבדוק הזדהות מול term.ie :

/**
Copyright (c) 2011 Stanford University (liboauthcpp)
Copyright (C) 2011 by swatkat (swatkat.thinkdigitATgmailDOTcom) (libtwitcurl)
 
 Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/

#include <iostream>
#include <liboauthcpp/liboauthcpp.h>
#include <boost/asio.hpp>

const std::string oauth_consumer_key = "key";            // Key from term.ie
const std::string oauth_consumer_secret = "secret";      // Secret from term.ie
const std::string oauth_server = "term.ie";
const std::string oauth_request_token_path ="/oauth/example/request_token.php";
const std::string oauth_access_token_path = "/oauth/example/access_token.php";
const std::string oauth_protected_path = "/oauth/example/echo_api.php";  //need to perform oauth before accessing
const std::string oauth_protected_resource_params = "method=foo&bar=baz";

//get http message body from server/path?query_string
//return http code , can throw
unsigned int getHttpMessageBody(
        const std::string & request_server,
     const std::string & request_path, 
        const std::string & query_string,
     std::string & message_body);

int main (int argc , char ** argv)
{
   if (argc > 1 && std::string(argv[1]) == std::string("--debug"))
   {
     OAuth::SetLogLevel(OAuth::LogLevelDebug);
   }
   
   OAuth::Consumer consumer(oauth_consumer_key, oauth_consumer_secret);
   OAuth::Client   oauth(&consumer);
           
   std::string request_token_url = "http://" + oauth_server + oauth_request_token_path;
   std::string request_token_query = oauth.getURLQueryString( OAuth::Http::Get, request_token_url);
   std::string request_tokenresp;
 
   if (200 != getHttpMessageBody(oauth_server,oauth_request_token_path,request_token_query,request_tokenresp))
   {
      return 1;
   }
   //Get access token
   OAuth::Token request_token = OAuth::Token::extract( request_tokenresp );
   oauth = OAuth::Client(&consumer, &request_token);

   std::string access_token_url = "http://" + oauth_server + oauth_access_token_path; 
   std::string access_token_query = oauth.getURLQueryString( OAuth::Http::Get, access_token_url, std::string( "" ), true );
   std::string access_token_resp ;

   if (200 != getHttpMessageBody(oauth_server,oauth_access_token_path,access_token_query,access_token_resp))
   {
      return 1;
   }

   OAuth::KeyValuePairs access_token_resp_data = OAuth::ParseKeyValuePairs(access_token_resp);
   OAuth::Token access_token = OAuth::Token::extract( access_token_resp_data );
   //Access token protected resource : 
   OAuth::Client protected_token(&consumer, &access_token);
   std::string oauth_protected_resource =   "http://" + oauth_server + oauth_protected_path;
   std::string protected_resource_query =   protected_token.getURLQueryString(OAuth::Http::Get, oauth_protected_resource + "?" + oauth_protected_resource_params);

   std::string protected_resp ;
   if (200 != getHttpMessageBody(oauth_server,oauth_protected_path,protected_resource_query,protected_resp))
   {
      return 1;
   }
   
   std::cout << protected_resp << std::endl;
                    
   return 0;
}

unsigned int getHttpMessageBody(
        const std::string & request_server,
     const std::string & request_path, 
        const std::string & query_string,
     std::string & message_body)
{
   boost::asio::ip::tcp::iostream stream;
   stream.connect (request_server, "http");
   if (! stream)
   {
     std::cout << " failed to connect to " << request_server << " " << stream.error().message() << std::endl;
     return 500;
   }

   stream << "GET " << request_path <<  "?" << query_string << " HTTP/1.0\r\n"
          << "Host: " <<  request_server << "\r\n"
          << "Accept: */*\r\n"
          << "Connection: close\r\n\r\n";

   stream.flush();
   std::string http_version;
   unsigned int status_code;

   stream >> http_version;
   stream >> status_code;
 
   if (!stream || http_version.substr(0, 5) != "HTTP/")
   {
      return 400;
   }
   if (status_code != 200)
   {
      return status_code;
   }

   std::string header;
   while (std::getline(stream, header) && header != "\r")//skip all headers
   {
   }
   //grab the conent of rdbuf
   std::ostringstream ss;
   ss << stream.rdbuf();
   message_body = ss.str();
   return status_code;
}

אין תגובות:

הוסף רשומת תגובה