The discussion revolves around the unexpected addition of IPs to the Screened IPs list when deleting users through the API, despite setting block_ip to false.
mentalstring initially reported the issue and suspected a bug, but codinghorror suggested that the “delete as spammer” function might be the cause. However, mentalstring clarified that they were using the correct API endpoint (DELETE /admin/users/{id}.json) with block_ip set to false.
After further investigation, mentalstring discovered that the issue was due to passing truthy/falsy values instead of the required string values 'true' and 'false'. However, even after correcting this, the problem persisted.
mentalstring found that the API endpoint always interprets present parameters as true, regardless of their value. To resolve the issue, they started only setting parameters that were true and skipping the false ones.
codinghorror advised emulating the behavior observed when using the “delete only” button, and riking confirmed that the server may treat present values as true in some cases, which is likely the cause of the issue.
We are using SSO for login and account creation. There’s no other way to login or signing up on our forum.
However, the list of screened IPs has dozens of IP addresses which are being added automatically on a daily basis. Is this expected? What makes an IP address get added to the Screened IPs list?
You may want to use Reverse engineer the Discourse API and see exactly what requests are sent when you delete a user, and pressing the button that says Delete only
… because I can tell you for a fact that if you are seeing IPs get added to the screened list after deletion, you are absolutely deleting the user as a spammer, e.g. the middle button – delete and block.
I had already done that and the deleting API endpoint is the one I have been using, which the same one for both actions (delete only and delete&block) — the only difference is on the parameters that are used with it (block_ip, block_email, …) that I mentioned aboved.
I think I finally got around what was the issue with my requests: Discourse’s API wants the strings ‘true’ and ‘false’ instead truthy/falsy values. My bad for not spotting the notice about that on the docs.
That was probably what has been causing all this mess.
Having corrected the truthy/falsy parameters to ‘true’/‘false’ strings, I still see entries being added to Screened IPs and Screened Emails upon deleting users.
Here’s the rails logs for a API call:
Started DELETE "/admin/users/9553.json" for 123.123.123.123 at 2021-06-10 00:01:21 +0000
Processing by Admin::UsersController#destroy as JSON
Parameters: {"delete_posts"=>"false", "block_email"=>"false", "blocked_urls"=>"false", "block_ip"=>"false", "id"=>"9553"}
Can't verify CSRF token authenticity.
Rendering text template
Rendered text template (Duration: 0.0ms | Allocations: 1)
Completed 418 in 8ms (Views: 1.4ms | ActiveRecord: 0.0ms | Allocations: 2301)
And here’s the request when done through the web interface instead of calling the API:
Started DELETE "/admin/users/49.json" for 123.123.123.123 at 2021-06-10 08:24:47 +0000
Processing by Admin::UsersController#destroy as JSON
Parameters: {"context"=>"/admin/users/49/XXX", "delete_posts"=>"true", "id"=>"49"}
Rendered text template (Duration: 0.0ms | Allocations: 1)
Completed 418 in 23ms (Views: 4.7ms | ActiveRecord: 0.0ms | Allocations: 1778)
So, after some tests, it seems that the parameters for the API endpoint /admin/users/{id}.json are always interpreted as true when they are present, regardless whether they are actually being set to ‘true’ or ‘false’?
Once I started only setting the parameters that were ‘true’, and skipping the ‘false’ ones, then no more entries are being added to the Screened IPs/emails.
Is this the intended behavior? That’s not what I understand from the docs.
As long as you’ve emulated the behavior that you observe when you follow the Reverse engineer the Discourse API topic, you should be OK. What API calls are you observing in the network monitor when you push the “delete only” button?
In some cases, when the JS isn’t explicitly passing false to the server, the server treats any present value as true. This is likely what you’re encountering here.