package com.odoo.core.account;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.odoo.OdooActivity;
import com.odoo.R;
import com.odoo.base.addons.res.ResCompany;
import com.odoo.core.auth.OdooAccountManager;
import com.odoo.core.auth.OdooAuthenticator;
import com.odoo.core.orm.ODataRow;
import com.odoo.core.support.OUser;
import com.odoo.core.support.OdooInstancesSelectorDialog;
import com.odoo.core.support.OdooLoginHelper;
import com.odoo.core.support.OdooServerTester;
import com.odoo.core.support.OdooUserLoginSelectorDialog;
import com.odoo.core.utils.IntentUtils;
import com.odoo.core.utils.OAlertDialog;
import com.odoo.core.utils.OResource;
import com.odoo.datas.OConstants;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLPeerUnverifiedException;
import odoo.OdooAccountExpireException;
import odoo.OdooInstance;
public class OdooLogin extends ActionBarActivity implements View.OnClickListener, View.OnFocusChangeListener, OdooInstancesSelectorDialog.OnInstanceSelectListener, OdooUserLoginSelectorDialog.IUserLoginSelectListener {
private EditText edtUsername, edtPassword, edtSelfHosted;
private Boolean mCreateAccountRequest = false;
private Boolean mSelfHostedURL = false;
private Boolean mForceConnect = false;
private Boolean mConnectedToServer = false;
private Boolean mAutoLogin = false;
private Boolean mRequestedForAccount = false;
private OdooURLTester odooURLTester = null;
private LoginProcess loginProcess = null;
private AccountCreater accountCreator = null;
private OdooServerTester mServerTester = null;
private InstanceGetter instanceGetter = null;
private OdooLoginHelper loginHelper = null;
private Spinner databaseSpinner = null;
private List<String> databases = new ArrayList<String>();
private TextView mLoginProcessStatus = null;
private TextView mTermsCondition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_login);
Bundle extras = getIntent().getExtras();
if (extras != null) {
if (extras.containsKey(OdooAuthenticator.KEY_NEW_ACCOUNT_REQUEST))
mCreateAccountRequest = true;
if (extras.containsKey(OdooActivity.KEY_ACCOUNT_REQUEST)) {
mRequestedForAccount = true;
setResult(RESULT_CANCELED);
}
}
if (!mCreateAccountRequest) {
if (OdooAccountManager.anyActiveUser(this)) {
startOdooActivity();
return;
} else if (OdooAccountManager.hasAnyAccount(this)) {
onRequestAccountSelect();
}
}
init();
}
private void init() {
loginHelper = new OdooLoginHelper(this);
mServerTester = new OdooServerTester(this);
mLoginProcessStatus = (TextView) findViewById(R.id.login_process_status);
mTermsCondition = (TextView) findViewById(R.id.termsCondition);
mTermsCondition.setMovementMethod(LinkMovementMethod.getInstance());
findViewById(R.id.btnLogin).setOnClickListener(this);
findViewById(R.id.forgot_password).setOnClickListener(this);
findViewById(R.id.create_account).setOnClickListener(this);
findViewById(R.id.txvAddSelfHosted).setOnClickListener(this);
edtSelfHosted = (EditText) findViewById(R.id.edtSelfHostedURL);
}
private void startOdooActivity() {
startActivity(new Intent(this, OdooActivity.class));
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_base_login, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.txvAddSelfHosted:
toggleSelfHostedURL();
break;
case R.id.btnLogin:
loginUser();
break;
case R.id.forgot_password:
IntentUtils.openURLInBrowser(this, OConstants.URL_ODOO_RESET_PASSWORD);
break;
case R.id.create_account:
IntentUtils.openURLInBrowser(this, OConstants.URL_ODOO_SIGN_UP);
break;
}
}
private void toggleSelfHostedURL() {
TextView txvAddSelfHosted = (TextView) findViewById(R.id.txvAddSelfHosted);
if (!mSelfHostedURL) {
mSelfHostedURL = true;
findViewById(R.id.layoutSelfHosted).setVisibility(View.VISIBLE);
edtSelfHosted.setOnFocusChangeListener(this);
edtSelfHosted.requestFocus();
txvAddSelfHosted.setText(R.string.label_login_with_odoo);
} else {
findViewById(R.id.layoutBorderDB).setVisibility(View.GONE);
findViewById(R.id.layoutDatabase).setVisibility(View.GONE);
findViewById(R.id.layoutSelfHosted).setVisibility(View.GONE);
mSelfHostedURL = false;
txvAddSelfHosted.setText(R.string.label_add_self_hosted_url);
edtSelfHosted.setText("");
}
}
@Override
public void onFocusChange(final View v, final boolean hasFocus) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (odooURLTester != null) {
odooURLTester.cancel(true);
}
if (mSelfHostedURL && v.getId() == R.id.edtSelfHostedURL && !hasFocus) {
if (!TextUtils.isEmpty(edtSelfHosted.getText())
&& validateURL(edtSelfHosted.getText().toString())) {
String test_url = createServerURL(edtSelfHosted.getText().toString());
odooURLTester = new OdooURLTester();
odooURLTester.execute(test_url);
}
}
}
}, 500);
}
private boolean validateURL(String url) {
return (url.contains("."));
}
private String createServerURL(String server_url) {
StringBuilder serverURL = new StringBuilder();
if (!server_url.contains("http://") && !server_url.contains("https://")) {
serverURL.append("http://");
}
serverURL.append(server_url);
return serverURL.toString();
}
private void showForceConnectDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.title_ssl_warning);
builder.setMessage(R.string.untrusted_ssl_warning);
builder.setPositiveButton(R.string.label_process_anyway,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (odooURLTester != null) {
odooURLTester.cancel(true);
odooURLTester = null;
}
mForceConnect = true;
odooURLTester = new OdooURLTester();
odooURLTester.execute(createServerURL(edtSelfHosted.getText().toString()));
}
});
builder.setNegativeButton(R.string.label_cancel, null);
builder.show();
}
// User Login
private void loginUser() {
String serverURL = createServerURL((mSelfHostedURL) ? edtSelfHosted.getText().toString() : OConstants.URL_ODOO_ACCOUNTS);
String databaseName = null;
edtUsername = (EditText) findViewById(R.id.edtUserName);
edtPassword = (EditText) findViewById(R.id.edtPassword);
if (mSelfHostedURL) {
edtSelfHosted.setError(null);
if (TextUtils.isEmpty(edtSelfHosted.getText())) {
edtSelfHosted.setError(OResource.string(this, R.string.error_provide_server_url));
edtSelfHosted.requestFocus();
return;
}
if (databaseSpinner != null && databases.size() > 1 && databaseSpinner.getSelectedItemPosition() == 0) {
Toast.makeText(this, OResource.string(this, R.string.label_select_database), Toast.LENGTH_LONG).show();
return;
}
}
edtUsername.setError(null);
edtPassword.setError(null);
if (TextUtils.isEmpty(edtUsername.getText())) {
edtUsername.setError(OResource.string(this, R.string.error_provide_username));
edtUsername.requestFocus();
return;
}
if (TextUtils.isEmpty(edtPassword.getText())) {
edtPassword.setError(OResource.string(this, R.string.error_provide_password));
edtPassword.requestFocus();
return;
}
if (mConnectedToServer) {
databaseName = databases.get(0);
if (databaseSpinner != null) {
databaseName = databases.get(databaseSpinner.getSelectedItemPosition());
}
mAutoLogin = false;
if (loginProcess != null) {
loginProcess.cancel(true);
}
loginProcess = new LoginProcess();
loginProcess.execute(databaseName, serverURL);
} else {
if (odooURLTester != null)
odooURLTester.cancel(true);
mAutoLogin = true;
odooURLTester = new OdooURLTester();
odooURLTester.execute(serverURL);
}
}
private void showDatabases() {
if (databases.size() > 1) {
findViewById(R.id.layoutBorderDB).setVisibility(View.VISIBLE);
findViewById(R.id.layoutDatabase).setVisibility(View.VISIBLE);
databaseSpinner = (Spinner) findViewById(R.id.spinnerDatabaseList);
databases.add(0, OResource.string(this, R.string.label_select_database));
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, databases);
databaseSpinner.setAdapter(adapter);
} else {
databaseSpinner = null;
findViewById(R.id.layoutBorderDB).setVisibility(View.GONE);
findViewById(R.id.layoutDatabase).setVisibility(View.GONE);
}
}
@Override
public void instanceSelected(OdooInstance instance, OUser user) {
OUser userData = user;
if (!instance.getInstanceUrl().equals(OConstants.URL_ODOO)) {
if (loginProcess != null)
loginProcess.cancel(true);
loginProcess = new LoginProcess(instance, user);
loginProcess.execute();
return;
}
accountCreator = new AccountCreater();
accountCreator.execute(userData);
}
@Override
public void canceledInstanceSelect() {
findViewById(R.id.controls).setVisibility(View.VISIBLE);
findViewById(R.id.login_progress).setVisibility(View.GONE);
}
@Override
public void onUserSelected(OUser user) {
OdooAccountManager.login(this, user.getAndroidName());
startOdooActivity();
}
@Override
public void onRequestAccountSelect() {
OdooUserLoginSelectorDialog dialog = new OdooUserLoginSelectorDialog(this);
dialog.setUserLoginSelectListener(this);
dialog.show();
}
@Override
public void onNewAccountRequest() {
init();
}
@Override
public void onCancelSelect() {
}
private class LoginProcess extends AsyncTask<String, Void, OUser> {
private OdooInstance mInstance;
private OUser mUser;
private String mExpireMessage = null;
public LoginProcess() {
}
public LoginProcess(OdooInstance instance, OUser user) {
mInstance = instance;
mUser = user;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
findViewById(R.id.controls).setVisibility(View.GONE);
findViewById(R.id.login_progress).setVisibility(View.VISIBLE);
if (mInstance != null && mUser != null)
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_logging_in_with_instance));
else
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_logging_in));
}
@Override
protected OUser doInBackground(String... params) {
try {
if (mInstance == null && mUser == null) {
String username = edtUsername.getText().toString();
String password = edtPassword.getText().toString();
return loginHelper.login(username, password, params[0], params[1], mForceConnect);
} else {
mSelfHostedURL = true;
return loginHelper.instanceLogin(mInstance, mUser);
}
} catch (OdooAccountExpireException expired) {
mExpireMessage = expired.getMessage();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(OUser user) {
super.onPostExecute(user);
edtUsername.setError(null);
if (user == null) {
findViewById(R.id.controls).setVisibility(View.VISIBLE);
findViewById(R.id.login_progress).setVisibility(View.GONE);
if (mExpireMessage != null) {
mSelfHostedURL = false;
OAlertDialog dialog = new OAlertDialog(OdooLogin.this);
dialog.setTitle(OResource.string(OdooLogin.this, R.string.title_instance_expired));
dialog.setMessage(mExpireMessage);
dialog.show();
} else {
edtUsername.setError(OResource.string(OdooLogin.this, R.string.error_invalid_username_or_password));
}
} else {
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_login_success));
if (!mSelfHostedURL) {
instanceGetter = new InstanceGetter();
instanceGetter.execute(user);
} else {
accountCreator = new AccountCreater();
accountCreator.execute(user);
}
}
}
}
private class InstanceGetter extends AsyncTask<OUser, Void, List<OdooInstance>> {
private OUser mUser;
@Override
protected void onPreExecute() {
super.onPreExecute();
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_getting_instances));
}
@Override
protected List<OdooInstance> doInBackground(OUser... params) {
mUser = params[0];
return loginHelper.getOdooInstances(mUser);
}
@Override
protected void onPostExecute(List<OdooInstance> odooInstances) {
super.onPostExecute(odooInstances);
if (odooInstances.size() > 1) {
OdooInstancesSelectorDialog instancesSelectorDialog = new OdooInstancesSelectorDialog(OdooLogin.this, mUser);
instancesSelectorDialog.setInstances(odooInstances);
instancesSelectorDialog.setOnInstanceSelectListener(OdooLogin.this);
instancesSelectorDialog.showDialog();
} else {
// Login to default odoo instance (www.odoo.com)
accountCreator = new AccountCreater();
accountCreator.execute(mUser);
}
}
}
private class AccountCreater extends AsyncTask<OUser, Void, Boolean> {
private OUser mUser;
@Override
protected void onPreExecute() {
super.onPreExecute();
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_creating_account));
}
@Override
protected Boolean doInBackground(OUser... params) {
mUser = params[0];
if (OdooAccountManager.createAccount(OdooLogin.this, params[0])) {
mUser = OdooAccountManager.getDetails(OdooLogin.this, mUser.getAndroidName());
try {
// Syncing company details
ODataRow company_details = new ODataRow();
company_details.put("id", mUser.getCompany_id());
ResCompany company = new ResCompany(OdooLogin.this, mUser);
company.quickCreateRecord(company_details);
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
return false;
}
@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_redirecting));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!mRequestedForAccount)
startOdooActivity();
else {
Intent intent = new Intent();
intent.putExtra(OdooActivity.KEY_NEW_USER_NAME, mUser.getAndroidName());
setResult(RESULT_OK, intent);
finish();
}
}
}, 1500);
}
}
private class OdooURLTester extends AsyncTask<String, Void, Boolean> {
private Boolean mRequiredForceConnect = false;
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.v("OdooURLTester", "Connecting to Server");
edtSelfHosted.setError(null);
if (mAutoLogin) {
findViewById(R.id.controls).setVisibility(View.GONE);
findViewById(R.id.login_progress).setVisibility(View.VISIBLE);
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_connecting_to_server));
}
findViewById(R.id.imgValidURL).setVisibility(View.GONE);
findViewById(R.id.serverURLCheckProgress).setVisibility(View.VISIBLE);
findViewById(R.id.layoutBorderDB).setVisibility(View.GONE);
findViewById(R.id.layoutDatabase).setVisibility(View.GONE);
}
@Override
protected Boolean doInBackground(String... params) {
try {
return mServerTester.testConnection(params[0], mForceConnect);
} catch (SSLPeerUnverifiedException peer) {
mRequiredForceConnect = true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
findViewById(R.id.serverURLCheckProgress).setVisibility(View.GONE);
edtSelfHosted.setError(null);
if (success) {
// Connected to server
Log.v("OdooURLTester", "Connected to server.");
mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_connected_to_server));
databases.clear();
databases.addAll(mServerTester.getDatabases());
showDatabases();
mConnectedToServer = true;
findViewById(R.id.imgValidURL).setVisibility(View.VISIBLE);
if (mAutoLogin) {
loginUser();
}
} else if (mRequiredForceConnect) {
showForceConnectDialog();
} else {
edtSelfHosted.setError(OResource.string(OdooLogin.this, R.string.error_invalid_odoo_url));
edtSelfHosted.requestFocus();
}
}
}
}