Commit Graph

1556 Commits

Author SHA1 Message Date
evazion
1ee1e807cf rate limits: penalize user if they keep making requests while limited.
If the user makes a request while rate limited, penalize them 1 second
for that request, up to a maximum of 30 seconds. This means that if a
user doesn't stop making requests after being rate limited, then they
will stay rate limited forever until they stop.

This is to temp ban bots, especially spam bots, that flood requests
while ignoring HTTP errors or rate limits.

(Note that this is on a per-endpoint basis. Being rate limited on one
endpoint won't penalize you for making calls to other endpoints.)
2021-03-05 16:04:48 -06:00
evazion
413cd34c45 rate limits: adjust limits for various actions.
* Tie rate limits to both the user's ID and their IP address.

* Make each endpoint have separate rate limits. This means that, for
  example, your post edit rate limit is separate from your post vote
  rate limit. Before all write actions had a shared rate limit.

* Make all write endpoints have rate limits. Before some endpoints, such
  as voting, favoriting, commenting, or forum posting, weren't subject
  to rate limits.

* Add stricter rate limits for some endpoints:

** 1 per 5 minutes for creating new accounts.
** 1 per minute for login attempts, changing your email address, or
   for creating mod reports.
** 1 per minute for sending dmails, creating comments, creating forum
   posts, or creating forum topics.
** 1 per second for voting, favoriting, or disapproving posts.
** These rate limits all have burst factors high enough that they
   shouldn't affect normal, non-automated users.

* Raise the default write rate limit for Gold users from 2 per second to
  4 per second, for all other actions not listed above.

* Raise the default burst factor to 200 for all other actions not listed
  above. Before it was 10 for Members, 30 for Gold, and 60 for Platinum.
2021-03-05 16:02:57 -06:00
evazion
4492610dfe rate limits: rework rate limit implementation.
Rework the rate limit implementation to make it more flexible:

* Allow setting different rate limits for different actions. Before we
  had a single rate limit for all write actions. Now different
  controller endpoints can have different limits.

* Allow actions to be rate limited by user ID, by IP address, or both.
  Before actions were only limited by user ID, which meant non-logged-in
  actions like creating new accounts or attempting to login couldn't be rate
  limited. Also, because actions were limited by user ID only, you could
  use multiple accounts with the same IP to get around limits.

Other changes:

* Remove the API Limit field from user profile pages.
* Remove the `remaining_api_limit` field from the `/profile.json` endpoint.
* Rename the `X-Api-Limit` header to `X-Rate-Limit` and change it from a
  number to a JSON object containing all the rate limit info
  (including the refill rate, the burst factor, the cost of the call,
  and the current limits).
* Fix a potential race condition where, if you flooded requests fast
  enough, you could exceed the rate limit. This was because we checked
  and updated the rate limit in two separate steps, which was racy;
  simultaneous requests could pass the check before the update happened.
  The new code uses some tricky SQL to check and update multiple limits
  in a single statement.
2021-03-05 16:00:54 -06:00
evazion
35a0c6b11f Fix #4736: Display network prefix length (if present) in API key IP whitelist. 2021-03-01 02:38:18 -06:00
evazion
1b93cbd075 autocomplete: match static metatags case-sensitively.
Fix rating:S not matching rating:s.
2021-02-25 06:16:17 -06:00
evazion
0cc1dae677 Fix #4725: Don't mark as spam DMails sent by an user to themselves. 2021-02-23 19:27:04 -06:00
evazion
8b8a3f3836 Merge pull request #4723 from nonamethanks/pawoo2mastodon
Convert pawoo strategy into mastodon; add baraag.net support
2021-02-16 18:22:20 -06:00
evazion
2fccf203bd Merge pull request #4719 from nonamethanks/fanbox-r18
Fanbox: fix tests and a bug with image ordering in the bookmarklet
2021-02-16 18:18:04 -06:00
nonamethanks
ffe8f8c92d Add baraag.net support 2021-02-15 13:51:52 +01:00
nonamethanks
5366b0781e Convert pawoo strategy to mastodon 2021-02-15 13:51:49 +01:00
evazion
206ff2b836 tests: fix ip geolocation test. 2021-02-15 00:38:59 -06:00
evazion
25fda1ecc2 api keys: add IP whitelist and API permission system.
Add the ability to restrict API keys so that they can only be used with
certain IP addresses or certain API endpoints.

Restricting your key is useful to limit damage in case it gets leaked or
stolen. For example, if your key is on a remote server and it gets
hacked, or if you accidentally check-in your key to Github.

Restricting your key's API permissions is useful if a third-party app or
script wants your key, but you don't want to give full access to your
account.

If you're an app or userscript developer, and your app needs an API key
from the user, you should only request a key with the minimum
permissions needed by your app.

If you have a privileged account, and you have scripts running under
your account, you are highly encouraged to restrict your key to limit
damage in case your key gets leaked or stolen.
2021-02-14 21:02:07 -06:00
evazion
a6707fbfa2 api keys: allow users to have multiple API keys.
This is useful if you have multiple programs and want to give them
different API keys, or if you want to rotate keys for a single program.
2021-02-14 04:09:47 -06:00
evazion
37061f95a6 api keys: rework API key UI.
* Add an explanation of what an API key is and how to use it.
* Make it possible for the site owner to view all API keys.
* Remove the requirement to re-enter your password before you can view
  your API key (to be reworked).
* Move the API key controller from maintenance/user/api_keys_controller.rb
  to a top level controller.
2021-02-14 04:09:47 -06:00
evazion
23a06aff1d Fix #4720: Pixiv commentary links all create invalid urls.
Regression caused by the switch from the mobile API to the Ajax API. In
the Ajax API, commentaries have /jump.php?<url> links that we have to strip out.
2021-02-13 17:41:01 -06:00
nonamethanks
482c1e4c7c Fanbox: fix tests and image ordering
* fix the test for R18 posts, which are now supported
* replace the dead post for the imageMap test with an active one
* fix the ordering of images: it was possible to get the wrong image in
some cases when not using the batch bookmarklet, because of how fanbox
orders imageMap posts
* fix a bug where the sample wasn't properly replaced with the full
size
* rename test file to match the rest of the other files
2021-02-10 16:53:22 +01:00
evazion
39cc3ed5cf pixiv: fix API breakage.
Fix the Pixiv API no longer working by rewriting the Pixiv strategy to
use the Ajax API instead of the mobile API.

Before we could authenticate in the mobile API by using the OAuth 2.0
grant_type=password authentication flow. This no longer works. Now it
requires logging in through a HTML page, which is protected by Google
reCaptcha. This makes using the mobile API infeasible.

Instead we switch to the Ajax API, which only needs a PHPSESSID to
authenticate. This can be obtained by logging in manually and using the
devtools to extract the cookie.

This also temporarily removes support for Pixiv novels. This should be
moved to a separate source strategy.
2021-02-09 06:18:36 -06:00
evazion
031032326e mentions: fix exception when mentioning nonexistent user. 2021-02-05 19:40:30 -06:00
evazion
3639d7eae5 tests: fixup twitter tests for c90ef9f1b. 2021-02-05 03:33:07 -06:00
evazion
410a37ec80 tests: fix ip geolocation test. 2021-02-04 00:20:52 -06:00
evazion
3f16fe3d80 Fix #4680: @-ing yourself sends you a DMail.
Don't send a dmail when the user @-mentions themselves, whether in an
edit or in the original message.
2021-02-03 23:46:59 -06:00
evazion
50864c7147 Fix #4685: Tagging "aliased_tag -aliased_tag" adds aliased_tag. 2021-02-03 23:24:12 -06:00
evazion
e28c28c03b BURs: when moving artists, add old tag to other names.
When aliasing or renaming an artist, add their old tag name to their
other names.
2021-02-03 23:17:13 -06:00
evazion
b03d8e728d Fix #4683: Automove _(style) tags when artists are processed via BUR. 2021-02-03 21:27:35 -06:00
evazion
19974d3ab1 Fix #4688: Malformed SQL when searching -status:any.
Negating `Post.all` produced the invalid SQL fragment `WHERE NOT ()`.
Use `Post.where("TRUE")` instead to produce `WHERE NOT (TRUE)`.
2021-02-03 21:15:58 -06:00
evazion
d0c9f6e0b8 posts: allow toggling between upvotes and downvotes.
Like 9efb374ae, allow users to toggle between upvoting and downvoting a
post without raising an error or having to manually remove the vote
first. If you upvote a post, then downvote it, the upvote is
automatically removed and replaced by the downvote.

Other changes:

* Tagging a post with `upvote:self` or `downvote:self` is now silently
  ignored when the user doesn't have permission to vote, instead of
  raising an error.
* Undoing a vote that doesn't exist now does nothing instead of
  returning an error. This can happen if you open the same post in two
  tabs, undo the vote in tab 1, then try to undo the vote again in tab 2.

Changes to the /post_votes API:

* `POST /post_votes` and `DELETE /post_votes` now return a post vote
  instead of a post.
* The `score` param in `POST /post_votes` is now 1 or -1, not `up` or
  `down`.
2021-01-29 02:22:23 -06:00
evazion
716cdb0126 tests: fix broken tests.
* Fix a broken Twitter profile image upload test.
* Skip a broken DeviantArt flash file upload test (flash no longer
  supported by DeviantArt?)
* Skip user upgrade tests when Stripe is not configured.
2021-01-27 00:40:53 -06:00
evazion
b689c9cbed comments: add uniqueness constraint on votes. 2021-01-23 14:44:11 -06:00
evazion
9d71ece55d comments: remove 2 comments per hour limit.
Remove the rule that Members could only post 2 bumping comments per
hour.

This was frequently misunderstood as meaning that Members could only
post 2 comments per hour. In fact, Members could post an unlimited
number of comments per hour, but the rest of their comments had to be
non-bumping. The error message we showed to users was misleading. Even
our own code misunderstood what this did when describing the config
option.

Gold users also weren't subject to this limit, which was unfair since
Gold users aren't any better at commenting than regular users. The fact
that a large number of users already ignored bump limits and nobody
really noticed indicates that the limit was unnecessary.
2021-01-22 05:16:45 -06:00
evazion
25bf78f9eb comments: fix incorrect comment links in mentions.
Fix mentions incorrectly linking to comments like this:

    https://danbooru.donmai.us/posts/1234#comment-5678

when it should have been this

    https://danbooru.donmai.us/posts/1234#comment_5678

Change comment links to this to ensure they're permanent:

    https://danbooru.donmai.us/comments/5678

The comment show action will redirect from there to the post with the
comment in context.
2021-01-21 15:36:49 -06:00
evazion
9efb374ae5 comments: allow swapping votes.
Allow users to upvote a comment, then downvote it, without raising an
error or having to manually remove the upvote first. The upvote is
automatically removed and replaced by the downvote.

Changes to the /comment_votes API:

* `POST /comment_votes` and `DELETE /comment_votes` now return a comment
  vote instead of a comment.
* The `score` param in `POST /comment_votes` is now 1 or -1, not
  `up` or `down.`
2021-01-21 07:58:50 -06:00
evazion
6ca007ee1f Fix #4670: Replace RequestStore with AS::CurrentAttributes.
This also requires replacing CurrentUser.name with CurrentUser.user.name
because the `name` method had a conflict with CurrentAttributes.
2021-01-16 12:43:20 -06:00
evazion
ceeed1e692 pagination: refactor page limits.
Refactor page limits to a) be explicitly listed in the User class (not
hidden away in the Danbooru config) and b) explicitly depend on the
CurrentUser (not implicitly by way of Danbooru.config.max_numbered_pages).
2021-01-11 21:09:06 -06:00
evazion
e9464d0ea5 tests: replace xip.io with nip.io.
https://xip.io tends to go down at random times, breaking our tests. Use
https://nip.io instead.
2021-01-11 21:09:06 -06:00
evazion
aab9fd710b tests: fix broken Danbooru::Http redirect tests.
Switch from https://httpbin.org to https://nghttp2.org/httpbin.
Redirects on https://httpbin.org have been broken for months, with no
resolution in sight.
2021-01-11 20:41:10 -06:00
evazion
c1b865b160 searchable: add more enum attribute search options.
Add `<enum>_not` and `<enum>_id_<op>` search options:

* https://danbooru.donmai.us/mod_actions?search[category_not]=post_regenerate,post_regenerate_iqdb
* https://danbooru.donmai.us/mod_actions?search[category_not]=48,49
* https://danbooru.donmai.us/mod_actions?search[category_id]=40..50
* https://danbooru.donmai.us/mod_actions?search[category_id_not]=40..50
* https://danbooru.donmai.us/mod_actions?search[category_id_gt]=40&search[category_id_lt]=50
2021-01-11 19:13:35 -06:00
evazion
e7b454686e searchable: refactor where_operator method.
Refactor the `where_operator` method so we can use it to avoid raw SQL
in more places.
2021-01-11 19:13:29 -06:00
evazion
6d2eeb6f28 searchable: fix being unable to use multiple operators on same attribute.
Fix searches like this not working:

* https://danbooru.donmai.us/tags?search[id]=1..100&search[id_not]=50

Before one of these params would override the other.
2021-01-11 14:59:04 -06:00
evazion
95f39afcd9 tests: fixup broken tests. 2021-01-11 05:12:09 -06:00
evazion
be1251b6be autocomplete: optimize various types of bogus input.
Optimize autocomplete to ignore various types of bogus input that will
never match anything. It turns out it's not uncommon for people to do
things like paste random URLs into autocomplete, or hold down keys, or
enter long strings of gibberish text (sometimes in other languages).
Some things, like autocorrect and slash abbreviations, become
pathologically slow when fed certain types of bad input.

Autocomplete will abort and return nothing in the following situations:

* Searching for URLs (tags that start with http:// or https://).
* Overly long tags (strings longer than the 170 char tag name limit).
* Slash abbreviations longer than 10 chars (e.g. typing `/qwoijqoiqogirqewgoi`).
* Slash abbreviations that aren't alphanumeric (e.g. typing `/////////`).
* Autocorrect input that contains too much punctuation and not enough actual letters.
2021-01-11 05:12:09 -06:00
evazion
d18dc573fb artists: fix misnormalization of emoji in other names.
Fix `normalize_whitespace` to not strip zero-width joiner characters
(U+200D). These characters are used in emoji and stripping them breaks
some artist other names that use emoji.
2021-01-10 02:46:20 -06:00
evazion
0899194f6b Fix conflict between normalize and array_attribute macros.
Fix the `normalize` and `array_attribute` macros conflicting with each
other on the WikiPage model. This meant code like
`wiki_page.other_names = "foo bar"` didn't work. Both macros defined a
`other_names=` method, but one method overrode the other.

The fix is to use anonymous modules and prepend so we can chain method
calls with super.
2021-01-10 02:03:12 -06:00
evazion
5962152ee3 wiki pages, artists: fix normalization of other names.
Fix wiki pages and artists to normalize other names more consistently
and correctly.

For wiki pages, we strip leading / trailing / repeated underscores to
fix user typos, and we normalize to NFKC form to make search more consistent.

For artists, we allow leading / trailing / repeated underscores because
some artist names have these, and we normalize to NFC form because some
artists have weird names that would be lost by NFKC form. This does make
search less consistent.
2021-01-10 02:03:12 -06:00
evazion
e788d8d0b6 saved searches: fix normalization of labels.
Fix saved searches to remove additional invalid characters from labels:

* Remove repeated spaces or underscores.
* Remove leading and trailing spaces or underscores.
* Normalize Unicode characters to NFC form.

Also add a fix script to renormalize labels in old saved searches. A few
problems with existing searches:

* Some saved searches somehow had labels containing NULL elements.
* Some had leading or trailing underscores.
* Some had repeated underscores.
* Some had non-English characters in uppercase.
2021-01-10 02:03:12 -06:00
evazion
7fbac34962 wiki pages: fix normalization of wiki page title.
Fix the wiki page title "azur___lane" being normalized to "azur__lane"
instead of "azur_lane".
2021-01-10 02:03:12 -06:00
evazion
ff6e640fcb tests: add normalize_attribute helper method.
Add a custom Shoulda matcher for testing that a model correctly normalizes an attribute.

Usage:

    subject { build(:wiki_page) }
    should normalize_attribute(:title).from(" Azur  Lane ").to("azur_lane")
2021-01-10 02:03:12 -06:00
evazion
9759701071 search: add way to search array attributes by regex.
Add a `where_any_in_array_matches_regex` method and expose it to the API:

 * https://danbooru.donmai.us/artists?search[any_other_name_matches_regex]=^blah
 * https://danbooru.donmai.us/wiki_pages?search[any_other_name_matches_regex]=^blah
 * https://danbooru.donmai.us/saved_searches?search[any_label_matches_regex]=^blah

In SQL, this does `WHERE '^blah' ~<< ANY(other_names)`, where `~<<` is a
custom operator based on the `~` regex match operator, but with the
arguments reversed. This allows it to be used with the ANY(array) operator.

See also:

* https://stackoverflow.com/a/22101172
* https://www.postgresql.org/docs/current/sql-createfunction.html
* https://www.postgresql.org/docs/current/sql-createoperator.html
* https://www.postgresql.org/docs/current/functions-comparisons.html
2021-01-10 02:03:02 -06:00
evazion
65adcd09c2 users: track logins, signups, and other user events.
Add tracking of certain important user actions. These events include:

* Logins
* Logouts
* Failed login attempts
* Account creations
* Account deletions
* Password reset requests
* Password changes
* Email address changes

This is similar to the mod actions log, except for account activity
related to a single user.

The information tracked includes the user, the event type (login,
logout, etc), the timestamp, the user's IP address, IP geolocation
information, the user's browser user agent, and the user's session ID
from their session cookie. This information is visible to mods only.

This is done with three models. The UserEvent model tracks the event
type (login, logout, password change, etc) and the user. The UserEvent
is tied to a UserSession, which contains the user's IP address and
browser metadata. Finally, the IpGeolocation model contains the
geolocation information for IPs, including the city, country, ISP, and
whether the IP is a proxy.

This tracking will be used for a few purposes:

* Letting users view their account history, to detect things like logins
  from unrecognized IPs, failed logins attempts, password changes, etc.
* Rate limiting failed login attempts.
* Detecting sockpuppet accounts using their login history.
* Detecting unauthorized account sharing.
2021-01-08 22:34:37 -06:00
evazion
da3e8e4726 searchable: fix bug with searching multiple association attributes.
Fix a bug with searches like the following not working correctly:

* https://danbooru.donmai.us/comments.json?search[creator][level]=20&search[creator_id]=1234
* https://danbooru.donmai.us/comments.json?search[creator][level]=20&search[creator_name]=abcd
* https://danbooru.donmai.us/comments.json?search[post][rating]=s&search[post_tags_match]=touhou

It wasn't possible to search for both `creator` and `creator_id` at the
same time (or `post` and `post_tags_match`, etc). Only the `creator_id`
param would be recognized.

Also refactor some internals:

* `search_includes` was renamed to `search_associated_attribute`.
* `search_attribute` was split up into `search_basic_attribute` and
  `search_associated_attribute`.
2021-01-07 17:10:29 -06:00
evazion
65be2c99b0 Fix #4657: Hentai-Foundry: Document tree depth limit exceeded. 2021-01-06 03:05:36 -06:00