Commit Graph

113 Commits

Author SHA1 Message Date
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
Lily
8d49d35ab1 make appeals editable 2021-06-29 14:43:27 -03:00
evazion
07e23204b6 rubocop: fix various Rubocop warnings. 2021-06-17 04:17:53 -05:00
evazion
2537145b02 users: disallow banned users from changing email or deleting account.
This is to prevent people from wiping their email address after they've
been banned and reusing it to verify a new account.
2021-05-15 04:36:22 -05:00
evazion
b3c1c753b3 comments: allow admins to remove comment votes (fix #4640)
Allow admins to remove comment votes by other users. This is done by
clicking the comment score to get to the comment vote list, then
clicking the Remove button on every vote.
2021-03-30 00:10:25 -05:00
evazion
6a84d33409 Fix #4770: Allow flaggers to update flag reason. 2021-03-23 01:27:16 -05:00
evazion
81fe68d392 bans: change expires_at field to duration.
Changes:

* Change the `expires_at` field to `duration`.
* Make moderators choose from a fixed set of standard ban lengths,
  instead of allowing arbitrary ban lengths.
* List `duration` in seconds in the /bans.json API.
* Dump bans to BigQuery.

Note that some old bans have a negative duration. This is because their
expiration date was before their creation date, which is because in 2013
bans were migrated to Danbooru 2 and the original ban creation dates
were lost.
2021-03-11 02:59:58 -06:00
evazion
791b8c61f6 post disapprovals: fix disapprovers being visible in API. 2021-03-11 02:59:56 -06:00
evazion
5a790ee25a wiki pages: remove category_name field from API.
Remove the `category_name` field from the `/wiki_page.json` API. This
field was originally added only because it was needed by our autocomplete
Javascript. It was also misnamed, it wasn't the tag's category name, it
was the category's ID.

Users should use `https://danbooru.donmai.us/wiki_pages.json?only=title,tag`
instead if they need this.

This triggered a N+1 query pattern when dumping wiki pages to BigQuery,
which made dumping wiki pages very slow. It also meant this field was
included in the database dump, even though it wasn't a real database
column.
2021-03-10 03:08:49 -06:00
evazion
58e42ee8d3 rate limits: add /rate_limits endpoint.
Allow users to view their own rate limits with /rate_limits.json.

Note that rate limits are only updated after every API call, so this
page only shows the state of the limits after the last call, not the
current state.
2021-03-05 16:47:20 -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
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
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
e23f09235e artists: redact version histories of banned artists.
Fix names and urls of banned artists being visible in Google through
artist version pages.
2021-02-07 23:28:50 -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
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
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
5780ed5768 comments: add scores, rework comment menu.
* Add comment scores.
* Rework voting buttons so that you can click the upvote/downvote
  buttons to toggle votes.
* Hide the edit, delete, undelete, and report buttons behind a popup menu.
* Show the upvote/downvote/reply buttons to logged out users. Redirect
  them to the login page instead.
2021-01-20 04:41:21 -06:00
evazion
027359a2c1 comments: fix modreport notices being visible to Members.
Fix the "This comment has been reported" notice being visible for
Members.
2021-01-19 06:05:51 -06:00
evazion
e1e3604f46 comments: rework deleted comments.
Let users see when a post has deleted comments. Show normal users a
'[deleted]' placeholder when a comment is deleted. Show the full comment
to moderators.

Also fix it so that the comment creator can't edit or undelete deleted
comments, and users can't vote on or report deleted comments.

Finally, hide the creator_id, updater_id, and body of deleted comments
in the API.
2021-01-19 04:34:51 -06:00
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
6671711784 dmails, emails: refactor to use Rails signed_id.
Refactor email verification links and Dmail share links to use the new
Rails signed_id mechanism, rather than our own handrolled mechanism.

For Dmail share links, we have to override some Rails internal methods
so that our old links still work. For email verification links, this
will invalidate existing links, but this isn't a huge deal since these
links are short-lived anyway.

https://api.rubyonrails.org/classes/ActiveRecord/SignedId.html
https://api.rubyonrails.org/classes/ActiveRecord/SignedId/ClassMethods.html
2021-01-17 00:24:02 -06:00
evazion
50a75e2ec5 modreports: allow users to see modreports they've submitted. 2021-01-16 02:19:25 -06:00
evazion
e7cdae33b2 modreports: remove dead code. 2021-01-16 01:34:38 -06:00
evazion
b4530183f4 Fix #4525: Show mod report notices next to reported content. 2021-01-16 01:02:42 -06:00
evazion
d408ccbd41 users: remove option to disable autocomplete.
This option was originally added in issue #1747. But only ~350 users
ever disabled autocomplete, only ~120 of these were seen in the last
year, and only 9 new users who signed up in the last year disabled it.

Users wishing to disable autocomplete can use this CSS:

    .ui-autocomplete { display: none !important: }

or this Javascript:

    $("[data-autocomplete]").autocomplete("disable");
2021-01-15 02:03:54 -06:00
evazion
99d447279b users: remove option to disable keyboard shortcuts.
Remove the enable_post_navigation option. This option was originally
added to disable the next/prev post navbar beneath posts. It was later
repurposed to disable keyboard shortcuts.

Users who don't want keyboard shortcuts are advised to not press random
buttons on the keyboard like a caveman.

Only ~1200 users disabled this option and only ~600 were seen in the
last year.
2021-01-15 02:03:54 -06:00
evazion
b6fef7f3f3 users: remove option to disable search navbar.
Remove the enable_sequential_post_navigation option. This option was
used to disable the next/previous post navbar below posts.

This option was originally added in issue #674 because of people
complaining about the navbar when it was originally added. Also there
were complaints about URLs being uglier because of search params in the
URL (e.g. /posts/1234?q=touhou). There were also various minor bugs with
it at the time, such as keyboard shortcuts not working correctly, or the
page not remembering your search after a tag edit.

These complaints are irrelevant nowadays because a) people are used to
the navbar by now (and more often complain about it *not* being there
for order:score searches), b) post URLs always contain the search now,
this option hasn't disabled that for years, and c) the initial bugs with
it were fixed years ago.

Only ~1000 users disabled this option and only ~600 were seen in the last year.

Users still wishing to hide the search navbar can use custom CSS instead.
2021-01-15 02:03:54 -06:00
evazion
7537edb211 user events: let mods only see login/logout/signup events.
Adjust permissions on user events to let Moderators only see login,
logout, and user creation events, not other types of events (password
changes, etc). Admins can see everything. These other types of events
are meant for account security purposes and aren't very relevant for
sockpuppet detection purposes.
2021-01-12 19:29:37 -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
df44937c57 post regenerations: replace PostRegeneration model with mod actions.
* Remove the PostRegeneration model. Instead just use a mod action
  to log when a post is regenerated.

* Change it so that IQDB is also updated when the image samples are
  regenerated. This is necessary because when the images samples are
  regenerated, the thumbnail may change, which means IQDB needs to be
  updated too. This can happen when regenerating old images with
  transparent backgrounds where the transparency was flattened to black
  instead of white in the thumbnail.

* Only display one "Regenerate image" option in the post sidebar, to
  regenerate both the images and IQDB. Regenerating IQDB only can be
  done through the API. Having two options in the sidebar is too much
  clutter, and it's too confusing for Mods who don't know the difference
  between an IQDB-only regeneration and a full image regeneration.

* Add a confirm prompt to the "Regenerate image" link.
2021-01-04 21:35:43 -06:00
BrokenEagle
16d6f3bbd5 Add post regenerations 2021-01-04 18:35:50 -06:00
evazion
de16d31135 favorites: remove is_favorited attribute from post API.
* Remove the data-is-favorited attribute from post thumbnails.
* Remove the is_favorited attribute from the /posts.json API.
* Remove the fav_string attribute from the /posts.json API (only visible
  to moderators).
* Change `Post#favorited_by?` to not use the fav_string.

Further addresses #4652 by eliminating the last places where fav_string
was used.
2021-01-03 19:58:43 -06:00
evazion
4b171bf97e user upgrades: add ability to refund upgrades. 2020-12-29 04:17:32 -06:00
evazion
87af02f689 user upgrades: add links to Stripe payment & receipt page.
Add links to the Stripe payment page and the Stripe receipt page on
completed user upgrades.

The Stripe payment link is a link to the payment details on the Stripe
dashboard and is only visible to the owner.
2020-12-29 00:19:52 -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
069231a33b user upgrades: update upgrade landing page.
* Add a frequently asked questions section.
* Add nicer looking upgrade buttons.
* Format the page nicer.
* Prevent users from attempting invalid upgrades on users that are
  already Platinum or above.
2020-12-25 00:47:08 -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
fbb4cfb807 users: let mods see users' last login time. 2020-12-21 22:42:50 -06:00
evazion
4cb39422b2 post replacements: rename <attr>_was to old_<attr>
Rename the following post replacement attributes:

* file_size_was -> old_file_size
* file_ext_was -> old_file_ext
* image_width_was -> old_image_width
* image_height_was -> old_image_height
* md5_was -> old_md5

In Rails 6.1, having attributes named `file_size` and `file_size_was` on
the same model breaks things because it conflicts with Rails' dirty
attribute tracking.
2020-12-19 14:26:07 -06:00
evazion
eae3c1942d dmails: allow site owner to read all mails.
Allow site owner to read dmails sent to other users. This is make it
easier to investigate spam without having to drop into the dev console.
2020-12-13 23:59:53 -06:00
evazion
2e633f84f6 emails: add /emails index page.
Add emails index page at https://danbooru.donmai.us/emails. Mods can use
this page to view and search emails belonging to users below mod level.
2020-12-13 21:21:08 -06:00
evazion
67eefadd7f users: let mods see email addresses on user profiles.
* Let Mods and Admins see the email addresses of users below their level.
* Let users see their own email address on their profile.
* Let users verify or edit their email address from their profile.

This is to make catching sockpuppets easier, and to make it easier for
users to fix their email.
2020-12-13 21:21:08 -06:00
evazion
9f09c495e4 users: don't allow admins to edit user levels directly.
Don't allow admins to bypass promotion restrictions by manually updating
user levels with a `PUT /users/:id` API call. Level changes have to go
through the /admin/users/:id/edit page.
2020-12-13 21:21:08 -06:00
evazion
86bba56eda users: allow site owner to reset passwords of other users. 2020-12-13 21:21:08 -06:00
evazion
7f90bc4216 BURs: remove ability to skip secondary validations.
Remove the ability to skip secondary validations when creating a BUR.
The only skippable validation that still existed was the requirement
that both tags in an implication must have wiki pages. It's now
mandatory to write wiki pages for tags before you can request an
implication. This doesn't apply to empty tags.
2020-11-12 20:15:14 -06:00
evazion
4c3b4671ef ip addresses: fix exception on ip_addresses/show page. 2020-08-18 11:16:26 -05:00
evazion
937653e519 models: move html_data_attributes to policies.
Move html_data_attributes definitions from models to policies. Which
attributes are permitted as data-* attributes is a view level concern
and should be defined on the policy level, not the model level. Models
should be agnostic about how they're used in views.
2020-08-17 22:33:18 -05:00