bump reporting xep and add ability to report messages

This commit is contained in:
Daniel Gultsch 2023-11-12 16:11:11 +01:00
parent 60dd710d43
commit 38ca53fcac
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
10 changed files with 69 additions and 11 deletions

View file

@ -375,7 +375,7 @@
<xmpp:SupportedXep> <xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0377.html"/> <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0377.html"/>
<xmpp:status>complete</xmpp:status> <xmpp:status>complete</xmpp:status>
<xmpp:version>0.2</xmpp:version> <xmpp:version>0.3.1</xmpp:version>
</xmpp:SupportedXep> </xmpp:SupportedXep>
</implements> </implements>
<implements> <implements>

View file

@ -344,12 +344,18 @@ public class IqGenerator extends AbstractGenerator {
return iq; return iq;
} }
public IqPacket generateSetBlockRequest(final Jid jid, boolean reportSpam) { public IqPacket generateSetBlockRequest(final Jid jid, final boolean reportSpam, final String serverMsgId) {
final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
final Element block = iq.addChild("block", Namespace.BLOCKING); final Element block = iq.addChild("block", Namespace.BLOCKING);
final Element item = block.addChild("item").setAttribute("jid", jid); final Element item = block.addChild("item").setAttribute("jid", jid);
if (reportSpam) { if (reportSpam) {
item.addChild("report", "urn:xmpp:reporting:0").addChild("spam"); final Element report = item.addChild("report", Namespace.REPORTING);
report.setAttribute("reason", Namespace.REPORTING_REASON_SPAM);
if (serverMsgId != null) {
final Element stanzaId = report.addChild("stanza-id", Namespace.STANZA_IDS);
stanzaId.setAttribute("by", jid);
stanzaId.setAttribute("id", serverMsgId);
}
} }
Log.d(Config.LOGTAG, iq.toString()); Log.d(Config.LOGTAG, iq.toString());
return iq; return iq;

View file

@ -4756,10 +4756,10 @@ public class XmppConnectionService extends Service {
mDatabaseWriterExecutor.execute(runnable); mDatabaseWriterExecutor.execute(runnable);
} }
public boolean sendBlockRequest(final Blockable blockable, boolean reportSpam) { public boolean sendBlockRequest(final Blockable blockable, final boolean reportSpam, final String serverMsgId) {
if (blockable != null && blockable.getBlockedJid() != null) { if (blockable != null && blockable.getBlockedJid() != null) {
final Jid jid = blockable.getBlockedJid(); final Jid jid = blockable.getBlockedJid();
this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetBlockRequest(jid, reportSpam), (a, response) -> { this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetBlockRequest(jid, reportSpam, serverMsgId), (a, response) -> {
if (response.getType() == IqPacket.TYPE.RESULT) { if (response.getType() == IqPacket.TYPE.RESULT) {
a.getBlocklist().add(jid); a.getBlocklist().add(jid);
updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED); updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED);

View file

@ -14,13 +14,27 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.ui.util.JidDialog; import eu.siacs.conversations.ui.util.JidDialog;
public final class BlockContactDialog { public final class BlockContactDialog {
public static void show(final XmppActivity xmppActivity, final Blockable blockable) { public static void show(final XmppActivity xmppActivity, final Blockable blockable) {
show(xmppActivity, blockable, null);
}
public static void show(final XmppActivity xmppActivity, final Blockable blockable, final String serverMsgId) {
final AlertDialog.Builder builder = new AlertDialog.Builder(xmppActivity); final AlertDialog.Builder builder = new AlertDialog.Builder(xmppActivity);
final boolean isBlocked = blockable.isBlocked(); final boolean isBlocked = blockable.isBlocked();
builder.setNegativeButton(R.string.cancel, null); builder.setNegativeButton(R.string.cancel, null);
DialogBlockContactBinding binding = DataBindingUtil.inflate(xmppActivity.getLayoutInflater(), R.layout.dialog_block_contact, null, false); DialogBlockContactBinding binding = DataBindingUtil.inflate(xmppActivity.getLayoutInflater(), R.layout.dialog_block_contact, null, false);
final boolean reporting = blockable.getAccount().getXmppConnection().getFeatures().spamReporting(); final boolean reporting = blockable.getAccount().getXmppConnection().getFeatures().spamReporting();
binding.reportSpam.setVisibility(!isBlocked && reporting ? View.VISIBLE : View.GONE); if (reporting && !isBlocked) {
binding.reportSpam.setVisibility(View.VISIBLE);
if (serverMsgId != null) {
binding.reportSpam.setChecked(true);
binding.reportSpam.setEnabled(false);
} else {
binding.reportSpam.setEnabled(true);
}
} else {
binding.reportSpam.setVisibility(View.GONE);
}
builder.setView(binding.getRoot()); builder.setView(binding.getRoot());
final String value; final String value;
@ -34,8 +48,18 @@ public final class BlockContactDialog {
value =blockable.getJid().getDomain().toEscapedString(); value =blockable.getJid().getDomain().toEscapedString();
res = isBlocked ? R.string.unblock_domain_text : R.string.block_domain_text; res = isBlocked ? R.string.unblock_domain_text : R.string.block_domain_text;
} else { } else {
int resBlockAction = blockable instanceof Conversation && ((Conversation) blockable).isWithStranger() ? R.string.block_stranger : R.string.action_block_contact; if (isBlocked) {
builder.setTitle(isBlocked ? R.string.action_unblock_contact : resBlockAction); builder.setTitle(R.string.action_unblock_contact);
} else if (serverMsgId != null) {
builder.setTitle(R.string.report_spam_and_block);
} else {
final int resBlockAction =
blockable instanceof Conversation
&& ((Conversation) blockable).isWithStranger()
? R.string.block_stranger
: R.string.action_block_contact;
builder.setTitle(resBlockAction);
}
value = blockable.getJid().asBareJid().toEscapedString(); value = blockable.getJid().asBareJid().toEscapedString();
res = isBlocked ? R.string.unblock_contact_text : R.string.block_contact_text; res = isBlocked ? R.string.unblock_contact_text : R.string.block_contact_text;
} }
@ -45,7 +69,7 @@ public final class BlockContactDialog {
xmppActivity.xmppConnectionService.sendUnblockRequest(blockable); xmppActivity.xmppConnectionService.sendUnblockRequest(blockable);
} else { } else {
boolean toastShown = false; boolean toastShown = false;
if (xmppActivity.xmppConnectionService.sendBlockRequest(blockable, binding.reportSpam.isChecked())) { if (xmppActivity.xmppConnectionService.sendBlockRequest(blockable, binding.reportSpam.isChecked(), serverMsgId)) {
Toast.makeText(xmppActivity, R.string.corresponding_conversations_closed, Toast.LENGTH_SHORT).show(); Toast.makeText(xmppActivity, R.string.corresponding_conversations_closed, Toast.LENGTH_SHORT).show();
toastShown = true; toastShown = true;
} }

View file

@ -87,7 +87,7 @@ public class BlocklistActivity extends AbstractSearchableListItemActivity implem
dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> {
Blockable blockable = new RawBlockable(account, contactJid); Blockable blockable = new RawBlockable(account, contactJid);
if (xmppConnectionService.sendBlockRequest(blockable, false)) { if (xmppConnectionService.sendBlockRequest(blockable, false, null)) {
Toast.makeText(BlocklistActivity.this, R.string.corresponding_conversations_closed, Toast.LENGTH_SHORT).show(); Toast.makeText(BlocklistActivity.this, R.string.corresponding_conversations_closed, Toast.LENGTH_SHORT).show();
} }
return true; return true;

View file

@ -1308,6 +1308,7 @@ public class ConversationFragment extends XmppFragment
|| t instanceof HttpDownloadConnection); || t instanceof HttpDownloadConnection);
activity.getMenuInflater().inflate(R.menu.message_context, menu); activity.getMenuInflater().inflate(R.menu.message_context, menu);
menu.setHeaderTitle(R.string.message_options); menu.setHeaderTitle(R.string.message_options);
final MenuItem reportAndBlock = menu.findItem(R.id.action_report_and_block);
MenuItem openWith = menu.findItem(R.id.open_with); MenuItem openWith = menu.findItem(R.id.open_with);
MenuItem copyMessage = menu.findItem(R.id.copy_message); MenuItem copyMessage = menu.findItem(R.id.copy_message);
MenuItem copyLink = menu.findItem(R.id.copy_link); MenuItem copyLink = menu.findItem(R.id.copy_link);
@ -1326,6 +1327,17 @@ public class ConversationFragment extends XmppFragment
m.getStatus() == Message.STATUS_SEND_FAILED m.getStatus() == Message.STATUS_SEND_FAILED
&& m.getErrorMessage() != null && m.getErrorMessage() != null
&& !Message.ERROR_MESSAGE_CANCELLED.equals(m.getErrorMessage()); && !Message.ERROR_MESSAGE_CANCELLED.equals(m.getErrorMessage());
final Conversational conversational = m.getConversation();
if (m.getStatus() == Message.STATUS_RECEIVED && conversational instanceof Conversation c) {
final XmppConnection connection = c.getAccount().getXmppConnection();
if (c.isWithStranger()
&& m.getServerMsgId() != null
&& !c.isBlocked()
&& connection != null
&& connection.getFeatures().spamReporting()) {
reportAndBlock.setVisible(true);
}
}
if (!m.isFileOrImage() if (!m.isFileOrImage()
&& !encrypted && !encrypted
&& !m.isGeoUri() && !m.isGeoUri()
@ -1449,6 +1461,9 @@ public class ConversationFragment extends XmppFragment
case R.id.open_with: case R.id.open_with:
openWith(selectedMessage); openWith(selectedMessage);
return true; return true;
case R.id.action_report_and_block:
reportMessage(selectedMessage);
return true;
default: default:
return super.onContextItemSelected(item); return super.onContextItemSelected(item);
} }
@ -2114,6 +2129,10 @@ public class ConversationFragment extends XmppFragment
} }
} }
private void reportMessage(final Message message) {
BlockContactDialog.show(activity, conversation.getContact(), message.getServerMsgId());
}
private void showErrorMessage(final Message message) { private void showErrorMessage(final Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
builder.setTitle(R.string.error_message); builder.setTitle(R.string.error_message);

View file

@ -67,4 +67,6 @@ public final class Namespace {
public static final String OMEMO_DTLS_SRTP_VERIFICATION = "http://gultsch.de/xmpp/drafts/omemo/dlts-srtp-verification"; public static final String OMEMO_DTLS_SRTP_VERIFICATION = "http://gultsch.de/xmpp/drafts/omemo/dlts-srtp-verification";
public static final String JINGLE_TRANSPORT_ICE_OPTION = "http://gultsch.de/xmpp/drafts/jingle/transports/ice-udp/option"; public static final String JINGLE_TRANSPORT_ICE_OPTION = "http://gultsch.de/xmpp/drafts/jingle/transports/ice-udp/option";
public static final String UNIFIED_PUSH = "http://gultsch.de/xmpp/drafts/unified-push"; public static final String UNIFIED_PUSH = "http://gultsch.de/xmpp/drafts/unified-push";
public static final String REPORTING = "urn:xmpp:reporting:1";
public static final String REPORTING_REASON_SPAM = "urn:xmpp:reporting:spam";
} }

View file

@ -2689,7 +2689,7 @@ public class XmppConnection implements Runnable {
} }
public boolean spamReporting() { public boolean spamReporting() {
return hasDiscoFeature(account.getDomain(), "urn:xmpp:reporting:reason:spam:0"); return hasDiscoFeature(account.getDomain(), Namespace.REPORTING);
} }
public boolean flexibleOfflineMessageRetrieval() { public boolean flexibleOfflineMessageRetrieval() {

View file

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_report_and_block"
android:title="@string/report_spam"
android:visible="false" />
<item <item
android:id="@+id/open_with" android:id="@+id/open_with"
android:title="@string/open_with" android:title="@string/open_with"

View file

@ -1020,4 +1020,6 @@
<string name="log_in">Log in</string> <string name="log_in">Log in</string>
<string name="contact_uses_unverified_keys">Your contact uses unverified devices. Scan their 2D barcode to perform verification and impede active MITM attacks.</string> <string name="contact_uses_unverified_keys">Your contact uses unverified devices. Scan their 2D barcode to perform verification and impede active MITM attacks.</string>
<string name="unverified_devices">You are using unverified devices. Scan the 2D barcode on your other devices to perform verification and impede active MITM attacks.</string> <string name="unverified_devices">You are using unverified devices. Scan the 2D barcode on your other devices to perform verification and impede active MITM attacks.</string>
<string name="report_spam">Report spam</string>
<string name="report_spam_and_block">Report spam and block spammer</string>
</resources> </resources>