use a config file to save credentials

pull/40/head
Matchman Green 2012-04-26 09:20:41 +08:00
parent 5830458ad0
commit b717bfb0d2
5 changed files with 127 additions and 19 deletions

View File

@ -34,7 +34,7 @@ Drive::Drive( OAuth2& auth ) :
m_http_hdr.push_back( "Authorization: Bearer " + m_auth.AccessToken() ) ;
m_http_hdr.push_back( "GData-Version: 3.0" ) ;
Json resp( HttpGet( "https://docs.google.com/feeds/default/private/full?alt=json", m_http_hdr ) ) ;
Json resp = Json::Parse(HttpGet( "https://docs.google.com/feeds/default/private/full?alt=json", m_http_hdr )) ;
/* Json::Object map = resp["feed"]["id"].As<Json::Object>() ;
for ( Json::Object::iterator i = map.begin() ; i != map.end() ; ++i )

View File

@ -23,16 +23,43 @@
#include <json/linkhash.h>
#include <cassert>
#include <ostream>
#include <iostream>
#include <sstream>
#include <stdexcept>
namespace gr {
Json::Json( const std::string& str ) :
m_json( ::json_tokener_parse( str.c_str() ) )
Json::Json( ) :
m_json( ::json_object_new_object() )
{
if ( m_json == 0 )
throw std::runtime_error( "cannot create json object" ) ;
}
template <>
Json::Json( const std::string& str ) :
m_json( ::json_object_new_string( str.c_str() ) )
{
if ( m_json == 0 )
throw std::runtime_error( "cannot create json string \"" + str + "\"" ) ;
// paranoid check
assert( ::json_object_get_string( m_json ) == str ) ;
}
Json Json::Parse( const std::string& str )
{
struct json_object *json = ::json_tokener_parse( str.c_str() ) ;
if ( json == 0 )
throw std::runtime_error( "json parse error" ) ;
return Json( json, NotOwned() ) ;
}
Json::Json( struct json_object *json, NotOwned ) :
m_json( json )
{
assert( json != 0 ) ;
}
Json::Json( struct json_object *json ) :
@ -80,12 +107,36 @@ Json Json::operator[]( const std::string& key ) const
return Json( j ) ;
}
Json Json::operator[]( const std::size_t& idx ) const
{
assert( m_json != 0 ) ;
struct json_object *j = ::json_object_array_get_idx( m_json, idx ) ;
if ( j == 0 )
{
std::ostringstream ss ;
ss << "index " << idx << " is not found in array" ;
throw std::runtime_error( ss.str() ) ;
}
return Json( j ) ;
}
bool Json::Has( const std::string& key ) const
{
assert( m_json != 0 ) ;
return ::json_object_object_get( m_json, key.c_str() ) != 0 ;
}
void Json::Add( const std::string& key, const Json& json )
{
assert( m_json != 0 ) ;
assert( json.m_json != 0 ) ;
::json_object_get( json.m_json ) ;
::json_object_object_add( m_json, key.c_str(), json.m_json ) ;
}
template <>
std::string Json::As<std::string>() const
{

View File

@ -34,11 +34,17 @@ public :
typedef std::vector<Json> Array ;
public :
Json( const std::string& str ) ;
template <typename T>
explicit Json( const T& val ) ;
Json() ;
Json( const Json& rhs ) ;
~Json( ) ;
static Json Parse( const std::string& str ) ;
Json operator[]( const std::string& key ) const ;
Json operator[]( const std::size_t& idx ) const ;
Json& operator=( const Json& rhs ) ;
void Swap( Json& other ) ;
@ -50,6 +56,7 @@ public :
bool Is() const ;
bool Has( const std::string& key ) const ;
void Add( const std::string& key, const Json& json ) ;
friend std::ostream& operator<<( std::ostream& os, const Json& json ) ;
@ -60,6 +67,9 @@ public :
private :
Json( struct json_object *json ) ;
struct NotOwned {} ;
Json( struct json_object *json, NotOwned ) ;
private :
struct json_object *m_json ;
} ;

View File

@ -49,7 +49,7 @@ void OAuth2::Auth( const std::string& auth_code )
"&redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob" +
"&grant_type=authorization_code" ;
Json resp( HttpPostData( token_url, post ) ) ;
Json resp = Json::Parse( HttpPostData( token_url, post ) ) ;
m_access = resp["access_token"].As<std::string>() ;
m_refresh = resp["refresh_token"].As<std::string>() ;
}
@ -78,7 +78,7 @@ void OAuth2::Refresh( )
"&client_secret=" + client_secret +
"&grant_type=refresh_token" ;
Json resp( HttpPostData( token_url, post ) ) ;
Json resp = Json::Parse( HttpPostData( token_url, post ) ) ;
m_access = resp["access_token"].As<std::string>() ;
}

View File

@ -19,14 +19,54 @@
#include "OAuth2.hh"
#include "Drive.hh"
#include "Json.hh"
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
namespace gr
{
const std::string& ConfigFilename()
{
static const char *env_cfg = ::getenv( "GR_CONFIG" ) ;
static const std::string filename =
(env_cfg != 0) ? env_cfg : std::string( ::getenv( "HOME") ) + "/.grive" ;
return filename ;
}
Json ReadConfig()
{
std::cout << ConfigFilename() << std::endl ;
std::ifstream ifile( ConfigFilename().c_str() ) ;
if ( ifile )
{
std::string cfg_str(
(std::istreambuf_iterator<char>( ifile )),
(std::istreambuf_iterator<char>()) ) ;
return Json::Parse( cfg_str ) ;
}
else
return Json() ;
}
void SaveConfig( const Json& config )
{
std::ofstream ofile( ConfigFilename().c_str() ) ;
ofile << config ;
}
}
int main( int argc, char **argv )
{
using namespace gr ;
Json config = ReadConfig() ;
int c ;
while ((c = getopt (argc, argv, "ac:")) != -1)
@ -35,24 +75,31 @@ int main( int argc, char **argv )
{
case 'a' :
{
std::cout <<
OAuth2::MakeAuthURL( "22314510474.apps.googleusercontent.com" ) << std::endl ;
return 0 ;
}
case 'c' :
{
std::cout
<< "Please go to this URL and enter the code:\n"
<< OAuth2::MakeAuthURL( "22314510474.apps.googleusercontent.com" )
<< std::endl ;
std::string code ;
std::cin >> code ;
OAuth2 token ;
token.Auth( optarg ) ;
token.Auth( code ) ;
// print the refresh token an exist
std::cout << token.RefreshToken() << std::endl ;
return 0 ;
std::cout << "got refresh token: " << token.RefreshToken() << std::endl ;
// save to config
config.Add( "refresh_token", Json( token.RefreshToken() ) ) ;
assert( config["refresh_token"].As<std::string>() == token.RefreshToken() ) ;
SaveConfig( config ) ;
break ;
}
}
}
OAuth2 token( getenv( "GR_REFRESH_CODE" ) ) ;
OAuth2 token( config["refresh_token"].As<std::string>() ) ;
Drive drive( token ) ;
return 0 ;