2016-05-11 13:45:10 +06:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
*/
2016-05-15 00:31:02 +06:00
# define FORBIDDEN_SYMBOL_ALLOW_ALL
2016-05-11 13:45:10 +06:00
2016-05-11 20:24:53 +06:00
# include "backends/cloud/dropbox/dropboxstorage.h"
2016-05-18 15:21:09 +06:00
# include "backends/networking/curl/connectionmanager.h"
2016-05-17 01:19:49 +06:00
# include "backends/networking/curl/curljsonrequest.h"
2016-05-18 14:08:05 +06:00
# include "common/config-manager.h"
2016-05-11 13:45:10 +06:00
# include "common/debug.h"
2016-05-17 01:19:49 +06:00
# include "common/json.h"
2016-05-15 00:31:02 +06:00
# include <curl/curl.h>
2016-05-11 01:10:37 +06:00
2016-05-12 18:52:57 +06:00
namespace Cloud {
namespace Dropbox {
2016-05-11 01:10:37 +06:00
2016-05-18 14:08:05 +06:00
Common : : String DropboxStorage : : KEY ; //can't use ConfMan there yet, loading it on instance creation/auth
Common : : String DropboxStorage : : SECRET ; //TODO: hide these secrets somehow
2016-05-21 00:44:09 +06:00
static void printJsonCallback ( Networking : : Request * rq , void * ptr ) {
2016-05-18 14:08:05 +06:00
Common : : JSONValue * json = ( Common : : JSONValue * ) ptr ;
if ( json ) {
debug ( " printJsonCallback: " ) ;
debug ( " %s " , json - > stringify ( true ) . c_str ( ) ) ;
delete json ;
} else {
debug ( " printJsonCallback: got NULL instead of JSON! " ) ;
}
}
2016-05-21 00:44:09 +06:00
static void saveAccessTokenCallback ( Networking : : Request * rq , void * ptr ) {
2016-05-17 01:19:49 +06:00
Common : : JSONValue * json = ( Common : : JSONValue * ) ptr ;
if ( json ) {
2016-05-18 14:08:05 +06:00
debug ( " saveAccessTokenCallback: " ) ;
2016-05-17 01:19:49 +06:00
debug ( " %s " , json - > stringify ( true ) . c_str ( ) ) ;
2016-05-18 14:08:05 +06:00
Common : : JSONObject result = json - > asObject ( ) ;
if ( ! result . contains ( " access_token " ) | | ! result . contains ( " uid " ) ) {
warning ( " Bad response, no token/uid passed " ) ;
} else {
ConfMan . set ( " current_storage_type " , " Dropbox " , " cloud " ) ;
ConfMan . set ( " current_storage_access_token " , result . getVal ( " access_token " ) - > asString ( ) , " cloud " ) ;
ConfMan . set ( " current_storage_user_id " , result . getVal ( " uid " ) - > asString ( ) , " cloud " ) ;
ConfMan . removeKey ( " dropbox_code " , " cloud " ) ;
debug ( " Now please restart ScummVM to apply the changes. " ) ;
}
2016-05-17 01:19:49 +06:00
delete json ;
} else {
2016-05-18 14:08:05 +06:00
debug ( " saveAccessTokenCallback: got NULL instead of JSON! " ) ;
2016-05-17 01:19:49 +06:00
}
2016-05-15 00:31:02 +06:00
}
2016-05-21 00:44:09 +06:00
void infoCallback ( Networking : : Request * request , void * jsonPointer ) {
if ( ! request ) {
warning ( " infoCallback: got NULL instead of Request " ) ;
Common : : JSONValue * json = ( Common : : JSONValue * ) jsonPointer ;
if ( json ) delete json ; //yeah I know we can delete NULL safely
return ;
}
Storage : : InfoCallback callback = ( Storage : : InfoCallback ) request - > pointer ( ) ;
Common : : JSONValue * json = ( Common : : JSONValue * ) jsonPointer ;
if ( json ) {
//Common::JSONObject result = json->asObject();
if ( callback ) {
callback ( StorageInfo ( json - > stringify ( ) ) ) ;
}
delete json ;
} else {
warning ( " infoCallback: got NULL instead of JSON! " ) ;
}
}
2016-05-21 14:06:50 +06:00
void info2Callback ( Networking : : Request * request , void * jsonPointer ) {
if ( ! request ) {
warning ( " infoCallback: got NULL instead of Request " ) ;
Common : : JSONValue * json = ( Common : : JSONValue * ) jsonPointer ;
if ( json ) delete json ; //yeah I know we can delete NULL safely
return ;
}
Common : : BaseCallback * callback = ( Common : : BaseCallback * ) request - > pointer ( ) ;
Common : : JSONValue * json = ( Common : : JSONValue * ) jsonPointer ;
if ( json ) {
//Common::JSONObject result = json->asObject();
if ( callback ) {
( * callback ) ( new StorageInfo ( json - > stringify ( ) ) ) ;
delete callback ;
}
delete json ;
} else {
warning ( " infoCallback: got NULL instead of JSON! " ) ;
}
}
2016-05-18 14:08:05 +06:00
DropboxStorage : : DropboxStorage ( Common : : String accessToken , Common : : String userId ) : _token ( accessToken ) , _uid ( userId ) {
2016-05-15 00:31:02 +06:00
curl_global_init ( CURL_GLOBAL_ALL ) ;
}
DropboxStorage : : ~ DropboxStorage ( ) {
curl_global_cleanup ( ) ;
2016-05-11 01:10:37 +06:00
}
2016-05-21 00:44:09 +06:00
void syncSavesInfoCallback ( StorageInfo info ) {
debug ( " info: %s " , info . info ( ) . c_str ( ) ) ;
2016-05-11 15:15:23 +06:00
}
2016-05-21 14:06:50 +06:00
void DropboxStorage : : infoMethodCallback ( void * storageInfo ) {
StorageInfo * info = ( StorageInfo * ) storageInfo ;
debug ( " info: %s " , info - > info ( ) . c_str ( ) ) ;
}
2016-05-21 00:44:09 +06:00
void DropboxStorage : : syncSaves ( OperationCallback callback ) {
2016-05-21 14:06:50 +06:00
//this is not the real syncSaves() implementation
info2 ( new Common : : Callback < DropboxStorage > ( this , & DropboxStorage : : infoMethodCallback ) ) ;
2016-05-18 14:08:05 +06:00
}
2016-05-21 00:44:09 +06:00
void DropboxStorage : : info ( InfoCallback callback ) {
Networking : : CurlJsonRequest * request = new Networking : : CurlJsonRequest ( infoCallback , " https://api.dropboxapi.com/1/account/info " ) ;
2016-05-18 14:08:05 +06:00
request - > addHeader ( " Authorization: Bearer " + _token ) ;
2016-05-18 15:21:09 +06:00
ConnMan . addRequest ( request ) ;
2016-05-21 00:44:09 +06:00
request - > setPointer ( callback ) ;
2016-05-18 14:08:05 +06:00
}
2016-05-21 14:06:50 +06:00
void DropboxStorage : : info2 ( Common : : Callback < DropboxStorage > * callback ) {
Networking : : CurlJsonRequest * request = new Networking : : CurlJsonRequest ( info2Callback , " https://api.dropboxapi.com/1/account/info " ) ;
request - > addHeader ( " Authorization: Bearer " + _token ) ;
ConnMan . addRequest ( request ) ;
request - > setPointer ( callback ) ;
}
2016-05-18 14:08:05 +06:00
DropboxStorage * DropboxStorage : : loadFromConfig ( ) {
KEY = ConfMan . get ( " DROPBOX_KEY " , " cloud " ) ;
SECRET = ConfMan . get ( " DROPBOX_SECRET " , " cloud " ) ;
if ( ! ConfMan . hasKey ( " current_storage_access_token " , " cloud " ) ) {
warning ( " No access_token found " ) ;
return 0 ;
}
if ( ! ConfMan . hasKey ( " current_storage_user_id " , " cloud " ) ) {
warning ( " No user_id found " ) ;
return 0 ;
}
Common : : String accessToken = ConfMan . get ( " current_storage_access_token " , " cloud " ) ;
Common : : String userId = ConfMan . get ( " current_storage_user_id " , " cloud " ) ;
return new DropboxStorage ( accessToken , userId ) ;
}
Common : : String DropboxStorage : : getAuthLink ( ) {
Common : : String url = " https://www.dropbox.com/1/oauth2/authorize " ;
url + = " ?response_type=code " ;
url + = " &redirect_uri=http://localhost:12345/ " ; //that's for copy-pasting
//url += "&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"; //that's "http://localhost:12345/" for automatic opening
url + = " &client_id= " + KEY ;
return url ;
}
2016-05-18 15:21:09 +06:00
void DropboxStorage : : authThroughConsole ( ) {
2016-05-18 14:08:05 +06:00
if ( ! ConfMan . hasKey ( " DROPBOX_KEY " , " cloud " ) | | ! ConfMan . hasKey ( " DROPBOX_SECRET " , " cloud " ) ) {
warning ( " No Dropbox keys available, cannot do auth " ) ;
2016-05-18 15:21:09 +06:00
return ;
2016-05-18 14:08:05 +06:00
}
KEY = ConfMan . get ( " DROPBOX_KEY " , " cloud " ) ;
SECRET = ConfMan . get ( " DROPBOX_SECRET " , " cloud " ) ;
if ( ConfMan . hasKey ( " dropbox_code " , " cloud " ) ) {
//phase 2: get access_token using specified code
2016-05-18 15:21:09 +06:00
getAccessToken ( ConfMan . get ( " dropbox_code " , " cloud " ) ) ;
return ;
2016-05-18 14:08:05 +06:00
}
debug ( " Navigate to this URL and press \" Allow \" : " ) ;
debug ( " %s \n " , getAuthLink ( ) . c_str ( ) ) ;
debug ( " Then, add dropbox_code key in [cloud] section of configuration file. You should copy the <code> value from URL and put it as value for that key. \n " ) ;
debug ( " Navigate to this URL to get more information on ScummVM's configuration files: " ) ;
2016-05-18 15:21:09 +06:00
debug ( " http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM#Using_the_configuration_file_to_configure_ScummVM \n " ) ;
2016-05-18 14:08:05 +06:00
}
2016-05-18 15:21:09 +06:00
void DropboxStorage : : getAccessToken ( Common : : String code ) {
2016-05-18 14:08:05 +06:00
Networking : : CurlJsonRequest * request = new Networking : : CurlJsonRequest ( saveAccessTokenCallback , " https://api.dropboxapi.com/1/oauth2/token " ) ;
request - > addPostField ( " code= " + code ) ;
request - > addPostField ( " grant_type=authorization_code " ) ;
request - > addPostField ( " client_id= " + KEY ) ;
request - > addPostField ( " client_secret= " + SECRET ) ;
2016-05-18 15:21:09 +06:00
request - > addPostField ( " &redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F " ) ;
ConnMan . addRequest ( request ) ;
2016-05-11 15:15:23 +06:00
}
2016-05-12 18:52:57 +06:00
} //end of namespace Dropbox
} //end of namespace Cloud