package io.codetail; import android.accounts.Account; import android.accounts.AccountAuthenticatorResponse; import android.accounts.AccountManager; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; import butterknife.OnClick; import codetail.text.MaterialEditText; import codetail.widget.Toolbar; import io.codetail.client.auth.Authenticator; import io.codetail.sources.Source; import io.codetail.watchme.R; import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE; import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; import static android.accounts.AccountManager.KEY_AUTHTOKEN; import static android.accounts.AccountManager.KEY_ERROR_CODE; import static io.codetail.client.auth.Authenticator.AuthenticationEvent; import static io.codetail.client.auth.BasicAccountAuthenticator.ACTION_AUTHENTICATE; import static io.codetail.client.auth.BasicAccountAuthenticator.ERROR_CODE_INVALID_USER_DATA; import static io.codetail.fragments.NavigationFragment.USER_PICTURE_URL; public class AuthenticationActivity extends WatchMeActivity{ Bus mEventBus; @InjectView(R.id.username) MaterialEditText mUsernameField; @InjectView(R.id.password) MaterialEditText mPasswordField; @InjectView(R.id.login) View mSignIn; @InjectView(R.id.headline) TextView mHeadline; @InjectView(R.id.description) TextView mDescription; Authenticator mAuthenticator; AccountAuthenticatorResponse mAuthenticatorResponse; String mSourceId; Account mAccount; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_auth); ButterKnife.inject(this); mEventBus = Constants.getEventBus(); final Intent intent = getIntent(); final String action = intent.getAction(); if(!ACTION_AUTHENTICATE.equals(action)){ throw new RuntimeException("Only authentication supported"); } mAuthenticatorResponse = intent.getParcelableExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); mSourceId = intent.getStringExtra(KEY_ACCOUNT_TYPE); if(mSourceId == null){ throw new NullPointerException("Account type is not given"); } List<Source> sources = WatchMeApplication.getApplication().getSources(); for(Source source : sources){ if(source.getSourceId().equals(mSourceId)){ mAuthenticator = source.getAuthenticator(); } } if(mAuthenticator == null){ throw new NullPointerException(String.format("Source for %s not found", mSourceId)); } if(mAuthenticatorResponse != null){ mAuthenticatorResponse.onRequestContinued(); } mHeadline.setText(mAuthenticator.getHeadline()); mDescription.setText(mAuthenticator.getDescription()); } @Override protected void onStart() { super.onStart(); mEventBus.register(this); } @OnClick(R.id.login) public void canLogin(){ if(!mUsernameField.isCharactersCountValid()){ mUsernameField.setError(getString(R.string.sign_in_field_must_be_more_than_4_chars)); } if(!mPasswordField.isCharactersCountValid()){ mPasswordField.setError(getString(R.string.sign_in_field_must_be_more_than_4_chars)); } if(mUsernameField.isCharactersCountValid() && mPasswordField.isCharactersCountValid()){ mUsernameField.setError(null); mPasswordField.setError(null); tryAuthenticateUser(); } } public void tryAuthenticateUser(){ setLockForm(true); String username = mUsernameField.getText().toString(); String password = mPasswordField.getText().toString(); mAccount = new Account(username, mSourceId); mAuthenticator.login(mAccount, password); } @Subscribe public void onEvent(AuthenticationEvent event){ Bundle result = event.getResult(); setLockForm(false); if(event.isSuccess()){ String password = mPasswordField.getText().toString(); AccountManager manager = AccountManager.get(this); Bundle userData = new Bundle(); userData.putString(USER_PICTURE_URL, result.getString(USER_PICTURE_URL)); manager.addAccountExplicitly(mAccount, password, userData); manager.setAuthToken(mAccount, mSourceId, result.getString(KEY_AUTHTOKEN)); mAuthenticatorResponse.onResult(result); mAuthenticatorResponse = null; setResult(RESULT_OK); finish(); }else{ int errorCode = result.getInt(KEY_ERROR_CODE); if(errorCode == ERROR_CODE_INVALID_USER_DATA){ mUsernameField.setError(getString(R.string.sign_in_failed_with_wrong_data_username)); mPasswordField.setError(getString(R.string.sign_in_failed_with_wrong_data_password)); } } } void setLockForm(boolean lockForm){ mUsernameField.setEnabled(!lockForm); mPasswordField.setEnabled(!lockForm); mSignIn.setEnabled(!lockForm); } public void cancel(){ mAuthenticatorResponse.onError(AccountManager.ERROR_CODE_CANCELED, "cancelled"); mAuthenticatorResponse = null; setResult(RESULT_CANCELED); super.finish(); } @Override protected void onStop() { super.onStop(); ButterKnife.reset(this); mEventBus.unregister(this); } @Override public void onBackPressed() { cancel(); } @Override public void setNavigationLockMode(boolean lockMode) { throw new UnsupportedOperationException("Lock mode is unsupported"); } @Override public Toolbar getToolbar() { throw new UnsupportedOperationException("No toolbar provided"); } }