diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a2bf533c..22beee29 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -95,6 +95,18 @@ + + + + + + + + + + + + diff --git a/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java b/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java index f1cc81b2..11358f1c 100644 --- a/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java +++ b/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java @@ -40,10 +40,15 @@ import org.fedorahosted.freeotp.add.ScanActivity; import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; import android.database.DataSetObserver; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; @@ -51,6 +56,8 @@ import android.view.WindowManager.LayoutParams; import android.widget.GridView; +import com.google.gson.Gson; + public class MainActivity extends Activity implements OnMenuItemClickListener { private TokenAdapter mTokenAdapter; private DataSetObserver mDataSetObserver; @@ -132,8 +139,126 @@ public boolean onMenuItemClick(MenuItem item) { protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - Uri uri = intent.getData(); - if (uri != null) - TokenPersistence.addWithToast(this, uri.toString()); + final Uri uri = intent.getData(); + if (uri != null) { + String action = intent.getAction(); + if (action.equals(Intent.ACTION_VIEW)) { + TokenPersistence.addWithToast(this, uri.toString()); + return; + } + try { + final Token token = new Token(uri); + final String key = token.getID(); + final Intent out = new Intent(); + out.putExtra("key", key); + String appname = intent.getStringExtra("appname"); + if (appname == null) { + appname = getString(R.string.default_appname); + } + final SharedPreferences prefs = getSharedPreferences(TokenPersistence.NAME, Context.MODE_PRIVATE); + switch (action) { + case Intent.ACTION_GET_CONTENT: + if (prefs.contains(key)) { + new AlertDialog.Builder(this) + .setTitle(R.string.attention) + .setMessage(appname + getString(R.string.request_code) + "\"" + key + "\"") + .setCancelable(false) + .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + out.putExtra("currentCode", new Gson().fromJson(prefs.getString(key, null), Token.class).generateCodes().getCurrentCode()); + setResult(Activity.RESULT_OK, out); + finish(); + } + }) + .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + setResult(Activity.RESULT_CANCELED, out); + finish(); + } + }) + .show() + ; + } else { + setResult(Activity.RESULT_CANCELED, out); + finish(); + } + break; + case Intent.ACTION_INSERT: + if (prefs.contains(key)) { + new AlertDialog.Builder(MainActivity.this) + .setTitle(R.string.error) + .setMessage(String.format(getString(R.string.token_already_exists), key)) + .setCancelable(false) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + setResult(Activity.RESULT_CANCELED, out); + finish(); + } + }) + .show() + ; + } else { + new AlertDialog.Builder(this) + .setTitle(R.string.attention) + .setMessage(appname + getString(R.string.request_install_token) + "\"" + key + "\"") + .setCancelable(false) + .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + try { + new TokenPersistence(MainActivity.this).add(token); + out.putExtra("currentCode", token.generateCodes().getCurrentCode()); + out.putExtra("secret", uri.getQueryParameter("secret")); + setResult(Activity.RESULT_OK, out); + finish(); + } catch (Token.TokenUriInvalidException e) { + new AlertDialog.Builder(MainActivity.this) + .setTitle(R.string.error) + .setMessage(getString(R.string.bad_token_uri) + uri.toString()) + .setCancelable(false) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + setResult(Activity.RESULT_CANCELED, out); + finish(); + } + }) + .show() + ; + } + } + }) + .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + setResult(Activity.RESULT_CANCELED, out); + finish(); + } + }) + .show() + ; + } + break; + default: + Log.e("LOG", "bad action: " + action); + } + } catch (Token.TokenUriInvalidException e) { + new AlertDialog.Builder(this) + .setTitle(R.string.error) + .setMessage(getString(R.string.bad_token_uri) + uri.toString()) + .setCancelable(false) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + finish(); + } + }) + .show() + ; + } + } } } diff --git a/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java b/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java index 3d450f90..8c4ba378 100644 --- a/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java +++ b/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java @@ -8,7 +8,6 @@ import android.content.Context; import android.content.SharedPreferences; -import android.net.Uri; import android.widget.Toast; import com.google.gson.Gson; @@ -16,7 +15,7 @@ import com.google.gson.reflect.TypeToken; public class TokenPersistence { - private static final String NAME = "tokens"; + protected static final String NAME = "tokens"; private static final String ORDER = "tokenOrder"; private final SharedPreferences prefs; private final Gson gson; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de39f413..3f6b2970 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,6 +38,16 @@ This is your last chance: if you delete this token, it will be gone forever. It will not be disabled on the server. Delete this token? + Attention + Error + Allow + Deny + An unspecified app + " has requested a code for token " + " has requested to install a token for " + "Bad token uri: " + Token \"%s\" already exists + MD5 SHA1