package net.hockeyapp.android.tasks;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import net.hockeyapp.android.Constants;
import net.hockeyapp.android.LoginManager;
import net.hockeyapp.android.utils.HttpURLConnectionBuilder;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.util.Map;
/**
* <h3>Description</h3>
*
* Perform the authentication process.
*
**/
public class LoginTask extends ConnectionTask<Void, Void, Boolean> {
/**
* Key for login success in the returend bundle
*/
public static final String BUNDLE_SUCCESS = "success";
private final int mMode;
private final String mUrlString;
private final Map<String, String> mParams;
private Context mContext;
private Handler mHandler;
private ProgressDialog mProgressDialog;
private boolean mShowProgressDialog;
/**
* Send feedback {@link AsyncTask}.
* If the class is intended to send a simple feedback message, the a POST is made with the specific data
* If the class is intended to fetch the messages by providing a token, a GET is made
*
* @param context {@link Context} object
* @param handler Handler object to send data back to the activity
* @param urlString URL for Identity Check
* @param mode LoginManager.LOGIN_MODE_ANONYMOUS, LoginManager.LOGIN_MODE_EMAIL_ONLY,
* LoginManager.LOGIN_MODE_EMAIL_PASSWORD, or LoginManager.LOGIN_MODE_VALIDATE
* @param params a map for all key value params.
*/
public LoginTask(Context context, Handler handler, String urlString, int mode, Map<String, String> params) {
this.mContext = context;
this.mHandler = handler;
this.mUrlString = urlString;
this.mMode = mode;
this.mParams = params;
this.mShowProgressDialog = true;
if (context != null) {
Constants.loadFromContext(context);
}
}
public void setShowProgressDialog(boolean showProgressDialog) {
this.mShowProgressDialog = showProgressDialog;
}
public void attach(Context context, Handler handler) {
this.mContext = context;
this.mHandler = handler;
}
public void detach() {
mContext = null;
mHandler = null;
mProgressDialog = null;
}
@Override
protected void onPreExecute() {
if ((mProgressDialog == null || !mProgressDialog.isShowing()) && mShowProgressDialog) {
mProgressDialog = ProgressDialog.show(mContext, "", "Please wait...", true, false);
}
}
@Override
protected Boolean doInBackground(Void... args) {
HttpURLConnection connection = null;
try {
connection = makeRequest(mMode, mParams);
connection.connect();
if (connection.getResponseCode() == 200) {
String responseStr = getStringFromConnection(connection);
if (!TextUtils.isEmpty(responseStr)) {
return handleResponse(responseStr);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
return false;
}
@Override
protected void onPostExecute(Boolean success) {
if (mProgressDialog != null) {
try {
mProgressDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
/** If the Handler object is not NULL, send a message to the Activity with the result */
if (mHandler != null) {
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putBoolean(BUNDLE_SUCCESS, success);
msg.setData(bundle);
mHandler.sendMessage(msg);
}
}
private HttpURLConnection makeRequest(int mode, Map<String, String> params) throws IOException {
if (mode == LoginManager.LOGIN_MODE_EMAIL_ONLY) {
return new HttpURLConnectionBuilder(mUrlString)
.setRequestMethod("POST")
.writeFormFields(params)
.build();
} else if (mode == LoginManager.LOGIN_MODE_EMAIL_PASSWORD) {
return new HttpURLConnectionBuilder(mUrlString)
.setRequestMethod("POST")
.setBasicAuthorization(params.get("email"), params.get("password"))
.build();
} else if (mode == LoginManager.LOGIN_MODE_VALIDATE) {
String type = params.get("type");
String id = params.get("id");
String paramUrl = mUrlString + "?" + type + "=" + id;
return new HttpURLConnectionBuilder(paramUrl)
.build();
} else {
throw new IllegalArgumentException("Login mode " + mode + " not supported.");
}
}
private boolean handleResponse(String responseStr) {
SharedPreferences prefs = mContext.getSharedPreferences("net.hockeyapp.android.login", 0);
try {
JSONObject response = new JSONObject(responseStr);
String status = response.getString("status");
if (TextUtils.isEmpty(status)) {
return false;
}
if (mMode == LoginManager.LOGIN_MODE_EMAIL_ONLY) {
if (status.equals("identified")) {
String iuid = response.getString("iuid");
if (!TextUtils.isEmpty(iuid)) {
prefs.edit()
.putString("iuid", iuid)
.putString("email", mParams.get("email"))
.apply();
return true;
}
}
} else if (mMode == LoginManager.LOGIN_MODE_EMAIL_PASSWORD) {
if (status.equals("authorized")) {
String auid = response.getString("auid");
if (!TextUtils.isEmpty(auid)) {
prefs.edit()
.putString("auid", auid)
.putString("email", mParams.get("email"))
.apply();
return true;
}
}
} else if (mMode == LoginManager.LOGIN_MODE_VALIDATE) {
if (status.equals("validated")) {
return true;
} else {
prefs.edit()
.remove("iuid")
.remove("auid")
.remove("email")
.apply();
}
} else {
throw new IllegalArgumentException("Login mode " + mMode + " not supported.");
}
return false;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
}