diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java index 7e15a174b..5789fd3eb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportFragment.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.annotation.StringRes; @@ -48,6 +49,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.widget.StatusIndicator; import org.sufficientlysecure.keychain.ui.widget.StatusIndicator.Status; import org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator; +import org.sufficientlysecure.keychain.util.FileHelper; public class CreateSecurityTokenImportFragment extends Fragment implements CreateSecurityTokenImportMvpView, @@ -56,6 +58,7 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat private static final String ARG_AID = "aid"; private static final String ARG_USER_ID = "user_ids"; private static final String ARG_URL = "key_uri"; + public static final int REQUEST_CODE_OPEN_FILE = 0; CreateSecurityTokenImportPresenter presenter; private ViewGroup statusLayoutGroup; @@ -114,6 +117,7 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat view.findViewById(R.id.button_reset_token_1).setOnClickListener(this); view.findViewById(R.id.button_reset_token_2).setOnClickListener(this); view.findViewById(R.id.button_reset_token_3).setOnClickListener(this); + view.findViewById(R.id.button_load_file).setOnClickListener(this); setHasOptionsMenu(true); @@ -228,6 +232,27 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat cryptoPromoteOperationHelper.cryptoOperation(); } + @Override + public void showFileSelectDialog() { + FileHelper.openDocument(this, null, "*/*", false, REQUEST_CODE_OPEN_FILE); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case REQUEST_CODE_OPEN_FILE: { + if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) { + Uri fileUri = data.getData(); + presenter.onFileSelected(fileUri); + } + break; + } + default: { + super.onActivityResult(requestCode, resultCode, data); + } + } + } + @Override public void onClick(View v) { switch (v.getId()) { @@ -243,6 +268,9 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat presenter.onClickViewKey(); break; } + case R.id.button_load_file: { + presenter.onClickLoadFile(); + } case R.id.button_reset_token_1: case R.id.button_reset_token_2: case R.id.button_reset_token_3: { @@ -298,7 +326,8 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat SEARCH_KEYSERVER (R.string.status_search_keyserver), IMPORT (R.string.status_import), TOKEN_PROMOTE(R.string.status_token_promote), - TOKEN_CHECK (R.string.status_token_check); + TOKEN_CHECK (R.string.status_token_check), + SEARCH_CONTENT_URI (R.string.status_content_uri); @StringRes private int stringRes; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java index 917e1c07b..8aa3a75af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportPresenter.java @@ -19,13 +19,14 @@ package org.sufficientlysecure.keychain.ui; import android.content.Context; +import android.net.Uri; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; -import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.ui.CreateSecurityTokenImportFragment.StatusLine; +import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.ContentUriRetrievalLoader; import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.KeyRetrievalResult; import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.KeyserverRetrievalLoader; import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.LocalKeyLookupLoader; @@ -36,6 +37,8 @@ class CreateSecurityTokenImportPresenter { private static final int LOADER_LOCAL = 0; private static final int LOADER_URI = 1; private static final int LOADER_KEYSERVER = 2; + private static final int LOADER_CONTENT_URI = 3; + private static final String ARG_CONTENT_URI = "content_uri"; private Context context; @@ -119,6 +122,9 @@ class CreateSecurityTokenImportPresenter { return new UriKeyRetrievalLoader(context, tokenUrl, tokenFingerprints); case LOADER_KEYSERVER: return new KeyserverRetrievalLoader(context, tokenFingerprints[0]); + case LOADER_CONTENT_URI: + return new ContentUriRetrievalLoader(context, tokenFingerprints[0], + args.getParcelable(ARG_CONTENT_URI)); } throw new IllegalArgumentException("called with unknown loader id!"); } @@ -138,6 +144,10 @@ class CreateSecurityTokenImportPresenter { searchedKeyservers = true; break; } + case LOADER_CONTENT_URI: { + // nothing to do here + break; + } default: { throw new IllegalArgumentException("called with unknown loader id!"); } @@ -218,7 +228,20 @@ class CreateSecurityTokenImportPresenter { } public void onClickResetToken() { + // TODO + } + void onClickLoadFile() { + view.showFileSelectDialog(); + } + + void onFileSelected(Uri contentUri) { + view.resetStatusLines(); + view.statusLineAdd(StatusLine.SEARCH_CONTENT_URI); + + Bundle args = new Bundle(); + args.putParcelable(ARG_CONTENT_URI, contentUri); + loaderManager.restartLoader(LOADER_CONTENT_URI, args, loaderCallbacks); } interface CreateSecurityTokenImportMvpView { @@ -236,5 +259,7 @@ class CreateSecurityTokenImportPresenter { void operationPromote(long masterKeyId, byte[] cardAid); void finishAndShowKey(long masterKeyId); + + void showFileSelectDialog(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java index 6ffd473d8..a407fed58 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PublicKeyRetrievalLoader.java @@ -18,16 +18,21 @@ package org.sufficientlysecure.keychain.ui; +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; +import android.content.ContentResolver; import android.content.Context; +import android.net.Uri; import android.os.SystemClock; import android.support.annotation.Nullable; import android.support.v4.content.AsyncTaskLoader; import android.util.Log; import com.google.auto.value.AutoValue; +import okhttp3.Call; import okhttp3.Request.Builder; import okhttp3.Response; import org.sufficientlysecure.keychain.Constants; @@ -35,10 +40,9 @@ import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress; import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient; import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryFailedException; import org.sufficientlysecure.keychain.network.OkHttpClientFactory; -import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeyRepository.NotFoundException; @@ -66,7 +70,7 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader uncachedKeyRingIterator = UncachedKeyRing.fromStream( + new BufferedInputStream(is)); + while (uncachedKeyRingIterator.hasNext()) { + UncachedKeyRing keyRing = uncachedKeyRingIterator.next(); + if (Arrays.equals(fingerprint, keyRing.getFingerprint())) { + return KeyRetrievalResult.createWithKeyringdata(keyRing.getMasterKeyId(), keyRing.getEncoded()); + } + } + } catch (IOException e) { + Log.e(Constants.TAG, "error retrieving key from keyserver", e); + } + + return KeyRetrievalResult.createWithError(); + } + } + @Override public void deliverResult(KeyRetrievalResult result) { cachedResult = result; diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 9e1d58a15..7419e0251 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1924,5 +1924,6 @@ Importing key… Setting up key… Checking key setup… + Reading file…