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.
This commit is contained in:
evazion
2021-03-05 16:25:23 -06:00
parent 1ee1e807cf
commit 58e42ee8d3
6 changed files with 84 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
class RateLimitsController < ApplicationController
respond_to :html, :json, :xml
def index
@rate_limits = authorize RateLimit.visible(CurrentUser.user).paginated_search(params, count_pages: true)
respond_with(@rate_limits)
end
end

View File

@@ -5,6 +5,22 @@ class RateLimit < ApplicationRecord
expired.delete_all
end
def self.visible(user)
if user.is_owner?
all
elsif user.is_anonymous?
none
else
where(key: [user.cache_key])
end
end
def self.search(params)
q = search_attributes(params, :id, :created_at, :updated_at, :limited, :points, :action, :key)
q = q.apply_default_order(params)
q
end
# `action` is the action being limited. Usually a controller endpoint.
# `keys` is who is being limited. Usually a [user, ip] pair, meaning the action is limited both by the user's ID and their IP.
# `cost` is the number of points the action costs.

View File

@@ -0,0 +1,5 @@
class RateLimitPolicy < ApplicationPolicy
def index?
true
end
end

View File

@@ -0,0 +1,21 @@
<div id="c-rate-limits">
<div id="a-index">
<%= table_for @rate_limits, class: "striped autofit" do |t| %>
<% t.column :action %>
<% t.column :key %>
<% t.column :points do |rate_limit| %>
<%= rate_limit.points.round(2) %>
<% end %>
<% t.column :limited? %>
<% t.column :updated_at do |rate_limit| %>
<%= time_ago_in_words_tagged rate_limit.updated_at %>
<% end %>
<% end %>
<%= numbered_paginator(@rate_limits) %>
</div>
</div>

View File

@@ -220,6 +220,7 @@ Rails.application.routes.draw do
end
end
resources :artist_commentary_versions, :only => [:index, :show]
resources :rate_limits, only: [:index]
resource :related_tag, :only => [:show, :update]
resources :recommended_posts, only: [:index]
resources :robots, only: [:index]

View File

@@ -0,0 +1,33 @@
require 'test_helper'
class RateLimitsControllerTest < ActionDispatch::IntegrationTest
context "The rate limits controller" do
context "index action" do
setup do
@user = create(:user)
create(:rate_limit, key: @user.cache_key)
end
should "show all rate limits to the owner" do
get_auth rate_limits_path, create(:owner_user)
assert_response :success
assert_select "tbody tr", count: 2 # 2 because the login action creates a second rate limit.
end
should "show the user their own rate limits" do
get_auth rate_limits_path, @user
assert_response :success
assert_select "tbody tr", count: 1
end
should "not show users rate limits belonging to other users" do
get_auth rate_limits_path, create(:user)
assert_response :success
assert_select "tbody tr", count: 0
end
end
end
end