Commit Graph

2286 Commits

Author SHA1 Message Date
evazion
054ac51d47 policies: remove current request from context.
This refactors Pundit policies to only rely on the current user, not on
the current user and the current HTTP request. In retrospect, it was a
bad idea to include the current request in the Pundit context. It bleeds
out everywhere and there are many contexts (in tests and models) where
we only have the current user, not the current request. The previous
commit got rid of the only two places where we used it.
2021-01-17 00:57:59 -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
6f6ec6592d Fix #4668: Add running commit to /status page. 2021-01-16 12:13:14 -06:00
evazion
32dd14f461 Remove /admin/dashboard page.
This page was just a combination of the forum listing and the bulk
update requests listing. It got zero hits in the last week.
2021-01-16 03:32:11 -06:00
evazion
1b30b71a07 posts: refactor post previews to use ViewComponent.
Refactor the post preview html to use the ViewComponent framework. This
lets us encapsulate all the HTML, CSS, and helper methods for a UI
component in a single place.

See https://viewcomponent.org.
2021-01-14 21:17:57 -06:00
evazion
81708d2ef8 search: log extra search metadata to NewRelic.
When a user does a tag search, log a few more things, including the normalized
search string, the number of tags in the search string, and the number of results.
2021-01-12 04:25:11 -06:00
evazion
c05868e7f1 users: log restricted signups to NewRelic.
When a new user creates an account and their account is automatically
restricted, log the reason why to NewRelic.
2021-01-12 04:25:11 -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
ef177a09cf searchable: fixup bugs in e7b454686. 2021-01-11 19:47:20 -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
1e7a5ba49d Fix ruby warnings about deprecated keyword arguments. 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
fc5db679e4 autocomplete: optimize searching by artist/wiki page other names.
Optimize searches for non-English phrases in autocomplete. These
searches were pretty slow, and could sometimes cause sitewide lag spikes
when users typed long strings of non-English text into the search box
and caused an unintentional DoS.

The trick is to use an `array_to_tsvector(other_names) USING gin` index
on other_names. This supports fast string prefix matching against all
elements of the array. The downside is that it doesn't allow infix or
suffix matches, so we can't support wildcards in general. Wildcards
didn't quite work anyway, since artist and wiki other names can contain
literal '*' characters.
2021-01-10 03:35:12 -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
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
94e125709c users: add Restricted user level.
Add a Restricted user level. Restricted users are level 10, below
Members. New users start out as Restricted if they sign up from a proxy
or an IP recently used by another user.

Restricted users can't update or edit any public content on the site
until they verify their email address, at which point they're promoted
to Member. Restricted users are only allowed to do personal actions
like keep favorites, keep favgroups and saved searches, mark dmails as
read or deleted, or mark forum posts as read.

The restricted state already existed before, the only change here is
that now it's an actual user level instead of a hidden state. Before it
was based on two hidden flags on the user, the `requires_verification`
flag (set when a user signs up from a proxy, etc), and the `is_verified`
flag (set after the user verifies their email). Making it a user level
means that now the Restricted status will be shown publicly.

Introducing a new level below Member means that we have to change every
`is_member?` check to `!is_anonymous` for every place where we used
`is_member?` to check that the current user is logged in.
2021-01-07 17:10:29 -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
BrokenEagle
db5f9ce243 Support multiple excludes for enum types
It's not possible to pass it off to search_numeric_attribute directly
since the column "category" does not match the prefix "category_id".
2021-01-06 20:21:56 +00:00
BrokenEagle
57de81686b Support using all numeric searches for includes 2021-01-06 20:21:56 +00:00
BrokenEagle
4a439d72d6 Support multiple exclusions
Since it does a not of numeric_attribute_matches which uses the
post query builder, it now also support reverse ranges and reverse
greater/less than.
2021-01-06 20:21:55 +00:00
evazion
65be2c99b0 Fix #4657: Hentai-Foundry: Document tree depth limit exceeded. 2021-01-06 03:05:36 -06:00
BrokenEagle
16d6f3bbd5 Add post regenerations 2021-01-04 18:35:50 -06:00
evazion
1909d6e062 Merge pull request #4636 from nonamethanks/fix_replacements
Uploads preprocessing: get rid of same-source existence check
2021-01-04 01:38:03 -06:00
evazion
3542c401d4 Merge pull request #4654 from nonamethanks/fix_gelbooru_normalization
Fix gelbooru source normalization
2021-01-04 01:31:17 -06:00
evazion
50e799e959 Merge branch 'master' into minor_fix 2021-01-04 01:30:28 -06:00
evazion
5612413546 Merge pull request #4641 from nonamethanks/weibo_previews
Weibo: use proxy for upload previews
2021-01-04 01:20:50 -06:00
evazion
ed7e7b1d30 Merge pull request #4639 from nonamethanks/fix_pixiv_en_links
Update artist finder blacklist
2021-01-04 01:15:15 -06:00
evazion
9008e836e4 BURs: raise limit on Builder artist tag moves from 100 to 200 posts. 2021-01-04 01:10:26 -06:00
evazion
257fa3d9c1 Fix #4645: Builders can alias empty non-artist tags 2021-01-04 01:02:39 -06:00
evazion
69cfa1696a html: disable browser spellcheck on all non-DText inputs.
Disable the browser's native spellchecking ability on all form inputs,
except for DText inputs. We do this by setting `spellcheck="false"` on
the <body> tag, and `spellcheck="true"` on DText <input> tags.

This fixes browsers displaying a red wavy underline beneath tags in the
tag search box, among other places. We disable spellchecking globally
because most form inputs, except for DText inputs, aren't meant for
natural English language.
2021-01-04 00:25:54 -06:00
evazion
98ee6c31c1 favorites: refactor fav:/ordfav: searches to not use fav_string.
Refactor fav:<name> and ordfav:<name> searches to use the favorites
table instead of the posts.fav_string.

This may be slower for fav:<name> searches. The fav_string effectively
treats favorites like secret tags on the post, so fav:<name> searches
were effectively the same as tag searches. Now they do a subquery on the
favorites table, which may not perform as well for things like multiple
fav:<name> metatags or negated fav:<name> metatags.

For ordfav:<name> searches, this may be faster. ordfav: searches had a
tag match clause (`tag_index @@ 'fav:123'`) in addition to a join on the
favs table. This was redundant, and in some cases it inhibited the query
planner from choosing a more optimal plan.

Partially addresses #4652 by eliminating another place where we depended
on the fav_string.
2021-01-03 19:18:31 -06:00
nonamethanks
b3f92dd2c7 Fix gelbooru source normalization 2021-01-03 20:12:40 +01:00
evazion
dbe2eeb00d emails: remove "Valid?" search option.
No longer necessary after running previous commit because all invalid
email addresses have been purged.
2021-01-02 04:09:43 -06:00
evazion
36f95891bd search: let wildcard searches match up to 100 tags.
Let searching for things like *_legwear match up to 100 tags. Previously
the limit was 25.
2021-01-02 04:09:43 -06:00
evazion
5b7894a8b2 autocomplete: fix exception when type param is missing. 2021-01-01 04:06:38 -06:00
evazion
430ba5dced users: fix exception during signup for IPv6 addresses.
`ip_address.private?` failed on IPv6 addresses.
2021-01-01 03:57:17 -06:00
evazion
ae5c0d1034 newrelic: log request path. 2020-12-31 06:50:10 -06:00
evazion
9e9ac8f4bf sessions: store geolocated country in CurrentUser. 2020-12-31 04:54:00 -06:00
evazion
7fc5845e72 /emails: add more search options.
Add options to search for invalid emails and emails from restricted
domains.
2020-12-28 19:31:40 -06:00
evazion
6a52216631 newrelic: log additional request headers.
Log the Referer header, as well as the Sec-Fetch-* headers. These are
only sent by recent versions of Chrome; see https://www.w3.org/TR/fetch-metadata.
2020-12-28 01:53:22 -06:00
evazion
805bbc8a33 users: add config option to disable verification of new accounts.
Fixes #4618.
2020-12-28 00:01:35 -06:00
evazion
9dc788c0ce users: improve sockpuppet detection on signup.
Require new accounts to verify their email address if any of the
following conditions are true:

* Their IP is a proxy.
* Their IP is under a partial IP ban.
* They're creating a new account while logged in to another account.
* Somebody recently created an account from the same IP in the last week.

Changes from before:

* Allow logged in users to view the signup page and create new accounts.
  Creating a new account while logged in to your old account is now
  allowed, but it requires email verification. This is a honeypot.
* Creating multiple accounts from the same IP is now allowed, but they
  require email verification. Previously the same IP check was only for
  the last day (now it's the last week), and only for an exact IP match
  (now it's a subnet match, /24 for IPv4 or /64 for IPv6).
* New account verification is disabled for private IPs (e.g. 127.0.0.1,
  192.168.0.1), to make development or running personal boorus easier
  (fixes #4618).
2020-12-27 23:41:07 -06:00
evazion
7e8f859b24 tags: eliminate Tag.category_for method.
Tag.category_for looked up a tag's category in the Redis cache. This was
only used in a few places (in related tags, and on the popular/missed
search pages). Get rid of this method so we can work towards getting rid
of caching tag categories in Redis.
2020-12-27 21:03:26 -06:00
evazion
7f1b798b05 searchable: refactor search_boolean_attribute. 2020-12-27 05:26:21 -06:00
evazion
058d71aa30 user upgrades: send dmail to purchaser for gifted upgrades.
* Refactor to move upgrade logic from UserPromotion to UserUpgrade.
* Send the recipient and the purchaser of a gifted upgrade separate
  dmail notifications.
2020-12-25 00:43:58 -06:00
evazion
74ed2a8b96 user upgrades: add UserUpgrade model.
Add a model to store the status of user upgrades.

* Store the upgrade purchaser and the upgrade receiver (these are
  different for a gifted upgrade, the same for a self upgrade).
* Store the upgrade type: gold, platinum, or gold-to-platinum upgrades.
* Store the upgrade status:
** pending: User is still on the Stripe checkout page, no payment
   received yet.
** processing: User has completed checkout, but the checkout status in
   Stripe is still 'unpaid'.
** complete: We've received notification from Stripe that the payment
   has gone through and the user has been upgraded.
* Store the Stripe checkout ID, to cross-reference the upgrade record on
  Danbooru with the checkout record on Stripe.

This is the upgrade flow:

* When the user clicks the upgrade button on the upgrade page, we call
  POST /user_upgrades and create a pending UserUpgrade.
* We redirect the user to the checkout page on Stripe.
* When the user completes checkout on Stripe, Stripe sends us a webhook
  notification at POST /webhooks/receive.
* When we receive the webhook, we check the payment status, and if it's
  paid we mark the UserUpgrade as complete and upgrade the user.
* After Stripe sees that we have successfully processed the webhook,
  they redirect the user to the /user_upgrades/:id page, where we show
  the user their upgrade receipt.
2020-12-24 21:15:04 -06:00
evazion
7762489d7d user upgrades: upgrade to new Stripe checkout system.
This upgrades from the legacy version of Stripe's checkout system to the
new version:

> The legacy version of Checkout presented customers with a modal dialog
> that collected card information, and returned a token or a source to
> your website. In contrast, the new version of Checkout is a smart
> payment page hosted by Stripe that creates payments or subscriptions. It
> supports Apple Pay, Dynamic 3D Secure, and many other features.

Basic overview of the new system:

* We send the user to a checkout page on Stripe.
* Stripe collects payment and sends us a webhook notification when the
  order is complete.
* We receive the webhook notification and upgrade the user.

Docs:

* https://stripe.com/docs/payments/checkout
* https://stripe.com/docs/payments/checkout/migration#client-products
* https://stripe.com/docs/payments/handling-payment-events
* https://stripe.com/docs/payments/checkout/fulfill-orders
2020-12-24 19:58:29 -06:00