Add /api/v1/admin/domain_allows (#18668)
- `GET /api/v1/admin/domain_allows` lists allowed domains - `GET /api/v1/admin/domain_allows/:id` shows one by ID - `DELETE /api/v1/admin/domain_allows/:id` deletes a given domain from the list of allowed domains - `POST /api/v1/admin/domain_allows` to allow a new domain: if that domain is already allowed, the existing DomainAllow will be returned
This commit is contained in:
		
							parent
							
								
									9c571a95db
								
							
						
					
					
						commit
						35588d09e2
					
				
					 6 changed files with 232 additions and 0 deletions
				
			
		
							
								
								
									
										95
									
								
								app/controllers/api/v1/admin/domain_allows_controller.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								app/controllers/api/v1/admin/domain_allows_controller.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class Api::V1::Admin::DomainAllowsController < Api::BaseController
 | 
			
		||||
  include Authorization
 | 
			
		||||
  include AccountableConcern
 | 
			
		||||
 | 
			
		||||
  LIMIT = 100
 | 
			
		||||
 | 
			
		||||
  before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:domain_allows' }, only: [:index, :show]
 | 
			
		||||
  before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:domain_allows' }, except: [:index, :show]
 | 
			
		||||
  before_action :require_staff!
 | 
			
		||||
  before_action :set_domain_allows, only: :index
 | 
			
		||||
  before_action :set_domain_allow, only: [:show, :destroy]
 | 
			
		||||
 | 
			
		||||
  after_action :insert_pagination_headers, only: :index
 | 
			
		||||
 | 
			
		||||
  PAGINATION_PARAMS = %i(limit).freeze
 | 
			
		||||
 | 
			
		||||
  def create
 | 
			
		||||
    authorize :domain_allow, :create?
 | 
			
		||||
 | 
			
		||||
    @domain_allow = DomainAllow.find_by(resource_params)
 | 
			
		||||
 | 
			
		||||
    if @domain_allow.nil?
 | 
			
		||||
      @domain_allow = DomainAllow.create!(resource_params)
 | 
			
		||||
      log_action :create, @domain_allow
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def index
 | 
			
		||||
    authorize :domain_allow, :index?
 | 
			
		||||
    render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def show
 | 
			
		||||
    authorize @domain_allow, :show?
 | 
			
		||||
    render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def destroy
 | 
			
		||||
    authorize @domain_allow, :destroy?
 | 
			
		||||
    UnallowDomainService.new.call(@domain_allow)
 | 
			
		||||
    log_action :destroy, @domain_allow
 | 
			
		||||
    render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def set_domain_allows
 | 
			
		||||
    @domain_allows = filtered_domain_allows.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def set_domain_allow
 | 
			
		||||
    @domain_allow = DomainAllow.find(params[:id])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def filtered_domain_allows
 | 
			
		||||
    # TODO: no filtering yet
 | 
			
		||||
    DomainAllow.all
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def insert_pagination_headers
 | 
			
		||||
    set_pagination_headers(next_path, prev_path)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def next_path
 | 
			
		||||
    api_v1_admin_domain_allows_url(pagination_params(max_id: pagination_max_id)) if records_continue?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def prev_path
 | 
			
		||||
    api_v1_admin_domain_allows_url(pagination_params(min_id: pagination_since_id)) unless @domain_allows.empty?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pagination_max_id
 | 
			
		||||
    @domain_allows.last.id
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pagination_since_id
 | 
			
		||||
    @domain_allows.first.id
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def records_continue?
 | 
			
		||||
    @domain_allows.size == limit_param(LIMIT)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pagination_params(core_params)
 | 
			
		||||
    params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def resource_params
 | 
			
		||||
    params.permit(:domain)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
#
 | 
			
		||||
 | 
			
		||||
class DomainAllow < ApplicationRecord
 | 
			
		||||
  include Paginable
 | 
			
		||||
  include DomainNormalizable
 | 
			
		||||
  include DomainMaterializable
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,14 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class DomainAllowPolicy < ApplicationPolicy
 | 
			
		||||
  def index?
 | 
			
		||||
    admin?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def show?
 | 
			
		||||
    admin?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def create?
 | 
			
		||||
    admin?
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								app/serializers/rest/admin/domain_allow_serializer.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/serializers/rest/admin/domain_allow_serializer.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class REST::Admin::DomainAllowSerializer < ActiveModel::Serializer
 | 
			
		||||
  attributes :id, :domain, :created_at
 | 
			
		||||
 | 
			
		||||
  def id
 | 
			
		||||
    object.id.to_s
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -570,6 +570,7 @@ Rails.application.routes.draw do
 | 
			
		|||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        resources :domain_allows, only: [:index, :show, :create, :destroy]
 | 
			
		||||
        resources :domain_blocks, only: [:index, :show, :update, :create, :destroy]
 | 
			
		||||
 | 
			
		||||
        namespace :trends do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										118
									
								
								spec/controllers/api/v1/admin/domain_allows_controller_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								spec/controllers/api/v1/admin/domain_allows_controller_spec.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,118 @@
 | 
			
		|||
require 'rails_helper'
 | 
			
		||||
 | 
			
		||||
RSpec.describe Api::V1::Admin::DomainAllowsController, type: :controller do
 | 
			
		||||
  render_views
 | 
			
		||||
 | 
			
		||||
  let(:role)   { 'admin' }
 | 
			
		||||
  let(:user)   { Fabricate(:user, role: role) }
 | 
			
		||||
  let(:scopes) { 'admin:read admin:write' }
 | 
			
		||||
  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
 | 
			
		||||
 | 
			
		||||
  before do
 | 
			
		||||
    allow(controller).to receive(:doorkeeper_token) { token }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  shared_examples 'forbidden for wrong scope' do |wrong_scope|
 | 
			
		||||
    let(:scopes) { wrong_scope }
 | 
			
		||||
 | 
			
		||||
    it 'returns http forbidden' do
 | 
			
		||||
      expect(response).to have_http_status(403)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  shared_examples 'forbidden for wrong role' do |wrong_role|
 | 
			
		||||
    let(:role) { wrong_role }
 | 
			
		||||
 | 
			
		||||
    it 'returns http forbidden' do
 | 
			
		||||
      expect(response).to have_http_status(403)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe 'GET #index' do
 | 
			
		||||
    let!(:domain_allow) { Fabricate(:domain_allow) }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      get :index
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'user'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'moderator'
 | 
			
		||||
 | 
			
		||||
    it 'returns http success' do
 | 
			
		||||
      expect(response).to have_http_status(200)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'returns the expected domain allows' do
 | 
			
		||||
      json = body_as_json
 | 
			
		||||
      expect(json.length).to eq 1
 | 
			
		||||
      expect(json[0][:id].to_i).to eq domain_allow.id
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe 'GET #show' do
 | 
			
		||||
    let!(:domain_allow) { Fabricate(:domain_allow) }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      get :show, params: { id: domain_allow.id }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'user'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'moderator'
 | 
			
		||||
 | 
			
		||||
    it 'returns http success' do
 | 
			
		||||
      expect(response).to have_http_status(200)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'returns expected domain name' do
 | 
			
		||||
      json = body_as_json
 | 
			
		||||
      expect(json[:domain]).to eq domain_allow.domain
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe 'DELETE #destroy' do
 | 
			
		||||
    let!(:domain_allow) { Fabricate(:domain_allow) }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      delete :destroy, params: { id: domain_allow.id }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'user'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'moderator'
 | 
			
		||||
 | 
			
		||||
    it 'returns http success' do
 | 
			
		||||
      expect(response).to have_http_status(200)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'deletes the block' do
 | 
			
		||||
      expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe 'POST #create' do
 | 
			
		||||
    let!(:domain_allow) { Fabricate(:domain_allow, domain: 'example.com') }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      post :create, params: { domain: 'foo.bar.com' }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'user'
 | 
			
		||||
    it_behaves_like 'forbidden for wrong role', 'moderator'
 | 
			
		||||
 | 
			
		||||
    it 'returns http success' do
 | 
			
		||||
      expect(response).to have_http_status(200)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'returns expected domain name' do
 | 
			
		||||
      json = body_as_json
 | 
			
		||||
      expect(json[:domain]).to eq 'foo.bar.com'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'creates a domain block' do
 | 
			
		||||
      expect(DomainAllow.find_by(domain: 'foo.bar.com')).to_not be_nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
		Reference in a new issue