diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eb839a2ac..a6b2329f3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -42,10 +42,6 @@ android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@style/AppTheme.NoActionBar"> - parameters = new HashMap<>(); + final HashMap parameters = new HashMap<>(); parameters.put(Helper.CLIENT_NAME, Helper.OAUTH_REDIRECT_HOST); parameters.put(Helper.REDIRECT_URIS,"https://" + Helper.INSTANCE + Helper.REDIRECT_CONTENT); parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES); @@ -105,8 +115,50 @@ public class LoginActivity extends AppCompatActivity { connectionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - startActivity(webviewIntent); - finish(); + connectionButton.setEnabled(false); + AsyncHttpClient client = new AsyncHttpClient(); + RequestParams requestParams = new RequestParams(); + SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + requestParams.add(Helper.CLIENT_ID, sharedpreferences.getString(Helper.CLIENT_ID, null)); + requestParams.add(Helper.CLIENT_SECRET, sharedpreferences.getString(Helper.CLIENT_SECRET, null)); + requestParams.add("grant_type", "password"); + EditText login_uid = (EditText) findViewById(R.id.login_uid); + EditText login_passwd = (EditText) findViewById(R.id.login_passwd); + requestParams.add("username",login_uid.getText().toString().trim()); + requestParams.add("password",login_passwd.getText().toString().trim()); + client.setUserAgent(USER_AGENT); + try { + client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore())); + client.post("https://" + Helper.INSTANCE + "/oauth/token", requestParams, new AsyncHttpResponseHandler() { + @Override + public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { + String response = new String(responseBody); + JSONObject resobj; + try { + resobj = new JSONObject(response); + String token = resobj.get("access_token").toString(); + SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token); + editor.apply(); + //Update the account with the token; + new UpdateAccountInfoAsyncTask(LoginActivity.this, token).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { + connectionButton.setEnabled(true); + Toast.makeText(getApplicationContext(),R.string.toast_error_login,Toast.LENGTH_LONG).show(); + } + }); + + } catch (NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | KeyStoreException e) { + e.printStackTrace(); + } + } }); } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/WebviewActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/WebviewActivity.java deleted file mode 100644 index 6f5afcb85..000000000 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/WebviewActivity.java +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright 2017 Thomas Schneider - * - * This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Mastodon Etalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Thomas Schneider; if not, - * see . */ - -package fr.gouv.etalab.mastodon.activities; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.webkit.CookieManager; -import android.webkit.CookieSyncManager; -import android.webkit.WebChromeClient; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.ProgressBar; - -import com.loopj.android.http.AsyncHttpResponseHandler; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; - -import cz.msebera.android.httpclient.Header; -import mastodon.etalab.gouv.fr.mastodon.R; -import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask; -import fr.gouv.etalab.mastodon.client.OauthClient; -import fr.gouv.etalab.mastodon.helper.Helper; - -/** - * Created by Thomas on 24/04/2017. - * Webview to connect accounts - */ -public class WebviewActivity extends AppCompatActivity { - - - private Activity activity; - private WebView webView; - private Context context; - private AlertDialog alert; - private String clientId, clientSecret; - - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_webview); - this.activity = this; - this.context = this; - this.context = this.getApplicationContext(); - SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - clientId = sharedpreferences.getString(Helper.CLIENT_ID, null); - clientSecret = sharedpreferences.getString(Helper.CLIENT_SECRET, null); - - webView = (WebView) findViewById(R.id.webviewConnect); - clearCookies(getApplicationContext()); - final ProgressBar pbar = (ProgressBar) findViewById(R.id.progress_bar); - - webView.setWebChromeClient(new WebChromeClient() { - @Override - public void onProgressChanged(WebView view, int progress) { - if (progress < 100 && pbar.getVisibility() == ProgressBar.GONE) { - pbar.setVisibility(ProgressBar.VISIBLE); - } - pbar.setProgress(progress); - if (progress == 100) { - pbar.setVisibility(ProgressBar.GONE); - } - } - }); - webView.setWebViewClient(new WebViewClient() { - @SuppressWarnings("deprecation") - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url){ - super.shouldOverrideUrlLoading(view,url); - if( url.contains(Helper.REDIRECT_CONTENT)){ - String val[] = url.split("code="); - String code = val[1]; - - String action = "/oauth/token"; - HashMap parameters = new HashMap<>(); - parameters.put(Helper.CLIENT_ID, clientId); - parameters.put(Helper.CLIENT_SECRET, clientSecret); - parameters.put(Helper.REDIRECT_URI,"https://" + Helper.INSTANCE + Helper.REDIRECT_CONTENT); - parameters.put("grant_type", "authorization_code"); - parameters.put("code",code); - new OauthClient().post(action, parameters, new AsyncHttpResponseHandler() { - @Override - public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { - String response = new String(responseBody); - JSONObject resobj; - try { - resobj = new JSONObject(response); - String token = resobj.get("access_token").toString(); - SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = sharedpreferences.edit(); - editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token); - editor.apply(); - //Update the account with the token; - new UpdateAccountInfoAsyncTask(WebviewActivity.this, true, token).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } catch (JSONException e) { - e.printStackTrace(); - } - - } - - @Override - public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { - error.printStackTrace(); - } - }); - - - return true; - } - return false; - } - }); - webView.loadUrl(redirectUserToAuthorizeAndLogin()); - } - - - @Override - public void onBackPressed() { - if (webView != null && webView.canGoBack()) { - webView.goBack(); - } else { - super.onBackPressed(); - } - } - - - - private String redirectUserToAuthorizeAndLogin() { - - String queryString = Helper.CLIENT_ID + "="+ clientId; - queryString += "&" + Helper.REDIRECT_URI + "="+ Uri.encode("https://" + Helper.INSTANCE + "/redirect_mastodon_api"); - queryString += "&" + Helper.RESPONSE_TYPE +"=code"; - queryString += "&" + Helper.SCOPE +"=" + Helper.OAUTH_SCOPES; - /*try { - queryString = URLEncoder.encode(queryString, "utf-8"); - } catch (UnsupportedEncodingException ignored) {}*/ - return "https://" + Helper.INSTANCE + Helper.EP_AUTHORIZE + "?" + queryString; - } - - - private String getOauthRedirectUri() { - return Helper.OAUTH_SCHEME + "://" + Helper.OAUTH_REDIRECT_HOST + "/"; - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (alert != null) { - alert.dismiss(); - alert = null; - } - } - - @SuppressWarnings("deprecation") - public static void clearCookies(Context context) - { - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { - CookieManager.getInstance().removeAllCookies(null); - CookieManager.getInstance().flush(); - } else - { - CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(context); - cookieSyncMngr.startSync(); - CookieManager cookieManager=CookieManager.getInstance(); - cookieManager.removeAllCookie(); - cookieManager.removeSessionCookie(); - cookieSyncMngr.stopSync(); - cookieSyncMngr.sync(); - } - } -} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java index a39442654..84ea7437f 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UpdateAccountInfoAsyncTask.java @@ -20,13 +20,11 @@ import android.content.Intent; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; -import android.util.Log; import fr.gouv.etalab.mastodon.activities.MainActivity; import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.helper.Helper; -import fr.gouv.etalab.mastodon.interfaces.OnUpdateAccountInfoInterface; import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.sqlite.AccountDAO; @@ -39,22 +37,11 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask { private Context context; private String token; - private boolean fromWebview; - private boolean error; - private OnUpdateAccountInfoInterface listener; - public UpdateAccountInfoAsyncTask(Context context, String token, OnUpdateAccountInfoInterface onUpdateAccountInfoInterface){ + + public UpdateAccountInfoAsyncTask(Context context, String token){ this.context = context; this.token = token; - this.fromWebview = false; - this.error = false; - this.listener = onUpdateAccountInfoInterface; - } - - public UpdateAccountInfoAsyncTask(Context context, boolean fromWebview, String token){ - this.context = context; - this.token = token; - this.fromWebview = fromWebview; } @@ -78,8 +65,6 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask { else { if( account.getUsername() != null && account.getCreated_at() != null) new AccountDAO(context, db).insertAccount(account); - else //Here the user credential in db doesn't match the remote one (it will be disconnected) - error = true; } return null; } @@ -87,14 +72,10 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask { @Override protected void onPostExecute(Void result) { - if( fromWebview){ - Intent mainActivity = new Intent(context, MainActivity.class); - mainActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(mainActivity); - ((Activity) context).finish(); - }else{ - listener.onUpdateAccountInfo(error); - } + Intent mainActivity = new Intent(context, MainActivity.class); + mainActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(mainActivity); + ((Activity) context).finish(); } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/MastalabSSLSocketFactory.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/MastalabSSLSocketFactory.java index 6979576ec..1789a491f 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/MastalabSSLSocketFactory.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/MastalabSSLSocketFactory.java @@ -27,7 +27,7 @@ import javax.net.ssl.X509TrustManager; * https://code.google.com/p/android/issues/detail?id=13117#c14

 

Warning! This omits SSL * certificate validation on every device, use with caution */ -class MastalabSSLSocketFactory extends com.loopj.android.http.MySSLSocketFactory { +public class MastalabSSLSocketFactory extends com.loopj.android.http.MySSLSocketFactory { private final SSLContext sslContext = SSLContext.getInstance("TLS"); /** @@ -39,7 +39,7 @@ class MastalabSSLSocketFactory extends com.loopj.android.http.MySSLSocketFactory * @throws KeyStoreException KeyStoreException * @throws UnrecoverableKeyException UnrecoverableKeyException */ - MastalabSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + public MastalabSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java index 4df102592..262c1a0a2 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/OauthClient.java @@ -59,6 +59,7 @@ public class OauthClient { public void post(String action, HashMap paramaters, AsyncHttpResponseHandler responseHandler) { RequestParams params = hashToRequestParams(paramaters); try { + client.setConnectTimeout(30000); //30s timeout client.setUserAgent(USER_AGENT); client.setSSLSocketFactory(new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore())); client.post(getAbsoluteUrl(action), params, responseHandler); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java index 476492543..b45a3346b 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java @@ -171,19 +171,16 @@ public class NotificationsListAdapter extends BaseAdapter { //Adds attachment -> disabled, to enable them uncomment the line below //loadAttachments(status, holder); holder.notification_status_container.setVisibility(View.VISIBLE); - - if( !status.getIn_reply_to_account_id().equals("null") || !status.getIn_reply_to_id().equals("null") ) { - holder.notification_status_content.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(context, ShowConversationActivity.class); - Bundle b = new Bundle(); - b.putString("statusId", status.getId()); //Your id - intent.putExtras(b); //Put your id to your next Intent - context.startActivity(intent); - } - }); - } + holder.notification_status_content.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(context, ShowConversationActivity.class); + Bundle b = new Bundle(); + b.putString("statusId", status.getId()); + intent.putExtras(b); + context.startActivity(intent); + } + }); switch (status.getVisibility()){ case "public": holder.status_privacy.setImageResource(R.drawable.ic_action_globe); @@ -216,8 +213,8 @@ public class NotificationsListAdapter extends BaseAdapter { public void onClick(View v) { Intent intent = new Intent(context, TootActivity.class); Bundle b = new Bundle(); - b.putString("inReplyTo", notification.getStatus().getId()); //Your id - intent.putExtras(b); //Put your id to your next Intent + b.putString("inReplyTo", notification.getStatus().getId()); + intent.putExtras(b); context.startActivity(intent); } }); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java index 215e2f1de..2d187e900 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java @@ -142,7 +142,7 @@ public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineSe title = getContext().getResources().getString(R.string.notif_pouet, status.getAccount().getDisplay_name()); }catch (Exception e){ icon_notification = BitmapFactory.decodeResource(getContext().getResources(), - R.drawable.mastodon_logo); + R.drawable.mastodonlogo); } } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java index 2f2ab6cb4..a116e1b2f 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java @@ -199,7 +199,7 @@ public class NotificationsSyncJob extends Job implements OnRetrieveNotifications icon_notification = imageLoaderNoty.loadImageSync(notificationUrl); }catch (Exception e){ icon_notification = BitmapFactory.decodeResource(getContext().getResources(), - R.drawable.mastodon_logo); + R.drawable.mastodonlogo); } } } diff --git a/app/src/main/res/drawable/background_splash.xml b/app/src/main/res/drawable/background_splash.xml index 3b4b972b7..1204da0ab 100644 --- a/app/src/main/res/drawable/background_splash.xml +++ b/app/src/main/res/drawable/background_splash.xml @@ -23,6 +23,6 @@ + android:src="@drawable/mastodonlogo"/> \ No newline at end of file diff --git a/app/src/main/res/drawable/mastodon_logo.png b/app/src/main/res/drawable/mastodon_logo.png deleted file mode 100644 index f0df29927..000000000 Binary files a/app/src/main/res/drawable/mastodon_logo.png and /dev/null differ diff --git a/app/src/main/res/drawable/mastodonlogo.png b/app/src/main/res/drawable/mastodonlogo.png new file mode 100644 index 000000000..3a2574151 Binary files /dev/null and b/app/src/main/res/drawable/mastodonlogo.png differ diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 97fd84b21..e8f35ad13 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -24,25 +24,41 @@ android:orientation="vertical" > + + +