aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java52
-rw-r--r--src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java108
-rw-r--r--src/main/java/eu/siacs/conversations/utils/XmppUri.java79
-rw-r--r--src/main/res/layout/activity_verify_otr.xml10
-rw-r--r--src/main/res/menu/verify_otr.xml20
-rw-r--r--src/main/res/values/strings.xml3
6 files changed, 214 insertions, 58 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
index fe188737..21ca5153 100644
--- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
@@ -45,8 +45,6 @@ import android.widget.Spinner;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -59,10 +57,10 @@ import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.ListItem;
+import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
-import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.Validator;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -755,21 +753,17 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
}
- private class Invite {
+ private class Invite extends XmppUri {
private String jid;
private boolean muc;
private String fingerprint;
- Invite(Uri uri) {
- parse(uri);
+ public Invite(Uri uri) {
+ super(uri);
}
- Invite(String uri) {
- try {
- parse(Uri.parse(uri));
- } catch (IllegalArgumentException e) {
- jid = null;
- }
+ public Invite(String uri) {
+ super(uri);
}
boolean invite() {
@@ -782,39 +776,5 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
return false;
}
-
- void parse(Uri uri) {
- String scheme = uri.getScheme();
- if ("xmpp".equals(scheme)) {
- // sample: xmpp:jid@foo.com
- muc = "join".equalsIgnoreCase(uri.getQuery());
- if (uri.getAuthority() != null) {
- jid = uri.getAuthority();
- } else {
- jid = uri.getSchemeSpecificPart().split("\\?")[0];
- }
- fingerprint = parseFingerprint(uri.getQuery());
- } else if ("imto".equals(scheme)) {
- // sample: imto://xmpp/jid@foo.com
- try {
- jid = URLDecoder.decode(uri.getEncodedPath(), "UTF-8").split("/")[1];
- } catch (final UnsupportedEncodingException ignored) {
- }
- }
- }
-
- String parseFingerprint(String query) {
- if (query == null) {
- return null;
- } else {
- final String NEEDLE = "otr-fingerprint=";
- int index = query.indexOf(NEEDLE);
- if (index >= 0 && query.length() >= (NEEDLE.length() + index + 40)) {
- return CryptoHelper.prettifyFingerprint(query.substring(index + NEEDLE.length(), index + NEEDLE.length() + 40));
- } else {
- return null;
- }
- }
- }
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java
index bffc9743..233a5e99 100644
--- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java
@@ -1,7 +1,11 @@
package eu.siacs.conversations.ui;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
@@ -9,14 +13,19 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
import net.java.otr4j.OtrException;
import net.java.otr4j.session.Session;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
+import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -32,22 +41,40 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
private TextView mYourFingerprint;
private EditText mSharedSecretHint;
private EditText mSharedSecretSecret;
- private Button mButtonVerifyFingerprint;
+ private Button mButtonScanQrCode;
+ private Button mButtonShowQrCode;
private Button mButtonSharedSecretPositive;
private Button mButtonSharedSecretNegative;
private TextView mStatusMessage;
private Account mAccount;
private Conversation mConversation;
- private View.OnClickListener mVerifyFingerprintListener = new View.OnClickListener() {
+ private DialogInterface.OnClickListener mVerifyFingerprintListener = new DialogInterface.OnClickListener() {
@Override
- public void onClick(View view) {
+ public void onClick(DialogInterface dialogInterface, int click) {
mConversation.verifyOtrFingerprint();
- finish();
+ updateView();
+ xmppConnectionService.syncRosterToDisk(mConversation.getAccount());
}
};
+ private View.OnClickListener mShowQrCodeListener = new View.OnClickListener() {
+ @Override
+ public void onClick(final View view) {
+ showQrCode();
+ }
+ };
+
+ private View.OnClickListener mScanQrCodeListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ new IntentIntegrator(VerifyOTRActivity.this).initiateScan();
+ }
+
+ };
+
private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() {
@Override
public void onClick(final View view) {
@@ -97,6 +124,8 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
}
};
+ private XmppUri mPendingUri = null;
+
protected boolean initSmp(final String question, final String secret) {
final Session session = mConversation.getOtrSession();
if (session!=null) {
@@ -143,6 +172,18 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
}
}
+ protected void verifyWithUri(XmppUri uri) {
+ Contact contact = mConversation.getContact();
+ if (this.mConversation.getContact().getJid().equals(uri.getJid()) && uri.getFingerprint() != null) {
+ contact.addOtrFingerprint(uri.getFingerprint());
+ Toast.makeText(this,R.string.verified,Toast.LENGTH_SHORT).show();
+ updateView();
+ xmppConnectionService.syncRosterToDisk(contact.getAccount());
+ } else {
+ Toast.makeText(this,R.string.could_not_verify_fingerprint,Toast.LENGTH_SHORT).show();
+ }
+ }
+
protected boolean isAccountOnline() {
if (this.mAccount.getStatus() != Account.State.ONLINE) {
Toast.makeText(this,R.string.not_connected_try_again,Toast.LENGTH_SHORT).show();
@@ -174,14 +215,36 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
}
@Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if ((requestCode & 0xFFFF) == IntentIntegrator.REQUEST_CODE) {
+ IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+ if (scanResult != null && scanResult.getFormatName() != null) {
+ String data = scanResult.getContents();
+ XmppUri uri = new XmppUri(data);
+ if (xmppConnectionServiceBound) {
+ verifyWithUri(uri);
+ } else {
+ this.mPendingUri = uri;
+ }
+ }
+ }
+ super.onActivityResult(requestCode, requestCode, intent);
+ }
+
+ @Override
protected void onBackendConnected() {
if (handleIntent(getIntent())) {
+ if (mPendingUri!=null) {
+ verifyWithUri(mPendingUri);
+ mPendingUri = null;
+ }
updateView();
}
}
protected void updateView() {
if (this.mConversation.hasValidOtrSession()) {
+ invalidateOptionsMenu();
this.mVerificationAreaOne.setVisibility(View.VISIBLE);
this.mVerificationAreaTwo.setVisibility(View.VISIBLE);
this.mErrorNoSession.setVisibility(View.GONE);
@@ -191,9 +254,9 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
Conversation.Smp smp = mConversation.smp();
Session session = mConversation.getOtrSession();
if (mConversation.isOtrFingerprintVerified()) {
- deactivateButton(mButtonVerifyFingerprint, R.string.verified);
+ deactivateButton(mButtonScanQrCode, R.string.verified);
} else {
- activateButton(mButtonVerifyFingerprint, R.string.verify, mVerifyFingerprintListener);
+ activateButton(mButtonScanQrCode, R.string.scan_qr_code, mScanQrCodeListener);
}
if (smp.status == Conversation.Smp.STATUS_NONE) {
activateButton(mButtonSharedSecretPositive, R.string.create, mCreateSharedSecretListener);
@@ -268,7 +331,9 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
this.mYourFingerprint = (TextView) findViewById(R.id.your_fingerprint);
this.mButtonSharedSecretNegative = (Button) findViewById(R.id.button_shared_secret_negative);
this.mButtonSharedSecretPositive = (Button) findViewById(R.id.button_shared_secret_positive);
- this.mButtonVerifyFingerprint = (Button) findViewById(R.id.button_verify_fingerprint);
+ this.mButtonScanQrCode = (Button) findViewById(R.id.button_scan_qr_code);
+ this.mButtonShowQrCode = (Button) findViewById(R.id.button_show_qr_code);
+ this.mButtonShowQrCode.setOnClickListener(this.mShowQrCodeListener);
this.mSharedSecretSecret = (EditText) findViewById(R.id.shared_secret_secret);
this.mSharedSecretHint = (EditText) findViewById(R.id.shared_secret_hint);
this.mStatusMessage= (TextView) findViewById(R.id.status_message);
@@ -278,6 +343,35 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
}
@Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.verify_otr, menu);
+ if (mConversation != null && mConversation.isOtrFingerprintVerified()) {
+ MenuItem manuallyVerifyItem = menu.findItem(R.id.manually_verify);
+ manuallyVerifyItem.setVisible(false);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem menuItem) {
+ if (menuItem.getItemId() == R.id.manually_verify) {
+ showManuallyVerifyDialog();
+ return true;
+ } else {
+ return super.onOptionsItemSelected(menuItem);
+ }
+ }
+
+ private void showManuallyVerifyDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.manually_verify);
+ builder.setMessage(R.string.are_you_sure_verify_fingerprint);
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.setPositiveButton(R.string.verify, mVerifyFingerprintListener);
+ builder.create().show();
+ }
+
+ @Override
protected String getShareableUri() {
if (mAccount!=null) {
return mAccount.getShareableUri();
diff --git a/src/main/java/eu/siacs/conversations/utils/XmppUri.java b/src/main/java/eu/siacs/conversations/utils/XmppUri.java
new file mode 100644
index 00000000..09abd049
--- /dev/null
+++ b/src/main/java/eu/siacs/conversations/utils/XmppUri.java
@@ -0,0 +1,79 @@
+package eu.siacs.conversations.utils;
+
+import android.net.Uri;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import eu.siacs.conversations.utils.CryptoHelper;
+import eu.siacs.conversations.xmpp.jid.InvalidJidException;
+import eu.siacs.conversations.xmpp.jid.Jid;
+
+public class XmppUri {
+
+ private String jid;
+ private boolean muc;
+ private String fingerprint;
+
+ public XmppUri(String uri) {
+ try {
+ parse(Uri.parse(uri));
+ } catch (IllegalArgumentException e) {
+ jid = null;
+ }
+ }
+
+ public XmppUri(Uri uri) {
+ parse(uri);
+ }
+
+ protected void parse(Uri uri) {
+ String scheme = uri.getScheme();
+ if ("xmpp".equals(scheme)) {
+ // sample: xmpp:jid@foo.com
+ muc = "join".equalsIgnoreCase(uri.getQuery());
+ if (uri.getAuthority() != null) {
+ jid = uri.getAuthority();
+ } else {
+ jid = uri.getSchemeSpecificPart().split("\\?")[0];
+ }
+ fingerprint = parseFingerprint(uri.getQuery());
+ } else if ("imto".equals(scheme)) {
+ // sample: imto://xmpp/jid@foo.com
+ try {
+ jid = URLDecoder.decode(uri.getEncodedPath(), "UTF-8").split("/")[1];
+ } catch (final UnsupportedEncodingException ignored) {
+ }
+ }
+ }
+
+ protected String parseFingerprint(String query) {
+ if (query == null) {
+ return null;
+ } else {
+ final String NEEDLE = "otr-fingerprint=";
+ int index = query.indexOf(NEEDLE);
+ if (index >= 0 && query.length() >= (NEEDLE.length() + index + 40)) {
+ return CryptoHelper.prettifyFingerprint(query.substring(index + NEEDLE.length(), index + NEEDLE.length() + 40));
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public Jid getJid() {
+ try {
+ return Jid.fromString(this.jid);
+ } catch (InvalidJidException e) {
+ return null;
+ }
+ }
+
+ public String getFingerprint() {
+ return this.fingerprint;
+ }
+
+ public boolean isMuc() {
+ return this.muc;
+ }
+}
diff --git a/src/main/res/layout/activity_verify_otr.xml b/src/main/res/layout/activity_verify_otr.xml
index d907d871..73539e0e 100644
--- a/src/main/res/layout/activity_verify_otr.xml
+++ b/src/main/res/layout/activity_verify_otr.xml
@@ -76,27 +76,27 @@
android:layout_alignParentRight="true" >
<Button
+ android:id="@+id/button_show_qr_code"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:visibility="invisible" />
+ android:text="@string/show_qr_code"/>
<View
android:layout_width="1dp"
android:layout_height="fill_parent"
android:layout_marginBottom="7dp"
android:layout_marginTop="7dp"
- android:background="@color/divider"
- android:visibility="invisible"/>
+ android:background="@color/divider" />
<Button
- android:id="@+id/button_verify_fingerprint"
+ android:id="@+id/button_scan_qr_code"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:text="@string/verify"
+ android:text="@string/scan_qr_code"
android:textColor="@color/primarytext" />
</LinearLayout>
</RelativeLayout>
diff --git a/src/main/res/menu/verify_otr.xml b/src/main/res/menu/verify_otr.xml
new file mode 100644
index 00000000..1d4a11b6
--- /dev/null
+++ b/src/main/res/menu/verify_otr.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/manually_verify"
+ android:orderInCategory="10"
+ android:showAsAction="never"
+ android:title="@string/manually_verify" />
+
+ <item
+ android:id="@+id/action_accounts"
+ android:orderInCategory="90"
+ android:showAsAction="never"
+ android:title="@string/action_accounts" />
+ <item
+ android:id="@+id/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never"
+ android:title="@string/action_settings" />
+</menu> \ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index db9f95d4..2912d895 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -346,4 +346,7 @@
<string name="file_transmission_failed">file transmission failed</string>
<string name="file_deleted">The file has been deleted</string>
<string name="no_application_found_to_open_file">No application found to open file</string>
+ <string name="could_not_verify_fingerprint">Could not verify fingerprint</string>
+ <string name="manually_verify">Manually verify</string>
+ <string name="are_you_sure_verify_fingerprint">Are you sure that you want to verify your contacts OTR fingerprint?</string>
</resources>