Summary: Merging two lexemes (via API or special page) makes two edits; only the second edit is rate limited and run though edit filters.
----
If the title of this task sounds familiar, that’s because I based it on {T345064}. In that task, we saw that Wikibase PHP code has two interfaces to save edits: the higher-level `EditEntity`, and the lower-level `EntityStore`. `EditEntity`, as implemented by `MediaWikiEditEntity`, handles permission checks, rate limits, edit filter hooks (e.g. AbuseFilter), and more; you really want to be using it if you can. However, it’s not quite suited for saving redirects. To solve the problem of missing rate limits and edit filters for merges and redirects in T345064, we added code to explicitly handle those things to `ItemMergeInteractor` and `EntityRedirectCreationInteractor`. (Side note: We’ll have to add more custom code to them in T356149 to handle temporary users correctly.)
Enter WikibaseLexeme. WikibaseLexeme also has the ability to merge entities, implemented in `MergeLexemesInteractor` (and exposed via a special page and an API). To perform the redirect, `MergeLexemesInteractor` uses an `EntityRedirectCreationInteractor` (implemented by `MediaWikiLexemeRedirector`), so it gets rate limit and edit filter handling from there. However, before redirecting the “source” lexeme to the “target” lexeme, it also edits the “target” lexeme to add data from the “source” lexeme; and this edit is done using the `EntityStore` interface (wrapped in a `MediaWikiLexemeRepository`), bypassing all the checks at the `EditEntity` level, and doesn’t implement those checks anywhere else either. Therefore, this first edit is not rate limited nor checked against AbuseFilter. (It //is// still permission-checked; that said, on Wikidata all users have the right to merge lexemes as far as I’m aware, so the permission check adds ~~no~~ little protection in production [edit: actually, it should at least protect against blocked users].)
Steps to reproduce:
- create two lexemes
- (they need to be compatible for merging, so they should not both have a lemma in the same language)
- create and enable an AbuseFilter that would block the first edit, but not the second edit, such as:
- conditions `!(added_lines contains "#REDIRECT")`
- prevent the user from performing the action in question, with message `abusefilter-disallowed`
- try to merge one lexeme into the other on Special:MergeLexemes
Expected result: an error from the AbuseFilter; actual result: both edits go through.