-package com.owncloud.android.authenticator.oauth2.services;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.message.BasicNameValuePair;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.util.Log;
-
-import com.owncloud.android.authenticator.oauth2.OAuth2Context;
-import com.owncloud.android.authenticator.oauth2.connection.ConnectorOAuth2;
-
-/**
- * Service class that implements the second communication with the oAuth2 server:
- * pooling for the token in an interval. It send a broadcast with the results when are positive;
- * otherwise, it continues asking to the server.
- *
- * @author Solid Gear S.L.
- *
- */
-public class OAuth2GetTokenService extends Service {
-
- public static final String TOKEN_RECEIVED_MESSAGE = "TOKEN_RECEIVED";
- public static final String TOKEN_RECEIVED_DATA = "TOKEN_DATA";
- public static final String TOKEN_URI = "TOKEN_URI";
- public static final String TOKEN_DEVICE_CODE = "device_code";
- public static final String TOKEN_INTERVAL = "interval";
- public static final String TOKEN_RECEIVED_ERROR = "error";
- public static final String TOKEN_RECEIVED_ERROR_AUTH_TOKEN = "authorization_pending";
- public static final String TOKEN_RECEIVED_ERROR_SLOW_DOWN = "slow_down";
- public static final String TOKEN_ACCESS_TOKEN = "access_token";
- public static final String TOKEN_TOKEN_TYPE = "token_type";
- public static final String TOKEN_EXPIRES_IN = "expires_in";
- public static final String TOKEN_REFRESH_TOKEN = "refresh_token";
-
- private String requestDeviceCode;
- private int requestInterval = -1;
- private String requestBaseURI;
- private ConnectorOAuth2 connectorOAuth2;
- private static final String TAG = "OAuth2GetTokenService";
- private Timer timer = new Timer();
-
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Bundle param = intent.getExtras();
-
- if (param != null) {
- String mUrl = param.getString(TOKEN_URI);
- if (!mUrl.startsWith("http://") || !mUrl.startsWith("https://")) {
- requestBaseURI = "https://" + mUrl;
- }
- requestDeviceCode = param.getString(TOKEN_DEVICE_CODE);
- requestInterval = param.getInt(TOKEN_INTERVAL);
-
- Log.d(TAG, "onStartCommand -> requestDeviceCode=" + requestDeviceCode);
- Log.d(TAG, "onStartCommand -> requestInterval=" + requestInterval);
- } else {
- Log.e(TAG, "onStartCommand -> params could not be null");
- }
- startService();
- return Service.START_NOT_STICKY;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- shutdownService();
- }
-
- private void startService() {
- final UrlEncodedFormEntity params = prepareComm();
- timer.scheduleAtFixedRate(
- new TimerTask() {
- public void run() {
- requestToken(params);
- }
- }, 0, requestInterval * 1000);
- Log.d(TAG, "startService -> Timer started");
- }
-
- private void shutdownService() {
- if (timer != null) timer.cancel();
- Log.d(TAG, "shutdownService -> Timer stopped");
- }
-
-
- private UrlEncodedFormEntity prepareComm() {
-
- UrlEncodedFormEntity params = null;
- connectorOAuth2 = new ConnectorOAuth2();
-
- if (requestBaseURI == null || requestBaseURI.trim().equals("")) {
- Log.e(TAG, "run -> request URI could not be null");
- postResult(null);
- }
-
- if (requestInterval == -1) {
- Log.e(TAG, "run -> request Interval must have valid positive value");
- postResult(null);
- }
-
- if (requestDeviceCode == null || requestDeviceCode.trim().equals("")) {
- Log.e(TAG, "run -> request DeviceCode could not be null");
- postResult(null);
- }
-
- try{
- connectorOAuth2.setConnectorOAuth2Url(requestBaseURI + OAuth2Context.OAUTH2_G_DEVICE_GETTOKEN_URL);
-
- List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
- nameValuePairs.add(new BasicNameValuePair("client_id", OAuth2Context.OAUTH2_G_DEVICE_CLIENT_ID));
- nameValuePairs.add(new BasicNameValuePair("client_secret", OAuth2Context.OAUTH2_G_DEVICE_CLIENT_SECRET));
- nameValuePairs.add(new BasicNameValuePair("code",requestDeviceCode));
- nameValuePairs.add(new BasicNameValuePair("grant_type",OAuth2Context.OAUTH_G_DEVICE_GETTOKEN_GRANT_TYPE));
-
- params = new UrlEncodedFormEntity(nameValuePairs);
- }
- catch (Exception ex1){
- Log.w(TAG, ex1.toString());
- postResult(null);
- }
-
- return params;
- }
-
- protected void requestToken(UrlEncodedFormEntity params){
- JSONObject tokenJson = null;
- String error = null;
- HashMap<String, String> resultTokenMap;
-
- String tokenResponse = connectorOAuth2.connPost(params);
-
- try {
- tokenJson = new JSONObject(tokenResponse);
- } catch (JSONException e) {
- Log.e(TAG, "Exception converting to Json " + e.toString());
- }
-
- try {
- // We try to get error string.
- if (tokenJson.has(TOKEN_RECEIVED_ERROR)) {
- error = tokenJson.getString(TOKEN_RECEIVED_ERROR);
- Log.d(TAG, "requestToken -> Obtained error "+ error);
- } else {
- //We have got the token. Parse the answer.
- resultTokenMap = parseResult(tokenJson);
- postResult(resultTokenMap);
- }
- } catch (JSONException e) {
- Log.e(TAG, "Exception converting to Json " + e.toString());
- }
- }
-
- private HashMap<String, String> parseResult (JSONObject tokenJson) {
- HashMap<String, String> resultTokenMap=new HashMap<String, String>();
-
- try {
- resultTokenMap.put(TOKEN_ACCESS_TOKEN, tokenJson.getString(TOKEN_ACCESS_TOKEN));
- resultTokenMap.put(TOKEN_TOKEN_TYPE, tokenJson.getString(TOKEN_TOKEN_TYPE));
- resultTokenMap.put(TOKEN_EXPIRES_IN, tokenJson.getString(TOKEN_EXPIRES_IN));
- resultTokenMap.put(TOKEN_REFRESH_TOKEN, tokenJson.getString(TOKEN_REFRESH_TOKEN));
- } catch (JSONException e) {
- Log.e(TAG, "parseResult: Exception converting to Json " + e.toString());
- }
- return resultTokenMap;
- }
-
- /**
- * Returns obtained values with a broadcast.
- *
- * @param tokenResponse : obtained values.
- */
- private void postResult(HashMap<String, String> tokenResponse) {
- Intent intent = new Intent(TOKEN_RECEIVED_MESSAGE);
- intent.putExtra(TOKEN_RECEIVED_DATA,tokenResponse);
- sendBroadcast(intent);
- shutdownService();
- }
-}