Login Improved; Still Bug when re-login

This commit is contained in:
Caesar2011
2018-12-19 01:08:39 +01:00
parent fd18e4b61a
commit 4d22613672
7 changed files with 137 additions and 271 deletions

View File

@@ -69,8 +69,6 @@ public class MainActivity extends AppCompatActivity
private static final int FRAGMENT_STARTUP = 0;
private static final int FRAGMENT_MODULES = 1;
private static final int FRAGMENT_MODULES_DETAILS = 2;
@Deprecated
private static final int FRAGMENT_LOGIN = 3;
private static final int FRAGMENT_SCHEDULE = 4;
private static final int FRAGMENT_CANTEENS = 5;
private static final int FRAGMENT_CANTEENS_DETAILS = 6;
@@ -129,7 +127,7 @@ public class MainActivity extends AppCompatActivity
if (!mAccountManager.hasAccounts(AccountGeneral.ACCOUNT_TYPE)) {
desiredPage = getDefaultFragmentAfterLogout();
desiredData = "";
mAccountManager.getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, null);
updateNavigation();
changeFragment(desiredPage, desiredData);
} else {
@@ -367,7 +365,7 @@ public class MainActivity extends AppCompatActivity
setRefreshFailedBanner(false);
updateNavigation();
changeFragment(getDefaultFragmentAfterLogout());
mAccountManager.getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, null);
}
private void toLoginState(String fullName, String email, int newFragment, boolean onlineMode) {
@@ -526,7 +524,7 @@ public class MainActivity extends AppCompatActivity
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
mAccountManager.getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, null);
});
}

View File

@@ -1,111 +0,0 @@
package de.sebse.fuplanner.fragments;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.MainActivityListener;
import de.sebse.fuplanner.tools.logging.Logger;
/**
* A simple {@link Fragment} subclass.
* Use the {@link LoginFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class LoginFragment extends Fragment {
private final Logger log = new Logger(this);
@Nullable private MainActivityListener mActivityListener;
public LoginFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @return A new instance of fragment LoginFragment.
*/
public static LoginFragment newInstance() {
LoginFragment fragment = new LoginFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_login, container, false);
//if (mActivityListener != null && mActivityListener.getKVV().account().isOfflineStoredAvailable()) {
// Button offline_btn = v.findViewById(R.id.btn_offline);
// offline_btn.setVisibility(View.VISIBLE);
// offline_btn.setText(v.getResources().getString(R.string.enter_offline_mode, mActivityListener.getKVV().modules().list().getUsername()));
//offline_btn.setOnClickListener(v1 -> mActivityListener.getKVV().account().doOfflineLogin());
//}
View btn_login = v.findViewById(R.id.btn_login);
btn_login.setOnClickListener(view -> {
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
R.style.FUTheme_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Authenticating...");
progressDialog.show();
EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
String username = input_usr.getText().toString();
String password = input_pwd.getText().toString();
mActivityListener.getKVV().account().doOnlineLogin(username, password, success -> {
progressDialog.dismiss();
mActivityListener.getGoogleAuth().setLoginState(username, password);
input_usr.setError(null);
input_pwd.setError(null);
}, error -> {
progressDialog.dismiss();
// Invalid password
if (mActivityListener != null) {
if (error.getCode() == 100131) {
mActivityListener.showToast(R.string.invalid_credentials);
input_usr.setError(input_usr.getResources().getString(R.string.invalid_credentials));
input_pwd.setError(input_pwd.getResources().getString(R.string.invalid_credentials));
} else {
mActivityListener.showToast(v.getResources().getString(R.string.error_occurred_code, error.getCode()));
}
}
log.e("Error on KVV login!", error);
});
});
return v;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MainActivityListener) {
mActivityListener = (MainActivityListener) context;
mActivityListener.onTitleTextChange(R.string.log_in);
} else
throw new RuntimeException(context.toString() + " must implement MainActivityListener");
}
@Override
public void onDetach() {
super.onDetach();
mActivityListener = null;
}
}

View File

@@ -55,6 +55,7 @@ public class Login extends HTTPService {
LoginToken.load(mListener.getAccountManager(), token -> {
boolean result = setToken(token, true);
mLoginPending = false;
log.d("loginToken", token != null ? token.toString() : null);
callback.run(result);
});
}
@@ -129,15 +130,18 @@ public class Login extends HTTPService {
if (!isFirst)
return;
CustomAccountManager manager = mListener.getAccountManager();
manager.invalidate(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
reset();
restoreOnlineLogin(isRestored -> {
if (isRestored)
testLoginToken(mRefreshCallbacks::responseResponse, mRefreshCallbacks::responseError);
else {
logout(true);
mRefreshCallbacks.responseError(new NetworkError(100180, 403, "Re-login failed!"));
}
manager.doInvalidateToken(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, ignored -> {
reset();
log.d("try restore", ignored);
restoreOnlineLogin(isRestored -> {
log.d("restore", isRestored, mToken);
if (isRestored)
testLoginToken(mRefreshCallbacks::responseResponse, mRefreshCallbacks::responseError);
else {
logout(true);
mRefreshCallbacks.responseError(new NetworkError(100180, 403, "Re-login failed!"));
}
});
});
/* mListener.getCredentials(credentials -> {
doOnlineLogin(credentials.getUsername(), credentials.getPassword(),

View File

@@ -17,18 +17,10 @@ import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import de.sebse.fuplanner.R;
@@ -51,7 +43,7 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mEmailView;
private EditText mEmailView;
EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
@@ -76,28 +68,20 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
setContentView(R.layout.activity_fu_authenticator);
// Set up the login form.
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
mEmailView = findViewById(R.id.input_username);
populateAutoComplete();
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
mPasswordView = findViewById(R.id.input_password);
mPasswordView.setOnEditorActionListener((textView, id, keyEvent) -> {
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
});
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
Button mEmailSignInButton = findViewById(R.id.btn_login);
mEmailSignInButton.setOnClickListener(view -> attemptLogin());
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
@@ -217,32 +201,25 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
// 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);
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);
}
});
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);
}
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);
}
});
}
@Override
@@ -264,14 +241,6 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> emails = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
emails.add(cursor.getString(ProfileQuery.ADDRESS));
cursor.moveToNext();
}
addEmailsToAutoComplete(emails);
}
@Override
@@ -279,15 +248,6 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
}
private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
ArrayAdapter<String> adapter =
new ArrayAdapter<>(FUAuthenticatorActivity.this,
android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
mEmailView.setAdapter(adapter);
}
private interface ProfileQuery {
String[] PROJECTION = {

View File

@@ -2,7 +2,6 @@ package de.sebse.fuplanner.tools;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.os.Build;
@@ -12,6 +11,7 @@ import java.io.IOException;
import androidx.annotation.Nullable;
import de.sebse.fuplanner.MainActivity;
import de.sebse.fuplanner.services.KVV.Login;
import de.sebse.fuplanner.tools.logging.Logger;
public class CustomAccountManager {
@@ -28,13 +28,10 @@ public class CustomAccountManager {
private void doInvalidateToken(String accountType, String authTokenType) {
//String token = mAccountManager.blockingGetAuthToken();
public void doInvalidateTokenSync(String accountType, String authTokenType) {
Account account = mAccountManager.getAccountsByType(accountType)[0];
String token = null;
try {
token = mAccountManager.blockingGetAuthToken(account, authTokenType, true);
//log.d("hihihi", accountType, authTokenType, token);
String token = mAccountManager.blockingGetAuthToken(account, authTokenType, true);
mAccountManager.invalidateAuthToken(accountType, token);
} catch (AuthenticatorException e) {
e.printStackTrace();
@@ -45,6 +42,28 @@ public class CustomAccountManager {
}
}
public void doInvalidateToken(String accountType, String authTokenType, Login.BooleanInterface callback) {
Account account = mAccountManager.getAccountsByType(accountType)[0];
mAccountManager.getAuthToken(account, authTokenType, null, true, accountManagerFuture -> {
try {
Bundle bnd = accountManagerFuture.getResult();
String token = bnd.getString(AccountManager.KEY_AUTHTOKEN);
mAccountManager.invalidateAuthToken(accountType, token);
if (callback != null)
callback.run(true);
return;
} catch (AuthenticatorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (OperationCanceledException e) {
e.printStackTrace();
}
if (callback != null)
callback.run(false);
}, null);
}
public void deleteAccount(String accountType) {
Account[] accounts = mAccountManager.getAccountsByType(accountType);
int[] count = {accounts.length};
@@ -57,34 +76,14 @@ public class CustomAccountManager {
}
}
public void getTokenForAccountCreateIfNeeded(String accountType, String authTokenType) {
MainActivity activity = this.mActivityInterface.get();
if (activity != null) {
final AccountManagerFuture<Bundle> future = mAccountManager.getAuthTokenByFeatures(accountType, authTokenType, null, activity, null, null,
future1 -> {
Bundle bnd = null;
try {
bnd = future1.getResult();
final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN);
//showToast(((authtoken != null) ? "SUCCESS!\ntoken: " + authtoken : "FAIL"));
//log.d("udinic", "GetTokenForAccount Bundle is " + bnd);
} catch (Exception e) {
e.printStackTrace();
//showToast(e.getMessage());
}
}
, null);
}
}
public void getTokenByType(String accountType, String authTokenType, StringInterface callback) {
public void getTokenByType(String accountType, String authTokenType, @Nullable StringInterface callback) {
Account account = mAccountManager.getAccountsByType(accountType)[0];
mAccountManager.getAuthToken(account, authTokenType, null, true, accountManagerFuture -> {
try {
Bundle bnd = accountManagerFuture.getResult();
final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN);
callback.run(authtoken);
if (callback != null)
callback.run(authtoken);
return;
} catch (AuthenticatorException e) {
e.printStackTrace();
@@ -93,7 +92,8 @@ public class CustomAccountManager {
} catch (OperationCanceledException e) {
e.printStackTrace();
}
callback.run(null);
if (callback != null)
callback.run(null);
}, null);
}
@@ -127,8 +127,4 @@ public class CustomAccountManager {
public interface StringInterface {
void run(@Nullable String string);
}
public void invalidate(String accountType, String authTokenType) {
mAccountManager.invalidateAuthToken(accountType, authTokenType);
}
}

View File

@@ -19,60 +19,79 @@
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:visibility="gone" />
<ScrollView
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/login_form"
tools:context="de.sebse.fuplanner.services.newkvv.FUAuthenticatorActivity">
<LinearLayout
android:id="@+id/email_login_form"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:paddingTop="56dp"
android:paddingLeft="24dp"
android:paddingRight="24dp">
<ImageView android:src="@mipmap/ic_launcher"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginBottom="24dp"
android:layout_gravity="center_horizontal"
android:contentDescription="@string/cd_ic_launcher"/>
<!-- Email Label -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="6"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/email_sign_in_button"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold" />
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="@string/username"
android:autofillHints="username"
tools:targetApi="o" />
</com.google.android.material.textfield.TextInputLayout>
<!-- Password Label -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="@string/password"
android:autofillHints="password"
tools:targetApi="o"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="@string/log_in"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_offline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:visibility="gone"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
</LinearLayout>

View File

@@ -3,7 +3,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="de.sebse.fuplanner.fragments.LoginFragment">
tools:context="de.sebse.fuplanner.services.newkvv.FUAuthenticatorActivity">
<LinearLayout
android:orientation="vertical"