Commit Graph

1642 Commits

Author SHA1 Message Date
evazion
6f5aef1cef uploads: fix being redirected to blank page when rating is not selected.
Fix the upload page redirecting you to a blank page if you forgot to
select the rating on a multi-asset upload.

ref: https://danbooru.donmai.us/forum_posts/206365
2022-02-23 02:50:40 -06:00
evazion
60a26af6e3 rails: add 'URL' inflection.
Make it so we can write `ArtistURL` instead of `ArtistUrl`.
2022-02-22 00:17:53 -06:00
evazion
68ba447494 uploads: remove batch upload page.
* Make /uploads/batch redirect to /uploads/new.
* Remove /uploads/image_proxy.
2022-02-21 00:03:43 -06:00
evazion
093a808a36 Fix #4986: Add ability to filter images in /media_assets and /uploads depending on if they have become posts 2022-02-18 03:39:08 -06:00
evazion
0b8d042c06 uploads: allow changing thumbnail size on My Uploads / All Uploads pages.
* Add a "Size" menu to the My Uploads / All Uploads pages to allow
  changing the thumbnail size.
* Make the My Uploads / All Uploads pages use the same thumbnail size as
  the post index page.
* Change the "Gallery | Table" links on the My Uploads page to icons.
2022-02-16 16:39:28 -06:00
evazion
f890e8595e uploads: respect user's posts-per-page setting on My Uploads page. 2022-02-16 16:38:47 -06:00
evazion
7c3586f985 uploads: make gallery mode the default on the My Uploads page. 2022-02-16 16:38:47 -06:00
evazion
049750e512 uploads: fix My Uploads page showing Admins uploads for other users.
Fix the "My Uploads" page showing Admins all uploads, not just their own
uploads.

Changes the URL of the My Uploads page from /uploads to /users/:id/uploads.
2022-02-16 14:11:40 -06:00
evazion
5b2fcaaafc uploads: default to only showing completed uploads.
Default to only showing completed uploads on the My Uploads page, not
failed or processing uploads.
2022-02-14 16:00:22 -06:00
evazion
bdf83d1ffd uploads: refactor /uploads/:id page for multi-file uploads. 2022-02-14 00:41:08 -06:00
evazion
229759cc72 uploads: add /upload_media_assets index page.
This page shows each individual file you've uploaded. This is different
from the regular uploads page because files in multi-file uploads are
not grouped together.
2022-02-14 00:41:08 -06:00
evazion
53a3beee35 uploads: refactor "My Uploads" page for multi-file uploads.
* Make thumbnails on the "My Uploads" page show an icon with an image
  count when an upload contains multiple files.

* Make the "My Uploads" page show each upload, not each individual file.
  If an upload contains multiple files, they're shown grouped together
  under a single upload. This does mean that failed or duplicate uploads
  will show up on this page now. This is because this page shows each
  upload attempt, not each uniquely uploaded file.
2022-02-14 00:41:07 -06:00
evazion
5bb64596cb uploads: include media assets in API response.
Include media assets in /uploads.json and /uploads/:id.json API responses, like this:

    {
      "id": 4983629,
      "source": "https://www.pixiv.net/en/artworks/96198438",
      "uploader_id": 52664,
      "status": "completed",
      "created_at": "2022-02-12T16:26:04.680-06:00",
      "updated_at": "2022-02-12T16:26:08.071-06:00",
      "referer_url": "",
      "error": null,
      "media_asset_count": 1,
      "upload_media_assets": [
        {
          "id": 9370,
          "created_at": "2022-02-12T16:26:08.068-06:00",
          "updated_at": "2022-02-12T16:26:08.068-06:00",
          "upload_id": 4983629,
          "media_asset_id": 5206552,
          "status": "pending",
          "source_url": "https://i.pximg.net/img-original/img/2022/02/13/01/20/19/96198438_p0.jpg",
          "error": null,
          "page_url": "https://www.pixiv.net/artworks/96198438",
          "media_asset": {
            "id": 5206552,
            "created_at": "2022-02-12T16:26:07.980-06:00",
            "updated_at": "2022-02-12T16:26:08.061-06:00",
            "md5": "90a85a5fae5f0e86bdb2501229af05b7",
            "file_ext": "jpg",
            "file_size": 1055775,
            "image_width": 1052,
            "image_height": 1545,
            "duration": null,
            "status": "active"
          }
        }
      ]
    }

This is needed so you can check for upload errors in the API, since in a multi-file
upload, each asset can have a separate error message. This is a stopgap solution until
something like /uploads.json?include=upload_media_assets.media_asset works.
2022-02-12 16:48:34 -06:00
evazion
37ad6f5a71 Fix non-existent .js requests raising DoubleRenderError.
Fix requests for non-existent .js pages, for example https://danbooru.donmai.us/oaisfj.js,
raising AbstractController::DoubleRenderError when trying to render the 404 response.
2022-02-08 00:14:38 -06:00
evazion
345a222163 Fix #4999: Unexpected error: ActiveRecord::RecordNotUnique sometimes appears when uploading posts
Fix two issues that could lead to duplicate errors when creating posts:

* Fix the submit button on the upload form to disable itself on submit, to prevent
  accidental double submit errors.

* Fix a race condition when checking for MD5 duplicates. MD5 uniqueness is checked on both
  the Rails level, with a uniqueness validation, and on the database level, with a unique
  index on the md5 column. Creating a post could fail with an ActiveRecord::RecordNotUnique
  error if the uniqueness validation in Rails passed, but the uniqueness constraint in the
  database failed. In this case, we catch the RecordNotUnique error and convert it to a
  Rails validation error so we can treat it like a normal validation failure.
2022-02-07 21:02:30 -06:00
evazion
7bed81812d Don't show error messages that could contain private information.
Fix a potential exploit where private information could be leaked if
it was contained in the error message of an unexpected exception.

For example, NoMethodError contains a raw dump of the object in the
error message, which could leak private user data if you could force a
User object to raise a NoMethodError.

Fix the error page to only show known-safe error messages from expected
exceptions, not unknown error messages from unexpected exceptions.

API changes:

* JSON errors now have a `message` param. The message will be blank for unknown exceptions.
* XML errors have a new format. This is a breaking change. They now look like this:

    <result>
      <success type="boolean">false</success>
      <error>PaginationExtension::PaginationError</error>
      <message>You cannot go beyond page 5000.</message>
      <backtrace type="array">
        <backtrace>app/logical/pagination_extension.rb:54:in `paginate'</backtrace>
        <backtrace>app/models/application_record.rb:17:in `paginate'</backtrace>
        <backtrace>app/logical/post_query_builder.rb:529:in `paginated_posts'</backtrace>
        <backtrace>app/logical/post_sets/post.rb:95:in `posts'</backtrace>
        <backtrace>app/controllers/posts_controller.rb:22:in `index'</backtrace>
      </backtrace>
    </result>

  instead of like this:

    <result success="false">You cannot go beyond page 5000.</result>
2022-02-06 18:09:54 -06:00
evazion
b3405d4947 uploads: fix exception on /uploads page when given invalid mode. 2022-02-03 22:00:31 -06:00
evazion
2c0feaf943 Fix #4988: 'my uploads' page has different links on 'gallery' mode vs 'table' mode
Fix a bug where images on the My Uploads page would link to the wrong
upload. If an image had been uploaded by multiple users, then it would
link to the first upload belonging to the first person to upload the
image. This would lead to an Access Denied error when you tried to open
the upload.

Also fix a bug where uploads on the My Uploads page were ordered
incorrectly. They were ordered by most recent asset first, rather than
most recent upload first. This meant if you uploaded an image someone
else had already uploaded, then it would appear behind your other more
recent uploads.
2022-02-03 21:58:55 -06:00
evazion
2b1c58c959 Fix #4987: Can't populate tag string from upload url anymore.
Usage: https://danbooru.donmai.us/uploads/new?url=...&post[tag_string]=...&post[rating]=...

* Pass the URL parameters from the /uploads/new page to the /uploads/:id page.
* Fix the /uploads/:id page throwing an "unpermitted parameters" error
  when given URL params for the post edit form.
2022-02-03 19:41:04 -06:00
evazion
7e146611d1 uploads: add space after artist tag (fix #4392). 2022-02-03 17:09:26 -06:00
evazion
2dfec29da7 uploads: mark old columns as ignored.
Mark old columns as ignored in preparation for dropping them. Make the
rating and tag_string nullable so they don't have to be set when
creating uploads and can be ignored too.
2022-02-03 14:07:09 -06:00
evazion
054b0b4d0a uploads: add thumbnail view to /uploads listing.
Add a thumbnail view to the /uploads listing. You can click on images to
resume the upload, or go to the post if it's already been posted.
2022-02-02 01:50:34 -06:00
evazion
317d369c6a uploads: fixup bug in 2d47ae70b causing disk uploads to fail.
Fix a nil dereference error when uploading files from disk.
2022-02-01 13:53:52 -06:00
evazion
2d47ae70b0 Fix #4392: Automatically add artist tag to tagbox on upload page 2022-02-01 09:47:13 -06:00
evazion
60a13fd2d5 Fix #4913: Invalid replacements created if an error is raised during replacement
Perform the replacement in a before_create callback so that it runs in a
transaction and if it fails, the transaction will rollback and the
replacement record won't be created.

Doing the replacement in a transaction isn't great because, for one
thing, it could hold the transaction open a long time, which isn't good
for the database. And two, if the transaction rolls back, the database
changes will be undone, but if the replacement file has already been saved
to disk, then it won't be undone, which could result in a dangling file.
2022-02-01 01:14:41 -06:00
evazion
65b7c08e33 post replacements: refactor and fix tests.
* Move replacement tests from test/unit/upload_service_test.rb to
  test/functional/post_replacement_controller_test.rb
* Move UploadService::Replacer to PostReplacementProcessor.
* Fix a minor bug where if you used the API to replace a post with a file,
  the replacement would fail unless you passed an empty string for the
  replacement_url.
2022-01-31 14:17:14 -06:00
evazion
0132c5f0a5 media assets: fix md5 leak in media assets.
Fix unprivileged users being able to see images and MD5 hashes of media
assets belonging to censored posts.
2022-01-30 23:23:55 -06:00
evazion
2fe058eccf uploads: fix tag warnings not being shown after upload.
Fix the warnings about not having enough tags, or not having an artist
or copyright tag, not being shown after creating a new post.
2022-01-30 22:39:54 -06:00
evazion
43c4158d36 uploads: merge tags when a duplicate is uploaded (fix #3130).
Automatically merge tags when uploading a duplicate.

There are two cases:

* You try to upload an image, but it's already on Danbooru. In this case
  you'll be immediately redirected to the original post, before you
  can start tagging the upload.

* You're uploading an image, it wasn't a dupe when you first opened the
  upload page, but you got sniped while tagging it. In this case your tags
  will be merged with the original post, and you will be redirected to the
  original post.

There are a few corner cases:

* If you don't have permission to edit the original post, for example
  because it's banned or has a censored tag, then your tags won't be
  merged and will be silently ignored.

* Only the tags, rating, and parent ID will be merged. The source and
  artist commentary won't be merged. This is so that if an artist uploads
  the exact same file to multiple sites, the new source won't override
  the original source.

* Some tags might be contradictory. For example, the new post might
  be tagged translation_request, but the original post might already be
  translated. It's up to the user to fix these things afterwards.
2022-01-30 03:14:22 -06:00
evazion
21dcf53dcb uploads: show similar images for disk uploads.
Fix the upload page so that it shows similar images (IQDB matches) for
files uploaded from your computer. Before this only worked for files
uploaded from a source.
2022-01-28 21:07:06 -06:00
evazion
abdab7a0a8 uploads: rework upload process.
Rework the upload process so that files are saved to Danbooru first
before the user starts tagging the upload.

The main user-visible change is that you have to select the file first
before you can start tagging it. Saving the file first lets us fix a
number of problems:

* We can check for dupes before the user tags the upload.
* We can perform dupe checks and show preview images for users not using the bookmarklet.
* We can show preview images without having to proxy images through Danbooru.
* We can show previews of videos and ugoira files.
* We can reliably show the filesize and resolution of the image.
* We can let the user save files to upload later.
* We can get rid of a lot of spaghetti code related to preprocessing
  uploads. This was the cause of most weird "md5 confirmation doesn't
  match md5" errors.

(Not all of these are implemented yet.)

Internally, uploading is now a two-step process: first we create an upload
object, then we create a post from the upload. This is how it works:

* The user goes to /uploads/new and chooses a file or pastes an URL into
  the file upload component.
* The file upload component calls `POST /uploads` to create an upload.
* `POST /uploads` immediately returns a new upload object in the `pending` state.
* Danbooru starts processing the upload in a background job (downloading,
  resizing, and transferring the image to the image servers).
* The file upload component polls `/uploads/$id.json`, checking the
  upload `status` until it returns `completed` or `error`.
* When the upload status is `completed`, the user is redirected to /uploads/$id.
* On the /uploads/$id page, the user can tag the upload and submit it.
* The upload form calls `POST /posts` to create a new post from the upload.
* The user is redirected to the new post.

This is the data model:

* An upload represents a set of files uploaded to Danbooru by a user.
  Uploaded files don't have to belong to a post. An upload has an
  uploader, a status (pending, processing, completed, or error), a
  source (unless uploading from a file), and a list of media assets
  (image or video files).

* There is a has-and-belongs-to-many relationship between uploads and
  media assets. An upload can have many media assets, and a media asset
  can belong to multiple uploads. Uploads are joined to media assets
  through a upload_media_assets table.

  An upload could potentially have multiple media assets if it's a Pixiv
  or Twitter gallery. This is not yet implemented (at the moment all
  uploads have one media asset).

  A media asset can belong to multiple uploads if multiple people try
  to upload the same file, or if the same user tries to upload the same
  file more than once.

New features:

* On the upload page, you can press Ctrl+V to paste an URL and immediately upload it.
* You can save files for upload later. Your saved files are at /uploads.

Fixes:

* Improved error messages when uploading invalid files, bad URLs, and
  when forgetting the rating.
2022-01-28 04:13:22 -06:00
evazion
90be15e0b5 Fix #4973: Wiki pages json index returns 404.
Fix regression introduced in 0db20e0ca. Setting `format: false` on the
wiki pages resource disabled format negotiation on all wiki page routes,
not just the show page, which meant /wiki_pages.json no longer worked.

The fix to monkey patch the internal Rails method that parses the file
extension from the URL, and have it ignore everything but the .html,
.json, .js, and .xml extensions. This is really hacky and may break in
future Rails releases.
2022-01-22 16:52:20 -06:00
evazion
56722df753 forum: delete posts when topic is deleted.
Fix it so that when a forum topic is deleted, all posts in the topic are
deleted too. Also make it so that when a forum topic is undeleted, all
posts in it are undeleted too.

Before when a topic was deleted, only the topic itself was marked as
deleted, not the posts inside the topic. This meant that when a spam
topic was deleted, the OP wouldn't be marked as deleted, so any
modreports against it wouldn't be marked as handled.

Also change it so that it's not possible to undelete a post in a deleted
topic, or to delete the OP of a topic without deleting the topic itself.

Finally, add a fix script to delete all active posts in deleted topics,
and to undelete all deleted OPs in active topics.
2022-01-21 22:35:20 -06:00
evazion
5fd0d498a4 modreports: log modaction when report is handled or rejected. 2022-01-20 21:28:29 -06:00
evazion
c8d27c2719 Fix #4669: Track moderation report status.
* Add ability to mark moderation reports as 'handled' or 'rejected'.
* Automatically mark reports as handled when the comment or forum post
  is deleted.
* Send a dmail to the reporter when their report is handled.
* Don't show the report notice on comments or forum posts when all
  reports against it have been handled or rejected.
* Add a fix script to mark all existing reports for deleted comments,
  forum posts, or dmails as handled.
2022-01-20 20:50:23 -06:00
evazion
0db20e0cab Fix #4591: Wiki pages with filename-like name are broken by default.
Fix wiki pages like this returning 406 errors:

* https://danbooru.donmai.us/wiki_pages/rnd.jpg

Caused by Rails parsing the .jpg part as a file extension and trying to
return a JPEG in response. This happens deep in Rails' MIME negotiation
code, so it's hard to override. The fix is to pass `format: false` in
the route to disable all special handling of file extensions by Rails,
and then handle it ourselves in the controller. Ugly.

This only affected two tags: `rnd.jpg` and `haru.jpg`.
2022-01-19 21:44:40 -06:00
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