package beyondsoft.bewomitarbeiterapp; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.EditorInfo; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.android.volley.RequestQueue; import com.android.volley.toolbox.Volley; import com.octo.android.robospice.SpiceManager; import com.octo.android.robospice.UncachedSpiceService; import com.octo.android.robospice.persistence.exception.SpiceException; import com.octo.android.robospice.request.listener.RequestListener; import org.ksoap2.serialization.PropertyInfo; import org.ksoap2.serialization.SoapPrimitive; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import javax.crypto.NoSuchPaddingException; import Database.DatabaseHandler; import soapConnection.ApplicationUser; import soapConnection.JsonSoapPrimitiveRequest; import soapConnection.SoapCalls; import soapConnection.SoapConnectionManager; import tcpConnection.LoginCallback; import tcpConnection.SocketManager; import util.SecurityUtils; import util.Util; /** * Created by bib on 02.05.2016. */ public class LoginActivity extends ActionBarActivity { private CheckBox mRememberMeCheckBoxView; private EditText mChatCodeView; private EditText mTenantView; private EditText mUsernameView; private EditText mPasswordView; private View mProgressView; private View mLoginFormView; private SpiceManager spiceManager = new SpiceManager(UncachedSpiceService.class); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); mChatCodeView = (EditText) findViewById(R.id.token); mTenantView = (EditText) findViewById(R.id.tenant); mUsernameView = (EditText) findViewById(R.id.username); mPasswordView = (EditText) findViewById(R.id.password); mRememberMeCheckBoxView = (CheckBox) findViewById(R.id.remember_me_checkbox); mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { if (id == R.id.login || id == EditorInfo.IME_NULL) { attemptLogin(); return true; } return false; } }); Button mSignInButton = (Button) findViewById(R.id.sign_in_button); mSignInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { attemptLogin(); } }); mLoginFormView = findViewById(R.id.login_form); mProgressView = findViewById(R.id.login_progress); SharedPreferences settings = getSharedPreferences(Util.PREFS_NAME, 0); String savedToken = settings.getString(Util.PREFS_TOKEN_KEY, null); String savedTenant = settings.getString(Util.PREFS_TENANT_KEY, null); String savedUsername = settings.getString(Util.PREFS_USERNAME_KEY, null); String savedPassword = settings.getString(Util.PREFS_PASSWORD, null); if(savedTenant != null && savedToken != null && savedUsername != null && savedPassword != null) { mRememberMeCheckBoxView.setChecked(true); byte[] tokenByteArray = Base64.decode(savedToken, Base64.DEFAULT); ByteArrayInputStream tokenStream = new ByteArrayInputStream(tokenByteArray); byte[] tenantByteArray = Base64.decode(savedTenant, Base64.DEFAULT); ByteArrayInputStream tenantStream = new ByteArrayInputStream(tenantByteArray); byte[] usernameByteArray = Base64.decode(savedUsername, Base64.DEFAULT); ByteArrayInputStream usernameStream = new ByteArrayInputStream(usernameByteArray); byte[] passwordByteArray = Base64.decode(savedPassword, Base64.DEFAULT); ByteArrayInputStream passwordStream = new ByteArrayInputStream(passwordByteArray); try { mChatCodeView.setText(SecurityUtils.decrypt(tokenStream).toString()); mTenantView.setText(SecurityUtils.decrypt(tenantStream).toString()); mUsernameView.setText(SecurityUtils.decrypt(usernameStream).toString()); mPasswordView.setText(SecurityUtils.decrypt(passwordStream).toString()); } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | InvalidKeyException e) { e.printStackTrace(); } } } @Override protected void onStart() { super.onStart(); spiceManager.start(this); } @Override protected void onStop() { spiceManager.shouldStop(); super.onStop(); } private void attemptLogin() { mTenantView.setError(null); mChatCodeView.setError(null); mUsernameView.setError(null); mPasswordView.setError(null); final String username = mUsernameView.getText().toString(); final String password = mPasswordView.getText().toString(); final String tenant = mTenantView.getText().toString(); String token = mChatCodeView.getText().toString(); boolean cancel = false; View focusView = null; if (TextUtils.isEmpty(password)) { mPasswordView.setError(getString(R.string.error_invalid_input)); focusView = mPasswordView; cancel = true; } if (TextUtils.isEmpty(username)) { mUsernameView.setError(getString(R.string.error_invalid_input)); focusView = mUsernameView; cancel = true; } if(TextUtils.isEmpty(tenant)) { mTenantView.setError(getString(R.string.error_invalid_input)); focusView = mTenantView; cancel = true; } if(TextUtils.isEmpty(token)) { mChatCodeView.setError(getString(R.string.error_invalid_input)); focusView = mChatCodeView; cancel = true; } if (cancel) { focusView.requestFocus(); } else { showProgress(true); RequestQueue queue = Volley.newRequestQueue(LoginActivity.this); String url = SoapCalls.TOKEN_CHECK_URL + token; // StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() { // @Override // public void onResponse(String response) { // if(response == null || TextUtils.isEmpty(response)) { // showProgress(false); // // clearSharedPreferences(); // // mPasswordView.setError(getString(R.string.error_invalid_input)); // mUsernameView.setError(getString(R.string.error_invalid_input)); // mChatCodeView.setError(getString(R.string.error_invalid_input)); // mTenantView.setError(getString(R.string.error_invalid_input)); // // return; // } ArrayList propertyInfos = new ArrayList<>(); propertyInfos.add(SoapConnectionManager.BuildProperty("pTenant", tenant, String.class)); propertyInfos.add(SoapConnectionManager.BuildProperty("pUsername", username, String.class)); propertyInfos.add(SoapConnectionManager.BuildProperty("pPassword", password, String.class)); JsonSoapPrimitiveRequest request = new JsonSoapPrimitiveRequest(SoapCalls.LOGIN_CALL, propertyInfos); spiceManager.execute(request, new JsonSoapPrimitiveRequestListener()); // } // }, new Response.ErrorListener() { // @Override // public void onErrorResponse(VolleyError error) { // showProgress(false); // Log.e("Error sending request", (error == null ? "error is null" : error.getMessage())); // } // }); // queue.add(stringRequest); } } public void rememberMeOnClick(View view) { CheckBox rememberMeCheckBox = (CheckBox) view; if(!rememberMeCheckBox.isChecked()) { clearSharedPreferences(); } } private final class JsonSoapPrimitiveRequestListener implements RequestListener { @Override public void onRequestFailure(SpiceException spiceException) { showProgress(false); Log.e("Error", spiceException.getMessage()); } @Override public void onRequestSuccess(SoapPrimitive soapPrimitive) { if(soapPrimitive == null) { showProgress(false); showLoginUIErrors(true, true, true, true); Toast.makeText(LoginActivity.this, "Login nicht möglich", Toast.LENGTH_SHORT).show(); return; } String abc = soapPrimitive.toString(); if(abc != null) { Log.i("LOGIN", abc); if(abc.contains(";")) { String[] blubb = abc.split(";"); SoapConnectionManager.User = new ApplicationUser(blubb[1], blubb[2], Long.valueOf(blubb[0]), Long.valueOf(blubb[3])); DatabaseHandler databaseHandler = DatabaseHandler.getInstance(getApplicationContext()); int owner = databaseHandler.getOwnerOid(); if(owner == 0) { databaseHandler.insertOwnerOid(SoapConnectionManager.User.getPersonOid().intValue()); } else if(owner != SoapConnectionManager.User.getPersonOid().intValue()) { databaseHandler.clearDatabase(); databaseHandler.insertOwnerOid(SoapConnectionManager.User.getPersonOid().intValue()); } SoapConnectionManager.User.setTenant(mTenantView.getText().toString()); if(mRememberMeCheckBoxView.isChecked()) { ByteArrayOutputStream tokenOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream tenantOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream usernameOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream passwordOutputStream = new ByteArrayOutputStream(); try { SecurityUtils.encrypt(mChatCodeView.getText().toString(), tokenOutputStream); SecurityUtils.encrypt(mTenantView.getText().toString(), tenantOutputStream); SecurityUtils.encrypt(mUsernameView.getText().toString(), usernameOutputStream); SecurityUtils.encrypt(mPasswordView.getText().toString(), passwordOutputStream); SharedPreferences settings = getSharedPreferences(Util.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putString(Util.PREFS_TOKEN_KEY, Base64.encodeToString(tokenOutputStream.toByteArray(), Base64.DEFAULT)); editor.putString(Util.PREFS_TENANT_KEY, Base64.encodeToString(tenantOutputStream.toByteArray(), Base64.DEFAULT)); editor.putString(Util.PREFS_USERNAME_KEY, Base64.encodeToString(usernameOutputStream.toByteArray(), Base64.DEFAULT)); editor.putString(Util.PREFS_PASSWORD, Base64.encodeToString(passwordOutputStream.toByteArray(), Base64.DEFAULT)); editor.apply(); } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | InvalidKeyException e) { e.printStackTrace(); } } SocketManager.tenant = mTenantView.getText().toString(); SocketManager.loginCallback = new LoginCallback() { @Override public void doCallback() { Log.e("LOGIN_CALLBACK", "LoginCallback aufgerufen. Ist verbunden und ruft die ChatActivity nun auf."); Intent kontaktChatActivity = new Intent(LoginActivity.this, KontaktChatActivity.class); LoginActivity.this.startActivity(kontaktChatActivity); } }; SocketManager.connectToServer(); } else { showProgress(false); switch(abc) { case "WrongTenant": showLoginUIErrors(false, true, false, false); break; case "WrongCredentials": showLoginUIErrors(false, false, true, true); break; case "Unauthorized": Toast.makeText(getApplicationContext(), "Sie sind nicht zum Chatten autorisiert. Bitte wenden Sie sich an Ihren Administrator.", Toast.LENGTH_LONG).show(); break; default: Toast.makeText(getApplicationContext(), "Ein unbekannter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.", Toast.LENGTH_LONG).show(); break; } } } else { showProgress(false); showLoginUIErrors(true, true, true, true); } } } private void showLoginUIErrors(boolean token, boolean tenant, boolean username, boolean password) { mChatCodeView.setError(token ? getString(R.string.error_invalid_input) : null); mTenantView.setError(tenant ? getString(R.string.error_invalid_input) : null); mUsernameView.setError(username ? getString(R.string.error_invalid_input) : null); mPasswordView.setError(password ? getString(R.string.error_invalid_input) : null); } private void clearSharedPreferences() { SharedPreferences settings = getSharedPreferences(Util.PREFS_NAME, 0); settings.edit().clear().commit(); } @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) private void showProgress(final boolean show) { // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow // for very easy animations. If available, use these APIs to fade-in // the progress spinner. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); mLoginFormView.animate().setDuration(shortAnimTime).alpha( show ? 0 : 1).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); } }); mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); mProgressView.animate().setDuration(shortAnimTime).alpha( show ? 1 : 0).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); } }); } else { // The ViewPropertyAnimator APIs are not available, so simply show // and hide the relevant UI components. mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); } } }