encode and decode % and # in invite links

This commit is contained in:
Daniel Gultsch 2018-05-04 12:18:31 +02:00
parent 9b73029267
commit 77fc8d2d9e
4 changed files with 78 additions and 69 deletions

View File

@ -6,9 +6,6 @@ import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.PgpDecryptionService;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -19,7 +16,9 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.PgpDecryptionService;
import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
@ -95,7 +94,7 @@ public class Account extends AbstractEntity {
public boolean setShowErrorNotification(boolean newValue) { public boolean setShowErrorNotification(boolean newValue) {
boolean oldValue = showErrorNotification(); boolean oldValue = showErrorNotification();
setKey("show_error",Boolean.toString(newValue)); setKey("show_error", Boolean.toString(newValue));
return newValue != oldValue; return newValue != oldValue;
} }
@ -109,7 +108,7 @@ public class Account extends AbstractEntity {
} }
public enum State { public enum State {
DISABLED(false,false), DISABLED(false, false),
OFFLINE(false), OFFLINE(false),
CONNECTING(false), CONNECTING(false),
ONLINE(false), ONLINE(false),
@ -117,12 +116,12 @@ public class Account extends AbstractEntity {
UNAUTHORIZED, UNAUTHORIZED,
SERVER_NOT_FOUND, SERVER_NOT_FOUND,
REGISTRATION_SUCCESSFUL(false), REGISTRATION_SUCCESSFUL(false),
REGISTRATION_FAILED(true,false), REGISTRATION_FAILED(true, false),
REGISTRATION_WEB(true,false), REGISTRATION_WEB(true, false),
REGISTRATION_CONFLICT(true,false), REGISTRATION_CONFLICT(true, false),
REGISTRATION_NOT_SUPPORTED(true,false), REGISTRATION_NOT_SUPPORTED(true, false),
REGISTRATION_PLEASE_WAIT(true,false), REGISTRATION_PLEASE_WAIT(true, false),
REGISTRATION_PASSWORD_TOO_WEAK(true,false), REGISTRATION_PASSWORD_TOO_WEAK(true, false),
TLS_ERROR, TLS_ERROR,
INCOMPATIBLE_SERVER, INCOMPATIBLE_SERVER,
TOR_NOT_AVAILABLE, TOR_NOT_AVAILABLE,
@ -148,7 +147,7 @@ public class Account extends AbstractEntity {
} }
State(final boolean isError) { State(final boolean isError) {
this(isError,true); this(isError, true);
} }
State(final boolean isError, final boolean reconnect) { State(final boolean isError, final boolean reconnect) {
@ -157,7 +156,7 @@ public class Account extends AbstractEntity {
} }
State() { State() {
this(true,true); this(true, true);
} }
public int getReadableId() { public int getReadableId() {
@ -254,9 +253,9 @@ public class Account extends AbstractEntity {
} }
private Account(final String uuid, final Jid jid, private Account(final String uuid, final Jid jid,
final String password, final int options, final String rosterVersion, final String keys, final String password, final int options, final String rosterVersion, final String keys,
final String avatar, String displayName, String hostname, int port, final String avatar, String displayName, String hostname, int port,
final Presence.Status status, String statusMessage) { final Presence.Status status, String statusMessage) {
this.uuid = uuid; this.uuid = uuid;
this.jid = jid; this.jid = jid;
this.password = password; this.password = password;
@ -265,7 +264,7 @@ public class Account extends AbstractEntity {
JSONObject tmp; JSONObject tmp;
try { try {
tmp = new JSONObject(keys); tmp = new JSONObject(keys);
} catch(JSONException e) { } catch (JSONException e) {
tmp = new JSONObject(); tmp = new JSONObject();
} }
this.keys = tmp; this.keys = tmp;
@ -286,7 +285,7 @@ public class Account extends AbstractEntity {
cursor.getString(cursor.getColumnIndex(SERVER)), cursor.getString(cursor.getColumnIndex(SERVER)),
resource == null || resource.trim().isEmpty() ? null : resource); resource == null || resource.trim().isEmpty() ? null : resource);
} catch (final IllegalArgumentException ignored) { } catch (final IllegalArgumentException ignored) {
Log.d(Config.LOGTAG,cursor.getString(cursor.getColumnIndex(USERNAME))+"@"+cursor.getString(cursor.getColumnIndex(SERVER))); Log.d(Config.LOGTAG, cursor.getString(cursor.getColumnIndex(USERNAME)) + "@" + cursor.getString(cursor.getColumnIndex(SERVER)));
throw new AssertionError(ignored); throw new AssertionError(ignored);
} }
return new Account(cursor.getString(cursor.getColumnIndex(UUID)), return new Account(cursor.getString(cursor.getColumnIndex(UUID)),
@ -480,7 +479,7 @@ public class Account extends AbstractEntity {
values.put(PORT, port); values.put(PORT, port);
values.put(STATUS, presenceStatus.toShowString()); values.put(STATUS, presenceStatus.toShowString());
values.put(STATUS_MESSAGE, presenceStatusMessage); values.put(STATUS_MESSAGE, presenceStatusMessage);
values.put(RESOURCE,jid.getResource()); values.put(RESOURCE, jid.getResource());
return values; return values;
} }
@ -584,7 +583,7 @@ public class Account extends AbstractEntity {
} }
public Bookmark getBookmark(final Jid jid) { public Bookmark getBookmark(final Jid jid) {
for(final Bookmark bookmark : this.bookmarks) { for (final Bookmark bookmark : this.bookmarks) {
if (bookmark.getJid() != null && jid.asBareJid().equals(bookmark.getJid().asBareJid())) { if (bookmark.getJid() != null && jid.asBareJid().equals(bookmark.getJid().asBareJid())) {
return bookmark; return bookmark;
} }
@ -619,9 +618,9 @@ public class Account extends AbstractEntity {
public String getShareableUri() { public String getShareableUri() {
List<XmppUri.Fingerprint> fingerprints = this.getFingerprints(); List<XmppUri.Fingerprint> fingerprints = this.getFingerprints();
String uri = "xmpp:"+this.getJid().asBareJid().toEscapedString(); String uri = "xmpp:" + this.getJid().asBareJid().toEscapedString();
if (fingerprints.size() > 0) { if (fingerprints.size() > 0) {
return XmppUri.getFingerprintUri(uri,fingerprints,';'); return XmppUri.getFingerprintUri(uri, fingerprints, ';');
} else { } else {
return uri; return uri;
} }
@ -629,9 +628,9 @@ public class Account extends AbstractEntity {
public String getShareableLink() { public String getShareableLink() {
List<XmppUri.Fingerprint> fingerprints = this.getFingerprints(); List<XmppUri.Fingerprint> fingerprints = this.getFingerprints();
String uri = "https://conversations.im/i/"+this.getJid().asBareJid().toEscapedString(); String uri = "https://conversations.im/i/" + XmppUri.lameUrlEncode(this.getJid().asBareJid().toEscapedString());
if (fingerprints.size() > 0) { if (fingerprints.size() > 0) {
return XmppUri.getFingerprintUri(uri,fingerprints,'&'); return XmppUri.getFingerprintUri(uri, fingerprints, '&');
} else { } else {
return uri; return uri;
} }
@ -642,10 +641,10 @@ public class Account extends AbstractEntity {
if (axolotlService == null) { if (axolotlService == null) {
return fingerprints; return fingerprints;
} }
fingerprints.add(new XmppUri.Fingerprint(XmppUri.FingerprintType.OMEMO,axolotlService.getOwnFingerprint().substring(2),axolotlService.getOwnDeviceId())); fingerprints.add(new XmppUri.Fingerprint(XmppUri.FingerprintType.OMEMO, axolotlService.getOwnFingerprint().substring(2), axolotlService.getOwnDeviceId()));
for(XmppAxolotlSession session : axolotlService.findOwnSessions()) { for (XmppAxolotlSession session : axolotlService.findOwnSessions()) {
if (session.getTrust().isVerified() && session.getTrust().isActive()) { if (session.getTrust().isVerified() && session.getTrust().isActive()) {
fingerprints.add(new XmppUri.Fingerprint(XmppUri.FingerprintType.OMEMO,session.getFingerprint().substring(2).replaceAll("\\s",""),session.getRemoteAddress().getDeviceId())); fingerprints.add(new XmppUri.Fingerprint(XmppUri.FingerprintType.OMEMO, session.getFingerprint().substring(2).replaceAll("\\s", ""), session.getRemoteAddress().getDeviceId()));
} }
} }
return fingerprints; return fingerprints;

View File

@ -45,6 +45,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat
import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate;
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.XmppUri;
import rocks.xmpp.addr.Jid; import rocks.xmpp.addr.Jid;
public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConfigurationPushed { public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConfigurationPushed {
@ -298,7 +299,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
protected String getShareableUri(boolean http) { protected String getShareableUri(boolean http) {
if (mConversation != null) { if (mConversation != null) {
if (http) { if (http) {
return "https://conversations.im/j/" + mConversation.getJid().asBareJid().toEscapedString(); return "https://conversations.im/j/" + XmppUri.lameUrlEncode(mConversation.getJid().asBareJid().toEscapedString());
} else { } else {
return "xmpp:" + mConversation.getJid().asBareJid() + "?join"; return "xmpp:" + mConversation.getJid().asBareJid() + "?join";
} }

View File

@ -10,7 +10,6 @@ import android.preference.PreferenceManager;
import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.Intents;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -63,14 +62,14 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) { boolean isChecked) {
if (isChecked) { if (isChecked) {
if (contact if (contact
.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
xmppConnectionService.sendPresencePacket(contact xmppConnectionService.sendPresencePacket(contact
.getAccount(), .getAccount(),
xmppConnectionService.getPresenceGenerator() xmppConnectionService.getPresenceGenerator()
.sendPresenceUpdatesTo(contact)); .sendPresenceUpdatesTo(contact));
} else { } else {
contact.setOption(Contact.Options.PREEMPTIVE_GRANT); contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
} }
@ -78,7 +77,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
xmppConnectionService.sendPresencePacket(contact.getAccount(), xmppConnectionService.sendPresencePacket(contact.getAccount(),
xmppConnectionService.getPresenceGenerator() xmppConnectionService.getPresenceGenerator()
.stopPresenceUpdatesTo(contact)); .stopPresenceUpdatesTo(contact));
} }
} }
}; };
@ -86,15 +85,15 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) { boolean isChecked) {
if (isChecked) { if (isChecked) {
xmppConnectionService.sendPresencePacket(contact.getAccount(), xmppConnectionService.sendPresencePacket(contact.getAccount(),
xmppConnectionService.getPresenceGenerator() xmppConnectionService.getPresenceGenerator()
.requestPresenceUpdatesFrom(contact)); .requestPresenceUpdatesFrom(contact));
} else { } else {
xmppConnectionService.sendPresencePacket(contact.getAccount(), xmppConnectionService.sendPresencePacket(contact.getAccount(),
xmppConnectionService.getPresenceGenerator() xmppConnectionService.getPresenceGenerator()
.stopPresenceUpdatesFrom(contact)); .stopPresenceUpdatesFrom(contact));
} }
} }
}; };
@ -163,18 +162,17 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override @Override
protected String getShareableUri(boolean http) { protected String getShareableUri(boolean http) {
final String prefix = http ? "https://conversations.im/i/" : "xmpp:"; if (http) {
if (contact != null) { return "https://conversations.im/j/" + XmppUri.lameUrlEncode(contact.getJid().asBareJid().toEscapedString());
return prefix+contact.getJid().asBareJid().toEscapedString();
} else { } else {
return ""; return "xmpp:" + contact.getJid().asBareJid().toEscapedString();
} }
} }
@Override @Override
protected void onCreate(final Bundle savedInstanceState) { protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
showInactiveOmemo = savedInstanceState != null && savedInstanceState.getBoolean("show_inactive_omemo",false); showInactiveOmemo = savedInstanceState != null && savedInstanceState.getBoolean("show_inactive_omemo", false);
if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) { if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
try { try {
this.accountJid = Jid.of(getIntent().getExtras().getString(EXTRA_ACCOUNT)); this.accountJid = Jid.of(getIntent().getExtras().getString(EXTRA_ACCOUNT));
@ -199,7 +197,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override @Override
public void onSaveInstanceState(final Bundle savedInstanceState) { public void onSaveInstanceState(final Bundle savedInstanceState) {
savedInstanceState.putBoolean("show_inactive_omemo",showInactiveOmemo); savedInstanceState.putBoolean("show_inactive_omemo", showInactiveOmemo);
super.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState);
} }
@ -235,9 +233,9 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
break; break;
case R.id.action_delete_contact: case R.id.action_delete_contact:
builder.setTitle(getString(R.string.action_delete_contact)) builder.setTitle(getString(R.string.action_delete_contact))
.setMessage(getString(R.string.remove_contact_text, contact.getJid().toString())) .setMessage(getString(R.string.remove_contact_text, contact.getJid().toString()))
.setPositiveButton(getString(R.string.delete), .setPositiveButton(getString(R.string.delete),
removeFromRoster).create().show(); removeFromRoster).create().show();
break; break;
case R.id.action_edit_contact: case R.id.action_edit_contact:
Uri systemAccount = contact.getSystemAccount(); Uri systemAccount = contact.getSystemAccount();
@ -317,7 +315,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
binding.statusMessage.setVisibility(View.VISIBLE); binding.statusMessage.setVisibility(View.VISIBLE);
int s = statusMessages.size(); int s = statusMessages.size();
for(int i = 0; i < s; ++i) { for (int i = 0; i < s; ++i) {
if (s > 1) { if (s > 1) {
builder.append(""); builder.append("");
} }
@ -384,7 +382,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} }
} }
binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this,contact.getJid())); binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this, contact.getJid()));
String account; String account;
if (Config.DOMAIN_LOCK != null) { if (Config.DOMAIN_LOCK != null) {
account = contact.getAccount().getJid().getLocal(); account = contact.getAccount().getJid().getLocal();
@ -429,7 +427,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} }
binding.scanButton.setVisibility(hasKeys && isCameraFeatureAvailable() ? View.VISIBLE : View.GONE); binding.scanButton.setVisibility(hasKeys && isCameraFeatureAvailable() ? View.VISIBLE : View.GONE);
if (hasKeys) { if (hasKeys) {
binding.scanButton.setOnClickListener((v)-> ScanActivity.scan(this)); binding.scanButton.setOnClickListener((v) -> ScanActivity.scan(this));
} }
if (Config.supportOpenPgp() && contact.getPgpKeyId() != 0) { if (Config.supportOpenPgp() && contact.getPgpKeyId() != 0) {
hasKeys = true; hasKeys = true;
@ -455,8 +453,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} else { } else {
binding.tags.setVisibility(View.VISIBLE); binding.tags.setVisibility(View.VISIBLE);
binding.tags.removeAllViewsInLayout(); binding.tags.removeAllViewsInLayout();
for(final ListItem.Tag tag : tagList) { for (final ListItem.Tag tag : tagList) {
final TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag,binding.tags,false); final TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag, binding.tags, false);
tv.setText(tag.getName()); tv.setText(tag.getName());
tv.setBackgroundColor(tag.getColor()); tv.setBackgroundColor(tag.getColor());
binding.tags.addView(tv); binding.tags.addView(tv);
@ -487,11 +485,11 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override @Override
protected void processFingerprintVerification(XmppUri uri) { protected void processFingerprintVerification(XmppUri uri) {
if (contact != null && contact.getJid().asBareJid().equals(uri.getJid()) && uri.hasFingerprints()) { if (contact != null && contact.getJid().asBareJid().equals(uri.getJid()) && uri.hasFingerprints()) {
if (xmppConnectionService.verifyFingerprints(contact,uri.getFingerprints())) { if (xmppConnectionService.verifyFingerprints(contact, uri.getFingerprints())) {
Toast.makeText(this,R.string.verified_fingerprints,Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.verified_fingerprints, Toast.LENGTH_SHORT).show();
} }
} else { } else {
Toast.makeText(this,R.string.invalid_barcode,Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.invalid_barcode, Toast.LENGTH_SHORT).show();
} }
} }
} }

View File

@ -1,6 +1,7 @@
package eu.siacs.conversations.utils; package eu.siacs.conversations.utils;
import android.net.Uri; import android.net.Uri;
import android.util.Log;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
@ -8,6 +9,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import eu.siacs.conversations.Config;
import rocks.xmpp.addr.Jid; import rocks.xmpp.addr.Jid;
public class XmppUri { public class XmppUri {
@ -21,7 +23,6 @@ public class XmppUri {
protected boolean safeSource = true; protected boolean safeSource = true;
public static final String OMEMO_URI_PARAM = "omemo-sid-"; public static final String OMEMO_URI_PARAM = "omemo-sid-";
public static final String OTR_URI_PARAM = "otr-fingerprint";
public static final String ACTION_JOIN = "join"; public static final String ACTION_JOIN = "join";
public static final String ACTION_MESSAGE = "message"; public static final String ACTION_MESSAGE = "message";
@ -60,8 +61,9 @@ public class XmppUri {
if (segments.size() >= 2 && segments.get(1).contains("@")) { if (segments.size() >= 2 && segments.get(1).contains("@")) {
// sample : https://conversations.im/i/foo@bar.com // sample : https://conversations.im/i/foo@bar.com
try { try {
jid = Jid.of(segments.get(1)).toString(); jid = Jid.of(lameUrlDecode(segments.get(1))).toString();
} catch (Exception e) { } catch (Exception e) {
Log.d(Config.LOGTAG, "parsing failed ", e);
jid = null; jid = null;
} }
} else if (segments.size() >= 3) { } else if (segments.size() >= 3) {
@ -71,7 +73,7 @@ public class XmppUri {
if (segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0))) { if (segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0))) {
action = ACTION_JOIN; action = ACTION_JOIN;
} }
fingerprints = parseFingerprints(uri.getQuery(),'&'); fingerprints = parseFingerprints(uri.getQuery(), '&');
} else if ("xmpp".equalsIgnoreCase(scheme)) { } else if ("xmpp".equalsIgnoreCase(scheme)) {
// sample: xmpp:foo@bar.com // sample: xmpp:foo@bar.com
@ -120,21 +122,21 @@ public class XmppUri {
} }
protected List<Fingerprint> parseFingerprints(String query) { protected List<Fingerprint> parseFingerprints(String query) {
return parseFingerprints(query,';'); return parseFingerprints(query, ';');
} }
protected List<Fingerprint> parseFingerprints(String query, char seperator) { protected List<Fingerprint> parseFingerprints(String query, char seperator) {
List<Fingerprint> fingerprints = new ArrayList<>(); List<Fingerprint> fingerprints = new ArrayList<>();
String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator)); String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator));
for(String pair : pairs) { for (String pair : pairs) {
String[] parts = pair.split("=",2); String[] parts = pair.split("=", 2);
if (parts.length == 2) { if (parts.length == 2) {
String key = parts[0].toLowerCase(Locale.US); String key = parts[0].toLowerCase(Locale.US);
String value = parts[1].toLowerCase(Locale.US); String value = parts[1].toLowerCase(Locale.US);
if (key.startsWith(OMEMO_URI_PARAM)) { if (key.startsWith(OMEMO_URI_PARAM)) {
try { try {
int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length())); int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length()));
fingerprints.add(new Fingerprint(FingerprintType.OMEMO,value,id)); fingerprints.add(new Fingerprint(FingerprintType.OMEMO, value, id));
} catch (Exception e) { } catch (Exception e) {
//ignoring invalid device id //ignoring invalid device id
} }
@ -145,11 +147,11 @@ public class XmppUri {
} }
protected String parseParameter(String key, String query) { protected String parseParameter(String key, String query) {
for(String pair : query == null ? new String[0] : query.split(";")) { for (String pair : query == null ? new String[0] : query.split(";")) {
final String[] parts = pair.split("=",2); final String[] parts = pair.split("=", 2);
if (parts.length == 2 && key.equals(parts[0].toLowerCase(Locale.US))) { if (parts.length == 2 && key.equals(parts[0].toLowerCase(Locale.US))) {
try { try {
return URLDecoder.decode(parts[1],"UTF-8"); return URLDecoder.decode(parts[1], "UTF-8");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
return null; return null;
} }
@ -159,8 +161,8 @@ public class XmppUri {
} }
private boolean hasAction(String query, String action) { private boolean hasAction(String query, String action) {
for(String pair : query == null ? new String[0] : query.split(";")) { for (String pair : query == null ? new String[0] : query.split(";")) {
final String[] parts = pair.split("=",2); final String[] parts = pair.split("=", 2);
if (parts.length == 1 && parts[0].equals(action)) { if (parts.length == 1 && parts[0].equals(action)) {
return true; return true;
} }
@ -178,7 +180,7 @@ public class XmppUri {
public Jid getJid() { public Jid getJid() {
try { try {
return this.jid == null ? null :Jid.of(this.jid.toLowerCase()); return this.jid == null ? null : Jid.of(this.jid.toLowerCase());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
return null; return null;
} }
@ -211,6 +213,7 @@ public class XmppUri {
public boolean hasFingerprints() { public boolean hasFingerprints() {
return fingerprints.size() > 0; return fingerprints.size() > 0;
} }
public enum FingerprintType { public enum FingerprintType {
OMEMO OMEMO
} }
@ -218,7 +221,7 @@ public class XmppUri {
public static String getFingerprintUri(String base, List<XmppUri.Fingerprint> fingerprints, char seperator) { public static String getFingerprintUri(String base, List<XmppUri.Fingerprint> fingerprints, char seperator) {
StringBuilder builder = new StringBuilder(base); StringBuilder builder = new StringBuilder(base);
builder.append('?'); builder.append('?');
for(int i = 0; i < fingerprints.size(); ++i) { for (int i = 0; i < fingerprints.size(); ++i) {
XmppUri.FingerprintType type = fingerprints.get(i).type; XmppUri.FingerprintType type = fingerprints.get(i).type;
if (type == XmppUri.FingerprintType.OMEMO) { if (type == XmppUri.FingerprintType.OMEMO) {
builder.append(XmppUri.OMEMO_URI_PARAM); builder.append(XmppUri.OMEMO_URI_PARAM);
@ -226,7 +229,7 @@ public class XmppUri {
} }
builder.append('='); builder.append('=');
builder.append(fingerprints.get(i).fingerprint); builder.append(fingerprints.get(i).fingerprint);
if (i != fingerprints.size() -1) { if (i != fingerprints.size() - 1) {
builder.append(seperator); builder.append(seperator);
} }
} }
@ -250,7 +253,15 @@ public class XmppUri {
@Override @Override
public String toString() { public String toString() {
return type.toString()+": "+fingerprint+(deviceId != 0 ? " "+String.valueOf(deviceId) : ""); return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + String.valueOf(deviceId) : "");
} }
} }
public static String lameUrlDecode(String url) {
return url.replace("%23", "#").replace("%25", "%");
}
public static String lameUrlEncode(String url) {
return url.replace("%", "%25").replace("#", "%23");
}
} }