made scan and show qr code more accessible in VerifyOtrActivity

This commit is contained in:
iNPUTmice 2014-11-16 02:10:29 +01:00
parent 2b21bc13fc
commit 2067b9bd8d
6 changed files with 214 additions and 58 deletions

View file

@ -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;
}
}
}
}
}

View file

@ -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,20 +41,38 @@ 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(DialogInterface dialogInterface, int click) {
mConversation.verifyOtrFingerprint();
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) {
mConversation.verifyOtrFingerprint();
finish();
new IntentIntegrator(VerifyOTRActivity.this).initiateScan();
}
};
private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() {
@ -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();
@ -173,15 +214,37 @@ 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);
@ -277,6 +342,35 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
this.mErrorNoSession = (TextView) findViewById(R.id.error_no_session);
}
@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) {

View file

@ -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;
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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>