Add admin API for managing IP blocks (#19065)

pull/19066/head^2
Eugen Rochko 2022-08-27 20:56:47 +02:00 committed by GitHub
parent ff19dad5a0
commit b399d79545
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 120 additions and 1 deletions

View File

@ -0,0 +1,99 @@
# frozen_string_literal: true
class Api::V1::Admin::IpBlocksController < Api::BaseController
include Authorization
include AccountableConcern
LIMIT = 100
before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:ip_blocks' }, only: [:index, :show]
before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:ip_blocks' }, except: [:index, :show]
before_action :set_ip_blocks, only: :index
before_action :set_ip_block, only: [:show, :update, :destroy]
after_action :verify_authorized
after_action :insert_pagination_headers, only: :index
PAGINATION_PARAMS = %i(
limit
).freeze
def create
authorize :ip_block, :create?
@ip_block = IpBlock.create!(resource_params)
log_action :create, @ip_block
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end
def index
authorize :ip_block, :index?
render json: @ip_blocks, each_serializer: REST::Admin::IpBlockSerializer
end
def show
authorize @ip_block, :show?
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end
def update
authorize @ip_block, :update?
@ip_block.update(resource_params)
log_action :update, @ip_block
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end
def destroy
authorize @ip_block, :destroy?
@ip_block.destroy!
log_action :destroy, @ip_block
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end
private
def set_ip_blocks
@ip_blocks = IpBlock.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def set_ip_block
@ip_block = IpBlock.find(params[:id])
end
def resource_params
params.permit(:ip, :severity, :comment, :expires_in)
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def next_path
api_v1_admin_ip_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
def prev_path
api_v1_admin_ip_blocks_url(pagination_params(min_id: pagination_since_id)) unless @ip_blocks.empty?
end
def pagination_max_id
@ip_blocks.last.id
end
def pagination_since_id
@ip_blocks.first.id
end
def records_continue?
@ip_blocks.size == limit_param(LIMIT)
end
def pagination_params(core_params)
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
end
end

View File

@ -16,6 +16,7 @@ class IpBlock < ApplicationRecord
CACHE_KEY = 'blocked_ips' CACHE_KEY = 'blocked_ips'
include Expireable include Expireable
include Paginable
enum severity: { enum severity: {
sign_up_requires_approval: 5000, sign_up_requires_approval: 5000,
@ -28,7 +29,7 @@ class IpBlock < ApplicationRecord
after_commit :reset_cache after_commit :reset_cache
def to_log_human_identifier def to_log_human_identifier
"#{record.ip}/#{record.ip.prefix}" "#{ip}/#{ip.prefix}"
end end
class << self class << self

View File

@ -9,6 +9,10 @@ class IpBlockPolicy < ApplicationPolicy
role.can?(:manage_blocks) role.can?(:manage_blocks)
end end
def update?
role.can?(:manage_blocks)
end
def destroy? def destroy?
role.can?(:manage_blocks) role.can?(:manage_blocks)
end end

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class REST::Admin::IpBlockSerializer < ActiveModel::Serializer
attributes :id, :ip, :severity, :comment,
:created_at, :expires_at
def id
object.id.to_s
end
def ip
"#{object.ip}/#{object.ip.prefix}"
end
end

View File

@ -591,6 +591,7 @@ Rails.application.routes.draw do
resources :domain_allows, only: [:index, :show, :create, :destroy] resources :domain_allows, only: [:index, :show, :create, :destroy]
resources :domain_blocks, only: [:index, :show, :update, :create, :destroy] resources :domain_blocks, only: [:index, :show, :update, :create, :destroy]
resources :ip_blocks, only: [:index, :show, :update, :create, :destroy]
namespace :trends do namespace :trends do
resources :tags, only: [:index] resources :tags, only: [:index]