From ee807628bb26d894f5d3f2266efbd0fedbdec9c0 Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Wed, 6 Aug 2014 19:37:18 +0200 Subject: [PATCH] Prevent flattr login if API keys are missing closes #474 --- .../activity/PreferenceActivity.java | 2 + src/de/danoeh/antennapod/storage/DBTasks.java | 4 +- .../antennapod/util/flattr/FlattrUtils.java | 459 ++++++++++-------- 3 files changed, 249 insertions(+), 216 deletions(-) diff --git a/src/de/danoeh/antennapod/activity/PreferenceActivity.java b/src/de/danoeh/antennapod/activity/PreferenceActivity.java index a62ad3ae9..cd6731c02 100644 --- a/src/de/danoeh/antennapod/activity/PreferenceActivity.java +++ b/src/de/danoeh/antennapod/activity/PreferenceActivity.java @@ -45,6 +45,7 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { private static final String TAG = "PreferenceActivity"; private static final String PREF_FLATTR_THIS_APP = "prefFlattrThisApp"; + private static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings"; private static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate"; private static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; private static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs"; @@ -332,6 +333,7 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { boolean hasFlattrToken = FlattrUtils.hasToken(); + findPreference(PREF_FLATTR_SETTINGS).setEnabled(FlattrUtils.hasAPICredentials()); findPreference(PREF_FLATTR_AUTH).setEnabled(!hasFlattrToken); findPreference(PREF_FLATTR_REVOKE).setEnabled(hasFlattrToken); findPreference(PREF_AUTO_FLATTR_PREFS).setEnabled(hasFlattrToken); diff --git a/src/de/danoeh/antennapod/storage/DBTasks.java b/src/de/danoeh/antennapod/storage/DBTasks.java index 8d0ffd9c1..a230ba797 100644 --- a/src/de/danoeh/antennapod/storage/DBTasks.java +++ b/src/de/danoeh/antennapod/storage/DBTasks.java @@ -872,7 +872,7 @@ public final class DBTasks { item.getFlattrStatus().setFlattrQueue(); DBWriter.setFlattredStatus(context, item, true); } else { - FlattrUtils.showNoTokenDialog(context, item.getPaymentLink()); + FlattrUtils.showNoTokenDialogOrRedirect(context, item.getPaymentLink()); } } @@ -888,7 +888,7 @@ public final class DBTasks { feed.getFlattrStatus().setFlattrQueue(); DBWriter.setFlattredStatus(context, feed, true); } else { - FlattrUtils.showNoTokenDialog(context, feed.getPaymentLink()); + FlattrUtils.showNoTokenDialogOrRedirect(context, feed.getPaymentLink()); } } diff --git a/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java b/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java index 202e3d304..1ff3437c0 100644 --- a/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java +++ b/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java @@ -9,12 +9,8 @@ import android.content.SharedPreferences; import android.net.Uri; import android.preference.PreferenceManager; import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.PodcastApp; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.FlattrAuthActivity; -import de.danoeh.antennapod.asynctask.FlattrTokenFetcher; -import de.danoeh.antennapod.storage.DBWriter; + +import org.apache.commons.lang3.StringUtils; import org.shredzone.flattr4j.FlattrService; import org.shredzone.flattr4j.exception.FlattrException; import org.shredzone.flattr4j.model.Flattr; @@ -23,252 +19,287 @@ import org.shredzone.flattr4j.oauth.AccessToken; import org.shredzone.flattr4j.oauth.AndroidAuthenticator; import org.shredzone.flattr4j.oauth.Scope; -import java.util.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.EnumSet; +import java.util.List; +import java.util.TimeZone; -/** Utility methods for doing something with flattr. */ +import de.danoeh.antennapod.BuildConfig; +import de.danoeh.antennapod.PodcastApp; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.FlattrAuthActivity; +import de.danoeh.antennapod.asynctask.FlattrTokenFetcher; +import de.danoeh.antennapod.storage.DBWriter; + +/** + * Utility methods for doing something with flattr. + */ public class FlattrUtils { - private static final String TAG = "FlattrUtils"; + private static final String TAG = "FlattrUtils"; - private static final String HOST_NAME = "de.danoeh.antennapod"; + private static final String HOST_NAME = "de.danoeh.antennapod"; - private static final String PREF_ACCESS_TOKEN = "de.danoeh.antennapod.preference.flattrAccessToken"; + private static final String PREF_ACCESS_TOKEN = "de.danoeh.antennapod.preference.flattrAccessToken"; - // Flattr URL for this app. - public static final String APP_URL = "http://antennapod.com"; - // Human-readable flattr-page. - public static final String APP_LINK = "https://flattr.com/thing/745609/"; - public static final String APP_THING_ID = "745609"; + // Flattr URL for this app. + public static final String APP_URL = "http://antennapod.com"; + // Human-readable flattr-page. + public static final String APP_LINK = "https://flattr.com/thing/745609/"; + public static final String APP_THING_ID = "745609"; - private static volatile AccessToken cachedToken; + private static volatile AccessToken cachedToken; - private static AndroidAuthenticator createAuthenticator() { - return new AndroidAuthenticator(HOST_NAME, BuildConfig.FLATTR_APP_KEY, - BuildConfig.FLATTR_APP_SECRET); - } + private static AndroidAuthenticator createAuthenticator() { + return new AndroidAuthenticator(HOST_NAME, BuildConfig.FLATTR_APP_KEY, + BuildConfig.FLATTR_APP_SECRET); + } - public static void startAuthProcess(Context context) throws FlattrException { - AndroidAuthenticator auth = createAuthenticator(); - auth.setScope(EnumSet.of(Scope.FLATTR)); - Intent intent = auth.createAuthenticateIntent(); - context.startActivity(intent); - } + public static void startAuthProcess(Context context) throws FlattrException { + AndroidAuthenticator auth = createAuthenticator(); + auth.setScope(EnumSet.of(Scope.FLATTR)); + Intent intent = auth.createAuthenticateIntent(); + context.startActivity(intent); + } - private static AccessToken retrieveToken() { - if (cachedToken == null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Retrieving access token"); - String token = PreferenceManager.getDefaultSharedPreferences( - PodcastApp.getInstance()) - .getString(PREF_ACCESS_TOKEN, null); - if (token != null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Found access token. Caching."); - cachedToken = new AccessToken(token); - } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "No access token found"); - return null; - } - } - return cachedToken; + private static AccessToken retrieveToken() { + if (cachedToken == null) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Retrieving access token"); + String token = PreferenceManager.getDefaultSharedPreferences( + PodcastApp.getInstance()) + .getString(PREF_ACCESS_TOKEN, null); + if (token != null) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Found access token. Caching."); + cachedToken = new AccessToken(token); + } else { + if (BuildConfig.DEBUG) + Log.d(TAG, "No access token found"); + return null; + } + } + return cachedToken; - } + } - public static boolean hasToken() { - return retrieveToken() != null; - } + /** + * Returns true if FLATTR_APP_KEY and FLATTR_APP_SECRET in BuildConfig are not null and not empty + */ + public static boolean hasAPICredentials() { + return StringUtils.isNotEmpty(BuildConfig.FLATTR_APP_KEY) + && StringUtils.isNoneEmpty(BuildConfig.FLATTR_APP_SECRET); + } - public static void storeToken(AccessToken token) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Storing token"); - SharedPreferences.Editor editor = PreferenceManager - .getDefaultSharedPreferences(PodcastApp.getInstance()).edit(); - if (token != null) { - editor.putString(PREF_ACCESS_TOKEN, token.getToken()); - } else { - editor.putString(PREF_ACCESS_TOKEN, null); - } - editor.commit(); - cachedToken = token; - } + public static boolean hasToken() { + return retrieveToken() != null; + } - public static void deleteToken() { - if (BuildConfig.DEBUG) - Log.d(TAG, "Deleting flattr token"); - storeToken(null); - } + public static void storeToken(AccessToken token) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Storing token"); + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(PodcastApp.getInstance()).edit(); + if (token != null) { + editor.putString(PREF_ACCESS_TOKEN, token.getToken()); + } else { + editor.putString(PREF_ACCESS_TOKEN, null); + } + editor.commit(); + cachedToken = token; + } - public static Thing getAppThing(Context context) { - FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); - try { - Thing thing = fs.getThing(Thing.withId(APP_THING_ID)); - return thing; - } catch (FlattrException e) { - e.printStackTrace(); - showErrorDialog(context, e.getMessage()); - return null; - } - } + public static void deleteToken() { + if (BuildConfig.DEBUG) + Log.d(TAG, "Deleting flattr token"); + storeToken(null); + } - public static void clickUrl(Context context, String url) - throws FlattrException { - if (hasToken()) { - FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); - fs.click(url); - } else { - Log.e(TAG, "clickUrl was called with null access token"); - } - } - - public static List retrieveFlattredThings() - throws FlattrException { - ArrayList myFlattrs = new ArrayList(); + public static Thing getAppThing(Context context) { + FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); + try { + Thing thing = fs.getThing(Thing.withId(APP_THING_ID)); + return thing; + } catch (FlattrException e) { + e.printStackTrace(); + showErrorDialog(context, e.getMessage()); + return null; + } + } - if (hasToken()) { - FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); + public static void clickUrl(Context context, String url) + throws FlattrException { + if (hasToken()) { + FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); + fs.click(url); + } else { + Log.e(TAG, "clickUrl was called with null access token"); + } + } - Calendar firstOfMonth = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - firstOfMonth.set(Calendar.MILLISECOND, 0); - firstOfMonth.set(Calendar.SECOND, 0); - firstOfMonth.set(Calendar.MINUTE, 0); - firstOfMonth.set(Calendar.HOUR_OF_DAY, 0); - firstOfMonth.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH)); - - Date firstOfMonthDate = firstOfMonth.getTime(); + public static List retrieveFlattredThings() + throws FlattrException { + ArrayList myFlattrs = new ArrayList(); - // subscriptions some times get flattrd slightly before midnight - give it an hour leeway - firstOfMonthDate = new Date(firstOfMonthDate.getTime() - 60*60*1000); - - final int FLATTR_COUNT = 30; - final int FLATTR_MAXPAGE = 5; - - for (int page = 0; page < FLATTR_MAXPAGE; page++) { - for (Flattr fl: fs.getMyFlattrs(FLATTR_COUNT, page)) { - if (fl.getCreated().after(firstOfMonthDate)) - myFlattrs.add(fl); - else - break; - } - } - - if (BuildConfig.DEBUG) { - Log.d(TAG, "Got my flattrs list of length " + Integer.toString(myFlattrs.size()) + " comparison date" + firstOfMonthDate); + if (hasToken()) { + FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); - for (Flattr fl: myFlattrs) { - Thing thing = fl.getThing(); - Log.d(TAG, "Flattr thing: " + fl.getThingId() + " name: " + thing.getTitle() + " url: " + thing.getUrl() + " on: " + fl.getCreated()); - } - } - - } else { - Log.e(TAG, "retrieveFlattrdThings was called with null access token"); - } - - return myFlattrs; - } + Calendar firstOfMonth = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + firstOfMonth.set(Calendar.MILLISECOND, 0); + firstOfMonth.set(Calendar.SECOND, 0); + firstOfMonth.set(Calendar.MINUTE, 0); + firstOfMonth.set(Calendar.HOUR_OF_DAY, 0); + firstOfMonth.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH)); - public static void handleCallback(Context context, Uri uri) { - AndroidAuthenticator auth = createAuthenticator(); - new FlattrTokenFetcher(context, auth, uri).executeAsync(); - } + Date firstOfMonthDate = firstOfMonth.getTime(); - public static void revokeAccessToken(Context context) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Revoking access token"); - deleteToken(); - FlattrServiceCreator.deleteFlattrService(); - showRevokeDialog(context); + // subscriptions some times get flattrd slightly before midnight - give it an hour leeway + firstOfMonthDate = new Date(firstOfMonthDate.getTime() - 60 * 60 * 1000); + + final int FLATTR_COUNT = 30; + final int FLATTR_MAXPAGE = 5; + + for (int page = 0; page < FLATTR_MAXPAGE; page++) { + for (Flattr fl : fs.getMyFlattrs(FLATTR_COUNT, page)) { + if (fl.getCreated().after(firstOfMonthDate)) + myFlattrs.add(fl); + else + break; + } + } + + if (BuildConfig.DEBUG) { + Log.d(TAG, "Got my flattrs list of length " + Integer.toString(myFlattrs.size()) + " comparison date" + firstOfMonthDate); + + for (Flattr fl : myFlattrs) { + Thing thing = fl.getThing(); + Log.d(TAG, "Flattr thing: " + fl.getThingId() + " name: " + thing.getTitle() + " url: " + thing.getUrl() + " on: " + fl.getCreated()); + } + } + + } else { + Log.e(TAG, "retrieveFlattrdThings was called with null access token"); + } + + return myFlattrs; + } + + public static void handleCallback(Context context, Uri uri) { + AndroidAuthenticator auth = createAuthenticator(); + new FlattrTokenFetcher(context, auth, uri).executeAsync(); + } + + public static void revokeAccessToken(Context context) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Revoking access token"); + deleteToken(); + FlattrServiceCreator.deleteFlattrService(); + showRevokeDialog(context); DBWriter.clearAllFlattrStatus(context); } - // ------------------------------------------------ DIALOGS + // ------------------------------------------------ DIALOGS - public static void showRevokeDialog(final Context context) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.access_revoked_title); - builder.setMessage(R.string.access_revoked_info); - builder.setNeutralButton(android.R.string.ok, new OnClickListener() { + public static void showRevokeDialog(final Context context) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.access_revoked_title); + builder.setMessage(R.string.access_revoked_info); + builder.setNeutralButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - builder.create().show(); - } + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + builder.create().show(); + } - public static void showNoTokenDialog(final Context context, final String url) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Creating showNoTokenDialog"); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.no_flattr_token_title); - builder.setMessage(R.string.no_flattr_token_msg); - builder.setPositiveButton(R.string.authenticate_now_label, - new OnClickListener() { + /** + * Opens a dialog that ask the user to either connect the app with flattr or to be redirected to + * the thing's website. + * If no API credentials are available, the user will immediately be redirected to the thing's website. + * */ + public static void showNoTokenDialogOrRedirect(final Context context, final String url) { + if (hasAPICredentials()) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.no_flattr_token_title); + builder.setMessage(R.string.no_flattr_token_msg); + builder.setPositiveButton(R.string.authenticate_now_label, + new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - context.startActivity(new Intent(context, - FlattrAuthActivity.class)); - } + @Override + public void onClick(DialogInterface dialog, int which) { + context.startActivity(new Intent(context, + FlattrAuthActivity.class)); + } - }); - builder.setNegativeButton(R.string.visit_website_label, - new OnClickListener() { + } + ); - @Override - public void onClick(DialogInterface dialog, int which) { - Uri uri = Uri.parse(url); - context.startActivity(new Intent(Intent.ACTION_VIEW, - uri)); - } + builder.setNegativeButton(R.string.visit_website_label, + new OnClickListener() { - }); - builder.create().show(); - } + @Override + public void onClick(DialogInterface dialog, int which) { + Uri uri = Uri.parse(url); + context.startActivity(new Intent(Intent.ACTION_VIEW, + uri)); + } - public static void showForbiddenDialog(final Context context, - final String url) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.action_forbidden_title); - builder.setMessage(R.string.action_forbidden_msg); - builder.setPositiveButton(R.string.authenticate_now_label, - new OnClickListener() { + } + ); + builder.create().show(); + } else { + Uri uri = Uri.parse(url); + context.startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + } - @Override - public void onClick(DialogInterface dialog, int which) { - context.startActivity(new Intent(context, - FlattrAuthActivity.class)); - } + public static void showForbiddenDialog(final Context context, + final String url) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.action_forbidden_title); + builder.setMessage(R.string.action_forbidden_msg); + builder.setPositiveButton(R.string.authenticate_now_label, + new OnClickListener() { - }); - builder.setNegativeButton(R.string.visit_website_label, - new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + context.startActivity(new Intent(context, + FlattrAuthActivity.class)); + } - @Override - public void onClick(DialogInterface dialog, int which) { - Uri uri = Uri.parse(url); - context.startActivity(new Intent(Intent.ACTION_VIEW, - uri)); - } + } + ); + builder.setNegativeButton(R.string.visit_website_label, + new OnClickListener() { - }); - builder.create().show(); - } + @Override + public void onClick(DialogInterface dialog, int which) { + Uri uri = Uri.parse(url); + context.startActivity(new Intent(Intent.ACTION_VIEW, + uri)); + } - public static void showErrorDialog(final Context context, final String msg) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.error_label); - builder.setMessage(msg); - builder.setNeutralButton(android.R.string.ok, new OnClickListener() { + } + ); + builder.create().show(); + } - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - builder.create().show(); - } + public static void showErrorDialog(final Context context, final String msg) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.error_label); + builder.setMessage(msg); + builder.setNeutralButton(android.R.string.ok, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + builder.create().show(); + } } \ No newline at end of file