2  *   ownCloud Android client application 
   4  *   Copyright (C) 2015 ownCloud Inc. 
   6  *   This program is free software: you can redistribute it and/or modify 
   7  *   it under the terms of the GNU General Public License version 2, 
   8  *   as published by the Free Software Foundation. 
  10  *   This program is distributed in the hope that it will be useful, 
  11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  13  *   GNU General Public License for more details. 
  15  *   You should have received a copy of the GNU General Public License 
  16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  20 package com
.owncloud
.android
.operations
; 
  22 import java
.util
.ArrayList
; 
  23 import java
.util
.HashMap
; 
  26 import org
.apache
.commons
.httpclient
.methods
.PostMethod
; 
  27 import org
.apache
.commons
.httpclient
.NameValuePair
; 
  28 import org
.json
.JSONException
; 
  29 import org
.json
.JSONObject
; 
  31 import com
.owncloud
.android
.authentication
.OAuth2Constants
; 
  32 import com
.owncloud
.android
.lib
.common
.OwnCloudClient
; 
  33 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperation
; 
  34 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
; 
  35 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
.ResultCode
; 
  36 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
; 
  39 public class OAuth2GetAccessToken 
extends RemoteOperation 
{ 
  41     private static final String TAG 
= OAuth2GetAccessToken
.class.getSimpleName(); 
  43     private String mClientId
; 
  44     private String mRedirectUri
; 
  45     private String mGrantType
; 
  47     private String mOAuth2AuthorizationResponse
; 
  48     private Map
<String
, String
> mOAuth2ParsedAuthorizationResponse
; 
  49     private Map
<String
, String
> mResultTokenMap
; 
  52     public OAuth2GetAccessToken(String clientId
, String redirectUri
, String grantType
, String oAuth2AuthorizationResponse
) { 
  54         mRedirectUri 
= redirectUri
; 
  55         mGrantType 
= grantType
; 
  56         mOAuth2AuthorizationResponse 
= oAuth2AuthorizationResponse
; 
  57         mOAuth2ParsedAuthorizationResponse 
= new HashMap
<String
, String
>(); 
  58         mResultTokenMap 
= null
; 
  62     public Map<String, String> getResultTokenMap() { 
  63         return mResultTokenMap; 
  68     protected RemoteOperationResult 
run(OwnCloudClient client
) { 
  69         RemoteOperationResult result 
= null
; 
  70         PostMethod postMethod 
= null
; 
  73             parseAuthorizationResponse(); 
  74             if (mOAuth2ParsedAuthorizationResponse
.keySet().contains(OAuth2Constants
.KEY_ERROR
)) { 
  75                 if (OAuth2Constants
.VALUE_ERROR_ACCESS_DENIED
.equals(mOAuth2ParsedAuthorizationResponse
.get(OAuth2Constants
.KEY_ERROR
))) { 
  76                     result 
= new RemoteOperationResult(ResultCode
.OAUTH2_ERROR_ACCESS_DENIED
); 
  78                     result 
= new RemoteOperationResult(ResultCode
.OAUTH2_ERROR
); 
  83                 NameValuePair
[] nameValuePairs 
= new NameValuePair
[4]; 
  84                 nameValuePairs
[0] = new NameValuePair(OAuth2Constants
.KEY_GRANT_TYPE
, mGrantType
); 
  85                 nameValuePairs
[1] = new NameValuePair(OAuth2Constants
.KEY_CODE
, mOAuth2ParsedAuthorizationResponse
.get(OAuth2Constants
.KEY_CODE
));             
  86                 nameValuePairs
[2] = new NameValuePair(OAuth2Constants
.KEY_REDIRECT_URI
, mRedirectUri
);        
  87                 nameValuePairs
[3] = new NameValuePair(OAuth2Constants
.KEY_CLIENT_ID
, mClientId
); 
  88                 //nameValuePairs[4] = new NameValuePair(OAuth2Constants.KEY_SCOPE, mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_SCOPE));          
  90                 postMethod 
= new PostMethod(client
.getWebdavUri().toString()); 
  91                 postMethod
.setRequestBody(nameValuePairs
); 
  92                 int status 
= client
.executeMethod(postMethod
); 
  94                 String response 
= postMethod
.getResponseBodyAsString(); 
  95                 if (response 
!= null 
&& response
.length() > 0) { 
  96                     JSONObject tokenJson 
= new JSONObject(response
); 
  97                     parseAccessTokenResult(tokenJson
); 
  98                     if (mResultTokenMap
.get(OAuth2Constants
.KEY_ERROR
) != null 
|| mResultTokenMap
.get(OAuth2Constants
.KEY_ACCESS_TOKEN
) == null
) { 
  99                         result 
= new RemoteOperationResult(ResultCode
.OAUTH2_ERROR
); 
 102                         result 
= new RemoteOperationResult(true
, status
, postMethod
.getResponseHeaders()); 
 103                         ArrayList
<Object
> data 
= new ArrayList
<Object
>(); 
 104                         data
.add(mResultTokenMap
); 
 105                         result
.setData(data
); 
 109                     client
.exhaustResponse(postMethod
.getResponseBodyAsStream()); 
 110                     result 
= new RemoteOperationResult(false
, status
, postMethod
.getResponseHeaders()); 
 114         } catch (Exception e
) { 
 115             result 
= new RemoteOperationResult(e
); 
 118             if (postMethod 
!= null
) 
 119                 postMethod
.releaseConnection();    // let the connection available for other methods 
 121             if (result
.isSuccess()) { 
 122                 Log_OC
.i(TAG
, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse
.get("code") + " to " + client
.getWebdavUri() + ": " + result
.getLogMessage()); 
 124             } else if (result
.getException() != null
) { 
 125                 Log_OC
.e(TAG
, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse
.get("code") + " to " + client
.getWebdavUri() + ": " + result
.getLogMessage(), result
.getException()); 
 127             } else if (result
.getCode() == ResultCode
.OAUTH2_ERROR
) { 
 128                 Log_OC
.e(TAG
, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse
.get("code") + " to " + client
.getWebdavUri() + ": " + ((mResultTokenMap 
!= null
) ? mResultTokenMap
.get(OAuth2Constants
.KEY_ERROR
) : "NULL")); 
 131                 Log_OC
.e(TAG
, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse
.get("code") + " to " + client
.getWebdavUri() + ": " + result
.getLogMessage()); 
 139     private void parseAuthorizationResponse() { 
 140         String
[] pairs 
= mOAuth2AuthorizationResponse
.split("&"); 
 144         StringBuilder sb 
= new StringBuilder(); 
 145         while (pairs
.length 
> i
) { 
 147             String
[] part 
= pairs
[i
].split("="); 
 148             while (part
.length 
> j
) { 
 152                     sb
.append(key 
+ " = "); 
 155                     mOAuth2ParsedAuthorizationResponse
.put(key
, value
); 
 156                     sb
.append(value 
+ "\n"); 
 159                 Log_OC
.v(TAG
, "[" + i 
+ "," + j 
+ "] = " + p
); 
 167     private void parseAccessTokenResult (JSONObject tokenJson
) throws JSONException 
{ 
 168         mResultTokenMap 
= new HashMap
<String
, String
>(); 
 170         if (tokenJson
.has(OAuth2Constants
.KEY_ACCESS_TOKEN
)) { 
 171             mResultTokenMap
.put(OAuth2Constants
.KEY_ACCESS_TOKEN
, tokenJson
.getString(OAuth2Constants
.KEY_ACCESS_TOKEN
)); 
 173         if (tokenJson
.has(OAuth2Constants
.KEY_TOKEN_TYPE
)) { 
 174             mResultTokenMap
.put(OAuth2Constants
.KEY_TOKEN_TYPE
, tokenJson
.getString(OAuth2Constants
.KEY_TOKEN_TYPE
)); 
 176         if (tokenJson
.has(OAuth2Constants
.KEY_EXPIRES_IN
)) { 
 177             mResultTokenMap
.put(OAuth2Constants
.KEY_EXPIRES_IN
, tokenJson
.getString(OAuth2Constants
.KEY_EXPIRES_IN
)); 
 179         if (tokenJson
.has(OAuth2Constants
.KEY_REFRESH_TOKEN
)) { 
 180             mResultTokenMap
.put(OAuth2Constants
.KEY_REFRESH_TOKEN
, tokenJson
.getString(OAuth2Constants
.KEY_REFRESH_TOKEN
)); 
 182         if (tokenJson
.has(OAuth2Constants
.KEY_SCOPE
)) { 
 183             mResultTokenMap
.put(OAuth2Constants
.KEY_SCOPE
, tokenJson
.getString(OAuth2Constants
.KEY_SCOPE
)); 
 185         if (tokenJson
.has(OAuth2Constants
.KEY_ERROR
)) { 
 186             mResultTokenMap
.put(OAuth2Constants
.KEY_ERROR
, tokenJson
.getString(OAuth2Constants
.KEY_ERROR
)); 
 188         if (tokenJson
.has(OAuth2Constants
.KEY_ERROR_DESCRIPTION
)) { 
 189             mResultTokenMap
.put(OAuth2Constants
.KEY_ERROR_DESCRIPTION
, tokenJson
.getString(OAuth2Constants
.KEY_ERROR_DESCRIPTION
)); 
 191         if (tokenJson
.has(OAuth2Constants
.KEY_ERROR_URI
)) { 
 192             mResultTokenMap
.put(OAuth2Constants
.KEY_ERROR_URI
, tokenJson
.getString(OAuth2Constants
.KEY_ERROR_URI
));