From 435a73fcab8f8e37442de4cac8abcb33495387f4 Mon Sep 17 00:00:00 2001 From: M66B Date: Sun, 28 Oct 2018 17:09:38 +0000 Subject: [PATCH] Refactoring --- .../java/eu/faircode/email/ActivityView.java | 177 +++++------ .../eu/faircode/email/FragmentCompose.java | 278 ++++++++++-------- 2 files changed, 225 insertions(+), 230 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 0ce0ff4f..0ab59a56 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.content.IntentSender; import android.content.SharedPreferences; import android.content.res.Configuration; import android.net.Uri; @@ -55,10 +56,10 @@ import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpServiceConnection; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.InputStreamReader; @@ -70,8 +71,11 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Properties; import javax.mail.Address; +import javax.mail.Session; +import javax.mail.internet.MimeMessage; import javax.net.ssl.HttpsURLConnection; import androidx.annotation.NonNull; @@ -91,9 +95,9 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB private ListView drawerList; private ActionBarDrawerToggle drawerToggle; + private long message = -1; private long attachment = -1; - private long decryptId = -1; - private File decryptFile = null; + private OpenPgpServiceConnection pgpService; private static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes @@ -894,116 +898,92 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB } private void onDecrypt(Intent intent) { + Intent data = new Intent(); + data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); + data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{intent.getStringExtra("to")}); + data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + + decrypt(data, intent.getLongExtra("id", -1)); + } + + private void onShowPro(Intent intent) { + FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); + fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro"); + fragmentTransaction.commit(); + } + + private void decrypt(Intent data, long id) { Bundle args = new Bundle(); - args.putLong("id", intent.getLongExtra("id", -1)); + args.putLong("id", id); + args.putParcelable("data", data); - new SimpleTask() { + new SimpleTask() { @Override - protected File onLoad(Context context, Bundle args) { + protected PendingIntent onLoad(Context context, Bundle args) throws Throwable { long id = args.getLong("id"); + Intent data = args.getParcelable("data"); DB db = DB.getInstance(context); - try { - db.beginTransaction(); - - for (EntityAttachment attachment : db.attachment().getAttachments(id)) - if (attachment.available && "encrypted.asc".equals(attachment.name)) - return EntityAttachment.getFile(context, attachment.id); - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - return null; - } - - @Override - protected void onLoaded(Bundle args, File file) { - if (file != null) - try { + for (EntityAttachment attachment : db.attachment().getAttachments(id)) + if (attachment.available && "encrypted.asc".equals(attachment.name)) { if (!pgpService.isBound()) throw new IllegalArgumentException(getString(R.string.title_no_openpgp)); - Intent data = new Intent(); - data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); - data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{args.getString("to")}); - data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + OpenPgpApi api = new OpenPgpApi(context, pgpService.getService()); + FileInputStream encrypted = new FileInputStream(EntityAttachment.getFile(context, attachment.id)); + ByteArrayOutputStream decrypted = new ByteArrayOutputStream(); - decrypt(data, args.getLong("id"), file); - } catch (Throwable ex) { - if (ex instanceof IllegalArgumentException) - Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); - else - Helper.unexpectedError(ActivityView.this, ex); - } - } - }.load(this, args); - } + Intent result = api.executeApi(data, encrypted, decrypted); + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + ByteArrayInputStream is = new ByteArrayInputStream(decrypted.toByteArray()); - private void onShowPro(Intent intent) { - FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); - fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro"); - fragmentTransaction.commit(); - } + Properties props = MessageHelper.getSessionProperties(Helper.AUTH_TYPE_PASSWORD, false); + Session isession = Session.getInstance(props, null); + MimeMessage imessage = new MimeMessage(isession, is); + MessageHelper helper = new MessageHelper(imessage); - private void decrypt(Intent data, final long id, final File file) throws FileNotFoundException { - final OpenPgpApi api = new OpenPgpApi(this, pgpService.getService()); - final FileInputStream msg = new FileInputStream(file); - final ByteArrayOutputStream decrypted = new ByteArrayOutputStream(); + EntityMessage m = db.message().getMessage(id); + m.write(context, helper.getHtml()); + db.message().setMessageStored(id, new Date().getTime()); + break; - api.executeApiAsync(data, msg, decrypted, new OpenPgpApi.IOpenPgpCallback() { - @Override - public void onReturn(Intent result) { - try { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - Bundle args = new Bundle(); - args.putLong("id", id); + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + message = id; + return result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); - new SimpleTask() { - @Override - protected Void onLoad(Context context, Bundle args) throws Throwable { - long id = args.getLong("id"); + case OpenPgpApi.RESULT_CODE_ERROR: + OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); + throw new IllegalArgumentException(error.getMessage()); + } - DB db = DB.getInstance(context); - EntityMessage message = db.message().getMessage(id); - message.write(context, decrypted.toString("UTF-8")); - db.message().setMessageStored(id, new Date().getTime()); + break; + } - return null; - } + return null; + } - @Override - protected void onException(Bundle args, Throwable ex) { - Helper.unexpectedError(ActivityView.this, ex); - } - }.load(ActivityView.this, args); - - break; - - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - decryptId = id; - decryptFile = file; - PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); - startIntentSenderForResult( - pi.getIntentSender(), - ActivityView.REQUEST_DECRYPT, - null, 0, 0, 0, null); - break; - - case OpenPgpApi.RESULT_CODE_ERROR: - OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); - throw new IllegalArgumentException(error.getMessage()); - } - } catch (Throwable ex) { - if (ex instanceof IllegalArgumentException) - Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); - else + @Override + protected void onLoaded(Bundle args, PendingIntent pi) { + if (pi != null) + try { + startIntentSenderForResult( + pi.getIntentSender(), + ActivityView.REQUEST_DECRYPT, + null, 0, 0, 0, null); + } catch (IntentSender.SendIntentException ex) { Helper.unexpectedError(ActivityView.this, ex); - } + } } - }); + + @Override + protected void onException(Bundle args, Throwable ex) { + if (ex instanceof IllegalArgumentException) + Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); + else + Helper.unexpectedError(ActivityView.this, ex); + } + }.load(ActivityView.this, args); } @Override @@ -1075,14 +1055,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB } } else if (requestCode == REQUEST_DECRYPT) { if (data != null) - try { - decrypt(data, decryptId, decryptFile); - } catch (Throwable ex) { - if (ex instanceof IllegalArgumentException) - Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); - else - Helper.unexpectedError(ActivityView.this, ex); - } + decrypt(data, message); } } } diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index c2a0841e..969c8b0e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -25,6 +25,7 @@ import android.content.ClipboardManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Typeface; @@ -65,29 +66,38 @@ import android.widget.Toast; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.snackbar.Snackbar; +import org.jsoup.Jsoup; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpServiceConnection; import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; +import java.util.Properties; import javax.mail.Address; +import javax.mail.BodyPart; import javax.mail.MessageRemovedException; +import javax.mail.Multipart; +import javax.mail.Session; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -482,9 +492,6 @@ public class FragmentCompose extends FragmentEx { private void onEncrypt() { try { - if (!pgpService.isBound()) - throw new IllegalArgumentException(getString(R.string.title_no_openpgp)); - String to = etTo.getText().toString(); InternetAddress ato[] = (TextUtils.isEmpty(to) ? new InternetAddress[0] : InternetAddress.parse(to)); if (ato.length == 0) @@ -508,131 +515,152 @@ public class FragmentCompose extends FragmentEx { } } - private void encrypt(final Intent data) throws IOException { - final OpenPgpApi api = new OpenPgpApi(getContext(), pgpService.getService()); - final FileInputStream msg = new FileInputStream(EntityMessage.getFile(getContext(), working)); - final ByteArrayOutputStream encrypted = new ByteArrayOutputStream(); - + private void encrypt(Intent data) { final Bundle args = new Bundle(); args.putLong("id", working); + args.putParcelable("data", data); - api.executeApiAsync(data, msg, encrypted, new OpenPgpApi.IOpenPgpCallback() { + new SimpleTask() { @Override - public void onReturn(Intent result) { - Log.i(Helper.TAG, "Pgp result=" + result); - Bundle extras = result.getExtras(); - for (String key : extras.keySet()) - Log.i(Helper.TAG, key + "=" + extras.get(key)); + protected PendingIntent onLoad(Context context, Bundle args) throws Throwable { + long id = args.getLong("id"); + Intent data = args.getParcelable("data"); + + String body = EntityMessage.read(getContext(), id); + + BodyPart plain = new MimeBodyPart(); + plain.setContent(Jsoup.parse(body).text(), "text/plain; charset=" + Charset.defaultCharset().name()); + + BodyPart html = new MimeBodyPart(); + html.setContent(body, "text/html; charset=" + Charset.defaultCharset().name()); + + Multipart alternative = new MimeMultipart("alternative"); + alternative.addBodyPart(plain); + alternative.addBodyPart(html); + + Properties props = MessageHelper.getSessionProperties(Helper.AUTH_TYPE_PASSWORD, false); + Session isession = Session.getInstance(props, null); + MimeMessage imessage = new MimeMessage(isession); + imessage.setContent(alternative); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + imessage.writeTo(os); + ByteArrayInputStream decrypted = new ByteArrayInputStream(os.toByteArray()); + ByteArrayOutputStream encrypted = new ByteArrayOutputStream(); + + if (!pgpService.isBound()) + throw new IllegalArgumentException(getString(R.string.title_no_openpgp)); + + OpenPgpApi api = new OpenPgpApi(getContext(), pgpService.getService()); + Intent result = api.executeApi(data, decrypted, encrypted); + + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + EntityAttachment attachment1 = new EntityAttachment(); + EntityAttachment attachment2 = new EntityAttachment(); + + Intent keyRequest = new Intent(); + keyRequest.setAction(OpenPgpApi.ACTION_DETACHED_SIGN); + keyRequest.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, data.getLongExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, -1)); + Intent keyData = api.executeApi(keyRequest, decrypted, null); + int r = keyData.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + if (r != OpenPgpApi.RESULT_CODE_SUCCESS) { + OpenPgpError error = keyData.getParcelableExtra(OpenPgpApi.RESULT_ERROR); + throw new IllegalArgumentException(error.getMessage()); + } - try { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - new SimpleTask() { - @Override - protected Void onLoad(Context context, Bundle args) throws Throwable { - long id = args.getLong("id"); - EntityAttachment attachment1 = new EntityAttachment(); - EntityAttachment attachment2 = new EntityAttachment(); - - Intent keyRequest = new Intent(); - keyRequest.setAction(OpenPgpApi.ACTION_DETACHED_SIGN); - keyRequest.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, data.getLongExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, -1)); - Intent keyData = api.executeApi(keyRequest, msg, null); - int r = keyData.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - if (r != OpenPgpApi.RESULT_CODE_SUCCESS) { - OpenPgpError error = keyData.getParcelableExtra(OpenPgpApi.RESULT_ERROR); - throw new IllegalArgumentException(error.getMessage()); - } - - byte[] signature = keyData.getByteArrayExtra(OpenPgpApi.RESULT_DETACHED_SIGNATURE); - - DB db = DB.getInstance(context); - try { - db.beginTransaction(); - - int seq = db.attachment().getAttachmentCount(id); - - attachment1.message = id; - attachment1.sequence = seq + 1; - attachment1.name = "encrypted.asc"; - attachment1.type = "application/octet-stream"; - attachment1.id = db.attachment().insertAttachment(attachment1); - - File file1 = EntityAttachment.getFile(context, attachment1.id); - - OutputStream os1 = null; - try { - os1 = new BufferedOutputStream(new FileOutputStream(file1)); - byte[] data = encrypted.toByteArray(); - os1.write(data); - - attachment1.size = data.length; - attachment1.progress = null; - attachment1.available = true; - db.attachment().updateAttachment(attachment1); - } finally { - if (os1 != null) - os1.close(); - } - - attachment2.message = id; - attachment2.sequence = seq + 2; - attachment2.name = "signature.asc"; - attachment2.type = "application/octet-stream"; - attachment2.id = db.attachment().insertAttachment(attachment2); - - File file2 = EntityAttachment.getFile(context, attachment2.id); - - OutputStream os2 = null; - try { - os2 = new BufferedOutputStream(new FileOutputStream(file2)); - os2.write(signature); - - attachment2.size = signature.length; - attachment2.progress = null; - attachment2.available = true; - db.attachment().updateAttachment(attachment2); - } finally { - if (os2 != null) - os2.close(); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - return null; - } + byte[] signature = keyData.getByteArrayExtra(OpenPgpApi.RESULT_DETACHED_SIGNATURE); - @Override - protected void onException(Bundle args, Throwable ex) { - Helper.unexpectedError(getContext(), ex); - } - }.load(FragmentCompose.this, args); + DB db = DB.getInstance(context); + try { + db.beginTransaction(); + + int seq = db.attachment().getAttachmentCount(id); + + attachment1.message = id; + attachment1.sequence = seq + 1; + attachment1.name = "encrypted.asc"; + attachment1.type = "application/octet-stream"; + attachment1.id = db.attachment().insertAttachment(attachment1); + + File file1 = EntityAttachment.getFile(context, attachment1.id); + + OutputStream os1 = null; + try { + os1 = new BufferedOutputStream(new FileOutputStream(file1)); + byte[] bytes = encrypted.toByteArray(); + os1.write(bytes); + + attachment1.size = bytes.length; + attachment1.progress = null; + attachment1.available = true; + db.attachment().updateAttachment(attachment1); + } finally { + if (os1 != null) + os1.close(); + } - break; + attachment2.message = id; + attachment2.sequence = seq + 2; + attachment2.name = "signature.asc"; + attachment2.type = "application/octet-stream"; + attachment2.id = db.attachment().insertAttachment(attachment2); + + File file2 = EntityAttachment.getFile(context, attachment2.id); + + OutputStream os2 = null; + try { + os2 = new BufferedOutputStream(new FileOutputStream(file2)); + os2.write(signature); + + attachment2.size = signature.length; + attachment2.progress = null; + attachment2.available = true; + db.attachment().updateAttachment(attachment2); + } finally { + if (os2 != null) + os2.close(); + } - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); - startIntentSenderForResult( - pi.getIntentSender(), - ActivityCompose.REQUEST_ENCRYPT, - null, 0, 0, 0, null); - break; + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } - case OpenPgpApi.RESULT_CODE_ERROR: - OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); - throw new IllegalArgumentException(error.getMessage()); - } - } catch (Throwable ex) { - if (ex instanceof IllegalArgumentException) - Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); - else - Helper.unexpectedError(getContext(), ex); + break; + + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + return result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); + + case OpenPgpApi.RESULT_CODE_ERROR: + OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); + throw new IllegalArgumentException(error.getMessage()); } + + return null; } - }); + + @Override + protected void onLoaded(Bundle args, PendingIntent pi) { + if (pi != null) + try { + startIntentSenderForResult( + pi.getIntentSender(), + ActivityCompose.REQUEST_ENCRYPT, + null, 0, 0, 0, null); + } catch (IntentSender.SendIntentException ex) { + Helper.unexpectedError(getContext(), ex); + } + } + + @Override + protected void onException(Bundle args, Throwable ex) { + if (ex instanceof IllegalArgumentException) + Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); + else + Helper.unexpectedError(getContext(), ex); + } + }.load(this, args); } @Override @@ -646,16 +674,10 @@ public class FragmentCompose extends FragmentEx { if (data != null) handleAddAttachment(data, false); } else if (requestCode == ActivityCompose.REQUEST_ENCRYPT) { - if (data != null) - try { - data.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT); - encrypt(data); - } catch (Throwable ex) { - if (ex instanceof IllegalArgumentException) - Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); - else - Helper.unexpectedError(getContext(), ex); - } + if (data != null) { + data.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT); + encrypt(data); + } } else { if (data != null) handlePickContact(requestCode, data);