83796d
From 32aecffb5517dfc3b3674a8f7db418456bd877ed Mon Sep 17 00:00:00 2001
83796d
From: Giuseppe Castagno <giuseppe.castagno@acca-esse.eu>
83796d
Date: Sat, 30 Apr 2016 14:29:56 +0200
83796d
Subject: [PATCH 1/5] Add new Google Drive OAuth 2.0 login procedure.
83796d
83796d
The new Google login sequence uses two html pages: first page for user email
83796d
the second page for password.
83796d
83796d
The older sequence used only one page for both user email and user password.
83796d
---
83796d
 src/libcmis/oauth2-providers.cxx | 67 +++++++++++++++++++++++++++++++---------
83796d
 1 file changed, 52 insertions(+), 15 deletions(-)
83796d
83796d
diff --git a/src/libcmis/oauth2-providers.cxx b/src/libcmis/oauth2-providers.cxx
83796d
index 5e7f3bf..68a6aa5 100644
83796d
--- a/src/libcmis/oauth2-providers.cxx
83796d
+++ b/src/libcmis/oauth2-providers.cxx
83796d
@@ -37,11 +37,28 @@ using namespace std;
83796d
 string OAuth2Providers::OAuth2Gdrive( HttpSession* session, const string& authUrl,
83796d
                                       const string& username, const string& password )
83796d
 {
83796d
+    /* This member function implements 'Google OAuth 2.0'
83796d
+     *
83796d
+     * The interaction is carried out by libcmis, with no web browser involved.
83796d
+     *
83796d
+     * Normal sequence (without 2FA) is:
83796d
+     * 1) a get to activate login page
83796d
+     *    receive first login page, html format
83796d
+     * 2) subsequent post to sent email
83796d
+     *    receive html page for password input
83796d
+     * 3) subsequent post to send password
83796d
+     *    receive html page for application consent
83796d
+     * 4) subsequent post to send a consent for the application
83796d
+     *    receive a single-use authorization code
83796d
+     *    this code is returned as a string
83796d
+     */
83796d
+
83796d
     static const string CONTENT_TYPE( "application/x-www-form-urlencoded" );
83796d
     // STEP 1: Log in
83796d
     string res;
83796d
     try
83796d
     {
83796d
+        // send the first get, receive the html login page
83796d
         res = session->httpGetRequest( authUrl )->getStream( )->str( );
83796d
     }
83796d
     catch ( const CurlException& e )
83796d
@@ -49,20 +66,39 @@ string OAuth2Providers::OAuth2Gdrive( HttpSession* session, const string& authUr
83796d
         return string( );
83796d
     }
83796d
 
83796d
-    string loginPost, loginLink; 
83796d
-    if ( !parseResponse( res.c_str( ), loginPost, loginLink ) ) 
83796d
+    string loginEmailPost, loginEmailLink;
83796d
+    if ( !parseResponse( res.c_str( ), loginEmailPost, loginEmailLink ) )
83796d
         return string( );
83796d
-    
83796d
-    loginPost += "Email=";  
83796d
-    loginPost += string( username );
83796d
-    loginPost += "&Passwd=";
83796d
-    loginPost += string( password );
83796d
-    
83796d
-    istringstream loginIs( loginPost );
83796d
-    string loginRes;
83796d
-    try 
83796d
+
83796d
+    loginEmailPost += "Email=";
83796d
+    loginEmailPost += string( username );
83796d
+
83796d
+    istringstream loginEmailIs( loginEmailPost );
83796d
+    string loginEmailRes;
83796d
+    try
83796d
+    {
83796d
+        // send a post with user email, receive the html page for password input
83796d
+        loginEmailRes = session->httpPostRequest ( loginEmailLink, loginEmailIs, CONTENT_TYPE )
83796d
+                        ->getStream( )->str( );
83796d
+    }
83796d
+    catch ( const CurlException& e )
83796d
+    {
83796d
+        return string( );
83796d
+    }
83796d
+
83796d
+    string loginPasswdPost, loginPasswdLink;
83796d
+    if ( !parseResponse( loginEmailRes.c_str( ), loginPasswdPost, loginPasswdLink ) )
83796d
+        return string( );
83796d
+
83796d
+    loginPasswdPost += "Passwd=";
83796d
+    loginPasswdPost += string( password );
83796d
+
83796d
+    istringstream loginPasswdIs( loginPasswdPost );
83796d
+    string loginPasswdRes;
83796d
+    try
83796d
     {
83796d
-        loginRes = session->httpPostRequest ( loginLink, loginIs, CONTENT_TYPE )
83796d
+        // send a post with user password, receive the application consent page
83796d
+        loginPasswdRes = session->httpPostRequest ( loginPasswdLink, loginPasswdIs, CONTENT_TYPE )
83796d
                         ->getStream( )->str( );
83796d
     }
83796d
     catch ( const CurlException& e )
83796d
@@ -71,8 +107,8 @@ string OAuth2Providers::OAuth2Gdrive( HttpSession* session, const string& authUr
83796d
     }
83796d
 
83796d
     // STEP 2: allow libcmis to access google drive
83796d
-    string approvalPost, approvalLink; 
83796d
-    if ( !parseResponse( loginRes. c_str( ), approvalPost, approvalLink) )
83796d
+    string approvalPost, approvalLink;
83796d
+    if ( !parseResponse( loginPasswdRes. c_str( ), approvalPost, approvalLink) )
83796d
         return string( );
83796d
     approvalPost += "submit_access=true";
83796d
 
83796d
@@ -80,7 +116,8 @@ string OAuth2Providers::OAuth2Gdrive( HttpSession* session, const string& authUr
83796d
     string approvalRes;
83796d
     try
83796d
     {
83796d
-        approvalRes = session->httpPostRequest ( approvalLink, approvalIs, 
83796d
+        // send a post with application consent
83796d
+        approvalRes = session->httpPostRequest ( approvalLink, approvalIs,
83796d
                             CONTENT_TYPE) ->getStream( )->str( );
83796d
     }
83796d
     catch ( const CurlException& e )
83796d
-- 
83796d
2.7.4
83796d