com.coloreight.plugin.socialAuth.SocialAuth.java Source code

Java tutorial

Introduction

Here is the source code for com.coloreight.plugin.socialAuth.SocialAuth.java

Source

/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Coloreight LLC
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.coloreight.plugin.socialAuth;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookAuthorizationException;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class SocialAuth extends CordovaPlugin {

    private AccountManager accountManager;
    private String requestedTwitterAccountName;
    private CallbackManager fbCallbackManager;
    private CallbackContext callbackContext;

    public static final String TAG = "SocialAuth";
    public static final int TWITTER_OAUTH_REQUEST = 1;

    @Override
    protected void pluginInitialize() {
        super.pluginInitialize();

        FacebookSdk.sdkInitialize(this.cordova.getActivity().getApplicationContext());

        fbCallbackManager = CallbackManager.Factory.create();

        LoginManager.getInstance().registerCallback(fbCallbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                try {
                    JSONObject json = new JSONObject();

                    json.put("userId", loginResult.getAccessToken().getUserId());
                    json.put("accessToken", loginResult.getAccessToken().getToken());
                    json.put("hasWritePermissions",
                            loginResult.getAccessToken().getPermissions().contains("publish_actions"));

                    PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, json);

                    Log.v(TAG, "Facebook SDK auth success -> sended data: " + json.toString());
                    callbackContext.sendPluginResult(pluginResult);
                } catch (JSONException e) {
                    PluginResult pluginResult = new PluginResult(PluginResult.Status.ERROR,
                            e.getLocalizedMessage());

                    callbackContext.sendPluginResult(pluginResult);
                }
            }

            @Override
            public void onCancel() {
                Log.v(TAG, "Facebook auth canceled");

                callbackContext.error("Facebook auth cancelled");
            }

            @Override
            public void onError(FacebookException exception) {
                if (exception instanceof FacebookAuthorizationException) {
                    if (AccessToken.getCurrentAccessToken() != null) {
                        LoginManager.getInstance().logOut();
                    }
                }

                Log.v(TAG, "Facebook auth error -> message:" + exception.getLocalizedMessage());

                callbackContext.error("Facebook auth error -> message:" + exception.getLocalizedMessage());
            }
        });
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;
        accountManager = AccountManager.get(this.cordova.getActivity().getApplicationContext());

        if (action.equals("canUseTwitterSystemAccount")) {
            this.canUseTwitterSystemAccount(callbackContext);
        } else if (action.equals("getTwitterSystemAccounts")) {
            this.getTwitterSystemAccounts(callbackContext);
        } else if (action.equals("getTwitterSystemAccount")) {
            this.getTwitterSystemAccount(args.getString(0), callbackContext);
        } else if (action.equals("setFacebookApp")) {
            this.setFacebookApp(args.getJSONObject(0), callbackContext);
        } else if (action.equals("getFacebookAccount")) {
            this.getFacebookAccount(args.getJSONObject(0), args.getString(1), callbackContext);
        } else {
            Log.d(TAG, "invalid/na social auth method: " + action);
            callbackContext.error("invalid/na social auth method: " + action);

            return false;
        }

        return true;
    }

    public void setFacebookApp(final JSONObject app, final CallbackContext callbackContext) {
        try {
            String displayName = app.getString("name");
            String appId = app.getString("id");

            FacebookSdk.setApplicationName(displayName);
            FacebookSdk.setApplicationId(appId);

            callbackContext.success();
        } catch (Exception e) {
            // do nothing
        }
    }

    public void getFacebookAccount(final JSONObject permissions, final String permissionsType,
            final CallbackContext callbackContext) {

        final SocialAuth me = this;

        cordova.getThreadPool().execute(new Runnable() {
            public void run() {

                try {
                    ArrayList<String> fbPermissions = new ArrayList<String>();

                    JSONArray jsonArray = (JSONArray) permissions.get("permissions");

                    if (jsonArray != null) {
                        int len = jsonArray.length();

                        for (int i = 0; i < len; i++) {
                            fbPermissions.add(jsonArray.get(i).toString());
                        }
                    }

                    LoginManager loginManager = LoginManager.getInstance();

                    cordova.setActivityResultCallback(me);

                    if (permissionsType.equals("write")) {
                        loginManager.logInWithPublishPermissions(cordova.getActivity(), fbPermissions);
                    } else {
                        loginManager.logInWithReadPermissions(cordova.getActivity(), fbPermissions);
                    }
                } catch (Exception e) {
                    callbackContext.error(e.getMessage());
                }
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        fbCallbackManager.onActivityResult(requestCode, resultCode, intent);

        if (requestCode == SocialAuth.TWITTER_OAUTH_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                Log.v(TAG, "On activity result with authtoken: " + intent.getExtras().keySet());

                for (String key : intent.getExtras().keySet()) {
                    Object value = intent.getExtras().get(key);
                    try {
                        String valueStr = value.toString();

                        Log.v("AUTH", String.format("%s %s (%s)", key, valueStr, value.getClass().getName()));
                    } catch (NullPointerException e) {
                        Log.v(TAG, e.getMessage());
                    }
                }

                this.getTwitterSystemAccount(this.requestedTwitterAccountName, callbackContext);
            } else if (resultCode == Activity.RESULT_CANCELED) {
                callbackContext.error("Twitter auth activity canceled");
            }
        }
    }

    public void canUseTwitterSystemAccount(final CallbackContext callbackContext) {

        cordova.getThreadPool().execute(new Runnable() {
            public void run() {

                PluginResult pluginResult;

                Account[] twitterAccounts = accountManager.getAccountsByType("com.twitter.android.auth.login");

                // Twitter doesn't allow to get user's tokens from native account which signed by custom app
                // therefore the method returns false

                //pluginResult = new PluginResult(PluginResult.Status.OK, (twitterAccounts.length > 0));

                pluginResult = new PluginResult(PluginResult.Status.OK, false);
                pluginResult.setKeepCallback(true);
                callbackContext.sendPluginResult(pluginResult);
            }
        });
    }

    public void getTwitterSystemAccounts(final CallbackContext callbackContext) {
        cordova.getThreadPool().execute(new Runnable() {
            public void run() {

                PluginResult pluginResult;
                JSONObject json = new JSONObject();
                JSONArray accounts = new JSONArray();

                Account[] twitterAccounts = accountManager.getAccountsByType("com.twitter.android.auth.login");

                try {
                    if (twitterAccounts.length > 0) {
                        json.put("granted", true);

                        for (int i = 0; i < twitterAccounts.length; i++) {
                            JSONObject account = new JSONObject();

                            account.put("userName", twitterAccounts[i].name);

                            accounts.put(account);

                            json.put("accounts", accounts);
                        }

                        pluginResult = new PluginResult(PluginResult.Status.OK, json);
                    } else {
                        json.put("code", "0");
                        json.put("message", "no have twitter accounts");

                        pluginResult = new PluginResult(PluginResult.Status.ERROR, json);
                    }
                } catch (JSONException e) {
                    pluginResult = new PluginResult(PluginResult.Status.ERROR, e.getLocalizedMessage());
                }

                pluginResult.setKeepCallback(true);
                callbackContext.sendPluginResult(pluginResult);
            }
        });
    }

    public void getTwitterSystemAccount(final String networkUserName, final CallbackContext callbackContext) {
        cordova.getThreadPool().execute(new Runnable() {
            public void run() {

                PluginResult pluginResult;
                final JSONObject json = new JSONObject();
                final JSONObject account = new JSONObject();

                final Account[] twitterAccounts = accountManager
                        .getAccountsByType("com.twitter.android.auth.login");

                try {
                    if (twitterAccounts.length > 0) {
                        json.put("granted", true);

                        for (int i = 0; i < twitterAccounts.length; i++) {
                            if (twitterAccounts[i].name.equals(networkUserName)) {
                                account.put("userName", twitterAccounts[i].name);

                                final Account twitterAccount = twitterAccounts[i];

                                accountManager.getAuthToken(twitterAccount, "com.twitter.android.oauth.token", null,
                                        false, new AccountManagerCallback<Bundle>() {
                                            @Override
                                            public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
                                                try {
                                                    Bundle bundle = accountManagerFuture.getResult();

                                                    if (bundle.containsKey(AccountManager.KEY_INTENT)) {
                                                        Intent intent = bundle
                                                                .getParcelable(AccountManager.KEY_INTENT);

                                                        //clear the new task flag just in case, since a result is expected
                                                        int flags = intent.getFlags();
                                                        flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK;
                                                        intent.setFlags(flags);

                                                        requestedTwitterAccountName = networkUserName;

                                                        cordova.getActivity().startActivityForResult(intent,
                                                                TWITTER_OAUTH_REQUEST);
                                                    } else {
                                                        account.put("oauth_token",
                                                                bundle.getString(AccountManager.KEY_AUTHTOKEN));

                                                        accountManager.getAuthToken(twitterAccount,
                                                                "com.twitter.android.oauth.token.secret", null,
                                                                false, new AccountManagerCallback<Bundle>() {
                                                                    @Override
                                                                    public void run(
                                                                            AccountManagerFuture<Bundle> accountManagerFuture) {
                                                                        try {
                                                                            Bundle bundle = accountManagerFuture
                                                                                    .getResult();

                                                                            if (bundle.containsKey(
                                                                                    AccountManager.KEY_INTENT)) {
                                                                                Intent intent = bundle
                                                                                        .getParcelable(
                                                                                                AccountManager.KEY_INTENT);

                                                                                //clear the new task flag just in case, since a result is expected
                                                                                int flags = intent.getFlags();
                                                                                flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK;
                                                                                intent.setFlags(flags);

                                                                                requestedTwitterAccountName = networkUserName;

                                                                                cordova.getActivity()
                                                                                        .startActivityForResult(
                                                                                                intent,
                                                                                                TWITTER_OAUTH_REQUEST);
                                                                            } else {
                                                                                account.put("oauth_token_secret",
                                                                                        bundle.getString(
                                                                                                AccountManager.KEY_AUTHTOKEN));

                                                                                json.put("data", account);

                                                                                Log.v(TAG, "Account data: "
                                                                                        + json.toString());

                                                                                PluginResult pluginResult = new PluginResult(
                                                                                        PluginResult.Status.OK,
                                                                                        json);
                                                                                pluginResult.setKeepCallback(true);
                                                                                callbackContext.sendPluginResult(
                                                                                        pluginResult);
                                                                            }

                                                                        } catch (Exception e) {
                                                                            PluginResult pluginResult = new PluginResult(
                                                                                    PluginResult.Status.ERROR,
                                                                                    e.getLocalizedMessage());
                                                                            pluginResult.setKeepCallback(true);
                                                                            callbackContext
                                                                                    .sendPluginResult(pluginResult);
                                                                        }
                                                                    }
                                                                }, null);
                                                    }

                                                } catch (Exception e) {
                                                    PluginResult pluginResult = new PluginResult(
                                                            PluginResult.Status.ERROR, e.getLocalizedMessage());
                                                    pluginResult.setKeepCallback(true);
                                                    callbackContext.sendPluginResult(pluginResult);
                                                }
                                            }
                                        }, null);
                            }
                        }
                    } else {
                        json.put("code", "0");
                        json.put("message", "no have twitter accounts");

                        pluginResult = new PluginResult(PluginResult.Status.ERROR, json);
                        pluginResult.setKeepCallback(true);
                        callbackContext.sendPluginResult(pluginResult);
                    }
                } catch (JSONException e) {
                    pluginResult = new PluginResult(PluginResult.Status.ERROR, e.getLocalizedMessage());
                    pluginResult.setKeepCallback(true);
                    callbackContext.sendPluginResult(pluginResult);
                }
            }
        });
    }
}