Commit Graph

1606 Commits

Author SHA1 Message Date
evazion
acf565be7b Fix #4678: Validate custom CSS.
* Make it an error to add invalid custom CSS to your account.
* Add a fix script to remove custom CSS from all accounts with invalid CSS.
2022-01-15 23:20:49 -06:00
evazion
1518c3c4be posts: fix search queries not being logged to NewRelic in some cases (#4900)
Fix the /posts index controller not logging the normalized search query
to NewRelic when the search failed, either because of a tag limit error,
a search timeout, or a RSS feed rate limit error.

Also don't log the number of search results when it's an API request or
failed search. This is to avoid doing a potentially slow full post count
when it's not otherwise needed.
2022-01-11 13:39:30 -06:00
evazion
323882dbc4 upgrades: fix unsafe redirect errors in receipt/payment actions. 2022-01-10 00:11:10 -06:00
evazion
37f2d5925f sessions: fix open redirect in login page.
Fix an open redirect exploit where if you went to <https://danbooru.donmai.us/login?url=//fakebooru.com>,
then after you logged in you would be redirected to https://fakebooru.com.

This was actually fixed by the upgrade to Rails 7.0. `redirect_to` now
raises an `UnsafeRedirectError` on redirect to an offsite URL. Before we
tried to prevent offsite redirects by checking that the URL started with
a slash, but this was insufficient - it allowed protocol-relative URLs
like `//fakebooru.com`.

Add a test case for protocol-relative URLs and return a 403 error on an
offsite redirect.
2022-01-07 21:11:04 -06:00
evazion
dc159ed135 jobs: show retried jobs in /jobs listing.
Fix the /jobs listing to show retried jobs. GoodJob::ActiveJobJob has a
default scope that filters out retried jobs; remove it in the index
controller so we can see retried jobs.

Also fix mail delivery jobs not showing up in the dropdown in the /jobs
search form.
2022-01-04 17:46:54 -06:00
evazion
82211ba935 jobs: add ability to search jobs on /jobs page.
Add ability to search jobs on the /jobs page by job type or by status.

Fixes #2577 (Search filters for delayed jobs). This wasn't possible
before with DelayedJobs because it stored the job data in a YAML string,
which made it difficult to search jobs by type. GoodJobs stores job data
in a JSON object, which is easier to search in Postgres.
2022-01-04 17:18:36 -06:00
evazion
21a9bb2c63 jobs: rename /delayed_jobs to /jobs.
Rename the /delayed_jobs endpoint to just /jobs since it's no longer
based on DelayedJob.
2022-01-02 21:21:16 -06:00
evazion
f7784d2340 jobs: update jobs dashboard to work with GoodJob.
Update the jobs dashboard at /delayed_jobs to work with GoodJob instead
of DelayedJob.
2022-01-02 21:21:04 -06:00
evazion
370ed32426 emails: fix exception when disabling dmail notifications.
Fix an `undefined method 'find' for Maintenance::User:Module` exception
when disabling email notifications using the "Disable notifications"
link in dmails.
2022-01-02 17:10:27 -06:00
evazion
32613f9bb1 emails: fix sending emails to invalid addresses.
Fix mailers to not attempt deliveries to invalid or nonexistent email
addresses. This usually happened when someone changed their email, and
we tried to send a confirmation email to a nonexistent address.
2022-01-02 16:07:57 -06:00
evazion
a7dc05ce63 Enable frozen string literals.
Make all string literals immutable by default.
2021-12-14 21:33:27 -06:00
evazion
0997f5595e posts: increase default thumbnail size.
* Increase the default thumbnail size from small (150x150) to medium (180x180).
* Change the mobile layout to use three posts per row instead of two for small thumbnails.

Parent/child posts are still 150x150 to avoid taking up even more space above posts.
2021-12-13 05:23:38 -06:00
evazion
e04892fb38 posts: use 180x180 thumbnails in place of 150x150 thumbnails.
For small thumbnails, use 180x180 thumbnails scaled down to 150x150.
This is so we can get rid of 150x150 images and just use 180x180 for
both small and medium size thumbnails.

Also fix RSS feeds, XML sitemaps, and Discord embeds to use 360x360
thumbnails instead of 150x150 thumbnails.
2021-12-13 05:23:38 -06:00
evazion
4021ddb579 Fix N+1 queries problem in /explore/posts/popular.json. 2021-12-10 01:46:01 -06:00
evazion
514c57ce58 api: add rate limit to /explore/posts/popular.json endpoint.
Add a rate limit of 1 request per minute to the /explore/posts/popular.json endpoint.
This is to deal with a particular bot checking this page multiple times
per second.
2021-12-10 01:46:01 -06:00
evazion
36985e9590 api: add rate limit to /posts.atom endpoint.
Add a rate limit of 1 request per 2 seconds to the post RSS feed
endpoint (/posts.atom).

This lets you check your feeds 30 times per minute, or 1800 times per
hour. The previous limit was 10 requests per second.

This is because there are too many bad RSS feed reader bots constantly
checking the same tags over and over again, 24 hours a day, as fast
they can.
2021-12-10 01:46:01 -06:00
evazion
2e9f4dc2f4 controllers: refactor rate limits.
Refactor controllers so that endpoint rate limits are declared locally,
with the endpoint, instead of globally, in a single method in ApplicationController.

This way an endpoint's rate limit is declared in the same file as the
endpoint itself.

This is so we can add fine-grained rate limits for certain GET requests.
Before rate limits were only for non-GET requests.
2021-12-10 01:46:01 -06:00
evazion
7976d12cd0 Fix #4930: "Show scores" setting should be preserved
Make "show scores" setting persistent.

The setting is stored in a `post_preview_show_votes` cookie. This means
it's remembered on a per-device basis, but not on a per-account basis.
This is so users without an account can use the setting, and so you can
use different settings on desktop and mobile.

The `view=score` URL param has been replaced by `show_votes=true`. The
`show_votes` URL param overrides the `post_preview_show_votes` cookie.
2021-12-09 15:47:10 -06:00
evazion
3de93f556e posts: make thumbnail size setting persistent.
Make setting the thumbnail size persistent.

The setting is stored in a `post_preview_size` cookie. This cookie can
be overridden by the `size` URL param, like so:

  https://danbooru.donmai.us/posts?tags=touhou&size=180

The `size` param is mainly for testing different sizes without setting a cookie.
2021-12-09 15:46:08 -06:00
evazion
8841de68ac posts: add adjustable thumbnail sizes (#4932).
Add a menu in the top right of the post index page that lets you select
the thumbnail size.

This menu is currently hidden until the new thumbnails have been generated.

On desktop, there are five thumbnail sizes:

* Small:    150x150 (https://danbooru.donmai.us/posts?size=150)
* Medium:   180x180 (https://danbooru.donmai.us/posts?size=180)
* Large:    225x225 (https://danbooru.donmai.us/posts?size=225)
* Huge:     270x270 (https://danbooru.donmai.us/posts?size=270)
* Gigantic: 360x360 (https://danbooru.donmai.us/posts?size=360)

On mobile, there are four sizes:

* Small:  150x150 / 3 posts per row (https://danbooru.donmai.us/posts?size=150)
* Medium: 180x180 / 2 posts per row (https://danbooru.donmai.us/posts?size=180)
* Large:  225x225 / 2 posts per row (https://danbooru.donmai.us/posts?size=225)
* Huge:   360x360 / 1 posts per row (https://danbooru.donmai.us/posts?size=360)

There are two extra sizes that aren't listed in the menu:

* 225x360 (https://danbooru.donmai.us/posts?size=225w)
* 270x360 (https://danbooru.donmai.us/posts?size=270w)

These sizes are good for tall thumbnails, but not so much for wide
thumbnails. They aren't listed because in practice they're a bit too big.

The 225x225 and 270x270 sizes are really just 360x360 thumbnails scaled
down in HTML. This means 225x225 and 360x360 thumbnails both use the
same amount of bandwidth.

Thumbnail size is currently a per-search option, not a persistent
account-level setting.

This changes the HTML structure of thumbnails somewhat, so this may
break userscripts and custom CSS.
2021-12-04 06:30:29 -06:00
evazion
9591fa1302 votes: fix bug with removing votes multiple times.
Fix an issue where if you tried to remove the same vote multiple times,
nothing would happen.

Specifically, if you upvoted a post in one tab, then opened it in a
second tab, then removed your vote in the first tab, then upvoted it
again in the first tab, then tried to remove your vote again in the
second tab, nothing would happen when removing it in the second tab.

This was because we were removing votes by vote ID, which meant that if
a vote had already been removed, removing it again would do nothing
since it was already deleted.
2021-11-25 23:49:18 -06:00
evazion
0baca68a37 search: make order:random truly random; add random:N metatag.
Make the `order:random` metatag truly randomize the search. Add a
`random:N` metatag that returns up to N random posts, like what
`order:random` did before.

`order:random` now returns the entire search in random order. Before it
just returned a pageful of pseudorandom posts. This will be more
accurate for small searches, but slower for large searches. If
`order:random` times out, try `random:N` instead.

The `random:N` metatag returns up to N pseudorandom posts. This is
faster than `order:random` for large searches, but for small searches,
it may return less than N posts, and the randomness may be biased. Some
posts may be more likely than others to appear. N must be between 0 and
200.

Also, `/posts?tags=touhou&random=1` now redirects to `/posts?tags=touhou+random:N`.
Before the `random=1` param acted like a free `order:random` tag; now it
redirects to a `random:N` search, so it counts against your tag limit.
2021-11-25 18:14:34 -06:00
evazion
a45e6b5cfe Fix #4931: Add popup voter list for comments.
Show the comment's upvote and downvote count when you hover over a
comment's score. For mods, show the list of voters as well.
2021-11-24 22:18:48 -06:00
evazion
353e708538 votes: allow admins to remove post votes.
Allow admins to remove votes on posts. This is for fixing vote abuse.

Votes can be removed by going to the vote list on the /post_votes page,
or by clicking on a post's score, then using the "Remove" option in the
"..." dropdown menu next to the vote.

Votes are soft-deleted - they're marked as deleted in the database, but
not fully deleted. Removed votes are only visible to admins, not to
regular users. When a vote is removed by an admin, it leaves a mod
action.

Technically it's possible to undelete votes, but there's no UI for it.
2021-11-23 23:18:54 -06:00
evazion
00befc96f0 /comments: add vote buttons beneath thumbnails on /comments page.
Also fix an N+1 queries problem.
2021-11-21 18:04:52 -06:00
evazion
3ae62d08eb favorites: show favlist when hovering over favcount.
Changes:

* Make it so you can click or hover over a post's favorite count to see
  the list of public favorites.
* Remove the "Show »" button next to the favorite count.
* Make the favorites list visible to all users. Before favorites were
  only visible to Gold users.
* Make the /favorites page show the list of all public favorites,
  instead of redirecting to the current user's favorites.
* Add /posts/:id/favorites endpoint.
* Add /users/:id/favorites endpoint.

This is for several reasons:

* To make viewing favorites work the same way as viewing upvotes.
* To make posts load faster for Gold users. Before, we loaded all the
  favorites when viewing a post, even when the user didn't look at them.
  This made pageloads slower for posts that had hundreds or thousands of
  favorites. Now we only load the favlist if the user hovers over the favcount.
* To make the favorite list visible to all users. Before, it wasn't
  visible to non-Gold users, because of the performance issue listed above.
* To make it more obvious that favorites are public by default. Before,
  since regular users could only see the favcount, they may have
  mistakenly believed other users couldn't see their favorites.
2021-11-20 02:40:18 -06:00
evazion
bd8672681f votes: add vote buttons beneath thumbnails.
Add upvote and downvote buttons beneath thumbnails on the post index page.

This is disabled by default. To enable it, click the "..." menu in the top
right of the page, then click "Show scores".

This is currently a per-search setting, not an account setting. If you
enable it in one tab, it won't be enabled in other tabs.
2021-11-18 04:15:20 -06:00
evazion
5585d1f7d6 votes: show votes when hovering over post score.
Make it so you can hover over a post's score to see the list of public
upvotes. Also show the upvote count, the downvote count, and the upvote
ratio.
2021-11-18 04:15:20 -06:00
evazion
a9997d0d2b favgroups: make private favgroups a Gold-only option.
Make private favgroups a Gold-only option. This is for consistency with
private favorites and upvotes being Gold-only options.

Existing Members with private favgroups are allowed to keep them, as
long as they don't disable privacy. If they disable it, then they can't
re-enable it again without upgrading to Gold first.
2021-11-18 04:15:20 -06:00
evazion
ab6d9bd0e8 post votes: fix exception when voting on posts using API.
Fix an `undefined method post_vote_url` exception when doing
`POST https://danbooru.donmai.us/posts/1/votes.json`.

Also add the following API endpoints:

* https://danbooru.donmai.us/post_votes/:id.json
* https://danbooru.donmai.us/comment_votes/:id.json
* https://danbooru.donmai.us/forum_post_votes/:id.json

where `:id` is the vote ID, not the post ID.
2021-11-14 20:11:38 -06:00
evazion
f1b5c34b4d posts: show length of videos and animations in thumbnails.
Show the length of videos and animated posts in the thumbnail. The
length is shown the top left corner in MM:SS format. This replaces the
play button icon.

Show a speaker icon instead of a music note icon for posts with sound.

Doing this requires doing `.includes(:media_asset)` in a bunch of
places to avoid N+1 queries when we access the post's duration.
2021-10-25 02:56:55 -05:00
evazion
1653392361 posts: stop updating fav_string attribute.
Stop updating the fav_string attribute on posts. The column still exists
on the table, but is no longer used or updated.

Like the pool_string in 7d503f08, the fav_string was used in the past to
facilitate `fav:X` searches. Posts had a hidden fav_string column that
contained a list of every user who favorited the post. These were
treated like fake hidden tags on the post so that a search for `fav:X`
was treated like a tag search.

The fav_string attribute has been unused for search purposes for a while
now. It was only kept because of technicalities that required
departitioning the favorites table first (340e1008e) before it could be
removed. Basically, removing favorites with `@favorite.destroy` was
slow because Rails always deletes object by ID, but we didn't have an
index on favorites.id, and we couldn't easily add one until the
favorites table was departitioned.

Fixes #4652. See https://github.com/danbooru/danbooru/issues/4652#issuecomment-754993802
for more discussion of issues caused by the fav_string (in short: write
amplification, post table bloat, and favorite inconsistency problems).
2021-10-09 22:36:26 -05:00
evazion
7d503f088e posts: stop using pool_string attribute.
Stop using the pool_string attribute on posts:

* Stop updating it when adding or removing posts from pools.
* Stop returning pool_string in the /posts.json API.
* Stop including the `data-pools` attribute on thumbnails.

The pool_string attribute was used in the past to facilitate pool:X
searches. Posts had a hidden pool_string attribute that contained a list
of every pool the post belonged to. These pools were treated like fake
hidden tags on the post and a search for `pool:X` was treated like a tag
search.

The pool_string has no longer been used for this purpose for a long time
now, and was only maintained for API compatibility purposes. Getting rid
of it eliminates a bunch of legacy cruft relating to adding and removing
posts from pools.

If you need to see which pools a post belongs to, do this:

* https://danbooru.donmai.us/pools.json?search[post_ids_include_any]=318550

The `data-pools` attribute on thumbnails was used by some people to add
custom borders to pooled posts with custom CSS. This will no longer
work. This was already broken because it included things like collection
pools and deleted pools, which you probably didn't want. Use a
userscript to add this attribute back to thumbnails if you need it.
2021-10-07 05:55:43 -05:00
evazion
ad523b3745 Fix #4895: Deleted forum topics visible by default in index.
The bug was that since search parameters normally come from URL request
parameters, a string value is expected here.
2021-10-01 17:14:48 -05:00
evazion
c99d0523bb /media_assets: add basic index and show pages.
* Add a basic index page at https://danbooru.donmai.us/media_assets.
* Add a basic show page at https://danbooru.donmai.us/media_assets/1.
* Add ability to search /media_assets.json by metadata. Example:
** https://danbooru.donmai.us/media_assets.json?search[metadata][File:ColorComponents]=3
* Add a "»" link next to the filesize on posts linking to the metadata page.

Known issues:

* Sometimes the MD5 links on the /media_assets page return "That record
  was not found" errors. These are unfinished uploads that haven't been
  made into posts yet.
* No good way to search for custom metadata fields in the search form.
* Design is ugly.
2021-09-29 07:46:11 -05:00
evazion
f9d25660b8 Fixup regression in 2eb89a835.
Fix regression in 2eb89a835 that broke the modqueue page because the
arguments to `paginated_search` changed and weren't updated here.

Also fix incorrect YARD documentation syntax.
2021-09-29 06:28:53 -05:00
evazion
2eb89a8354 Fix #4601: Hide deleted pools by default in pool search.
* On /pools, hide deleted pools by default in HTML responses. Don't
  filter out deleted pools in API responses.

* API change: on /forum_topics, only hide deleted forum topics by
  default for HTML responses, not for API responses. Explicitly do
  https://danbooru.donmai.us/forum_topics.json?search[is_deleted]=false
  to filter out deleted topics.

* API change: on /tags, only hide empty tags by default for HTML
  responses, not for API responses. Explicitly do
  https://danbooru.donmai.us/tags.json?search[is_empty]=false to filter
  out empty tags.

* API change: on /pools, default to 20 posts per page for API responses,
  not 40.

* API change: add `search[is_empty]` param to /tags.json endpoint.
  `search[hide_empty]=true` is deprecated in favor of `search[is_empty]=false`.

* On /pools, add option to show/hide deleted pools in search form.

* Fix the /forum_topics page putting `search[order]=sticky&limit=40` in
  the URL when browsing past page 1.
2021-09-29 05:44:59 -05:00
evazion
79fdfa86ae Fix various rubocop warnings. 2021-09-27 00:46:13 -05:00
evazion
4cc8dd41ec puma: add rack-timeout gem.
Unlike Unicorn, Puma doesn't have a builtin HTTP request timeout
mechanism, so we have to use Rack::Timeout instead.

See the caveats in the Rack::Timeout documentation [1]. In Unicorn, a
timeout would send a SIGKILL to the worker, immediately killing it. This
would result in a dropped connection and a Cloudflare 502 error to the
user. In Puma, it raises an exception, which we can catch and return a
better error to the user. On the other hand, raising an exception can
potentially corrupt application state if it's sent at the wrong time, or
be delayed indefinitely if the app is stuck in IO or C extension code.

The default request timeout is 65 seconds. 65 seconds is to give things
like HTTP requests on a 60 second timeout enough time to complete. Set
the RACK_REQUEST_TIMEOUT environment variable to change the timeout.

1: https://github.com/sharpstone/rack-timeout#further-documentation
2021-09-12 09:32:12 -05:00
evazion
3d660953d4 Add MediaMetadata model.
Add a model for storing image and video metadata for uploaded files.

Metadata is extracted using ExifTool. You will need to install ExifTool
after this commit. ExifTool 12.22 is the minimum required version
because we use the `--binary` option, which was added in this release.

The MediaMetadata model is separate from the MediaAsset model because
some files contain tons of metadata, and most of it is non-essential.
The MediaAsset model represents an uploaded file and contains essential
metadata, like the file's size and type, while the MediaMetadata model
represents all the other non-essential metadata associated with a file.

Metadata is stored as a JSON column in the database.

ExifTool returns all the file's metadata, not just the EXIF metadata.
EXIF is one of several types of image metadata, hence why we call
it MediaMetadata instead of EXIFMetadata.
2021-09-08 05:00:54 -05:00
evazion
4dcfd1d141 aliases/implications: log manual deletions by admins.
Log when an admin manually deletes an alias or implication outside of a
BUR. This is usually only necessary when a BUR is bugged.
2021-09-06 03:25:02 -05:00
evazion
b068c113a8 Add MediaAsset model.
A MediaAsset represents an image or video file uploaded to Danbooru. It
stores the metadata associated with the image or video. This is to work
on decoupling files from posts so that images can be uploaded separately
from posts.
2021-09-02 06:07:52 -05:00
evazion
c29539d44e /posts/random: fix reorder(nil).first deprecation warning
DEPRECATION WARNING: `.reorder(nil)` with `.first` / `.first!` no
    longer takes non-deterministic result in Rails 6.2. To continue
    taking non-deterministic result, use `.take` / `.take!` instead.
    (called from random at /home/user/src/danbooru/app/controllers/posts_controller.rb:91)
2021-09-02 04:09:03 -05:00
evazion
1bb383703d iqdb: allow searching images by iqdb hash.
Example:

    https://danbooru.donmai.us/iqdb_queries?search[hash]=iqdb_3fe4c0bd5a88fab53fbe5104efdc43ba3fa094416e6e039cf880f9f1fafafafffc80fd7bfd7dfd80fe72fe79fe80fefafefdfeffff75ff79ff7aff7dfff1fffb000100020003000400080082008a00940184018802000287028c028f030004000600078308001080ef80f800f8fdf900fafdfc00fc7dfcfafe00fe72fefdff7effdffff0fff8fffcfffd0007000f001f003e0080008f0106018d02800282038003810403040806800683070b078007870d800d830f801f00f800f96cfa76fb00fb7efbf4fc00fcfdfd00fd74fdfbfe78fe7efef5fef9fefbfefeff6cff76ff7efffcfffe00070080008300860087008b01030106018002820283028503800402040a0502058b0d80

The hash may be obtained from a regular IQDB search, or by calculating
it yourself (an exercise for the reader).
2021-09-02 03:37:36 -05:00
Lily
8d49d35ab1 make appeals editable 2021-06-29 14:43:27 -03:00
evazion
ad4c75eb1a docs add more docs to app/{jobs,logical}.
These were missed in the last commit.
2021-06-28 05:09:19 -05:00
evazion
0563ca3001 docs: document config/ and some directories in app/.
* Add README files to several directories in app/ giving a brief
  overview of some parts of Danbooru's architecture.
* Add documentation for files in config/.
2021-06-27 05:21:38 -05:00
evazion
07e23204b6 rubocop: fix various Rubocop warnings. 2021-06-17 04:17:53 -05:00
evazion
0f36bbf8d3 iqdb: update API client to use new version of IQDB.
Replace the old IQDB API client with a new client for the new forked
version of IQDB at https://github.com/danbooru/iqdb.

Changes:

* The /iqdb_queries endpoint now returns `hash` and `signature` fields.
  The `signature` is the full decoded Haar signature, while the `hash`
  is a encoded version of the signature.
* The /iqdb_queries endpoint no longer returns `width` and `height`
  fields in the response (these were always 128x128).
* We no longer need the IQDBs frontend server, now we talk to the IQDB
  instance directly.
* We no longer send add/remove image commands to IQDB through AWS SQS,
  now we send them to IQDB directly. They are sent in a delayed job so
  that if IQDB is down, uploading images is still possible, the add
  image commands will just get queued up.
* Fix a bug where regenerating an image's thumbnails didn't regenerate
  IQDB, because IQDB silently ignored add image commands when the image
  already existed in the database.
2021-06-16 05:36:24 -05:00
evazion
24ead500f0 users: use sudo mode when changing email addresses.
When a user tries to change their email, redirect them to the confirm
password page (like Github's sudo mode) instead of having them re-enter
their password on the change email page. This is the same thing we do
when a user updates their API keys. This way we have can use the same
confirm password authentication flow for everything that needs a
password.
2021-05-19 01:10:03 -05:00