Implement EmailBlackList (#5109)
* Implement BlacklistedEmailDomain * Use Faker::Internet.domain_name * Remove note column * Add frozen_string_literal comment * Delete unnecessary codes * Sort alphabetically * Change of wording * Rename BlacklistedEmailDomain to EmailDomainBlock
This commit is contained in:
parent
d5091387c6
commit
b3af3f9f8c
15 changed files with 207 additions and 1 deletions
40
app/controllers/admin/email_domain_blocks_controller.rb
Normal file
40
app/controllers/admin/email_domain_blocks_controller.rb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class EmailDomainBlocksController < BaseController
|
||||||
|
before_action :set_email_domain_block, only: [:show, :destroy]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@email_domain_blocks = EmailDomainBlock.page(params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@email_domain_block = EmailDomainBlock.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@email_domain_block = EmailDomainBlock.new(resource_params)
|
||||||
|
|
||||||
|
if @email_domain_block.save
|
||||||
|
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg')
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@email_domain_block.destroy
|
||||||
|
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.destroyed_msg')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_email_domain_block
|
||||||
|
@email_domain_block = EmailDomainBlock.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def resource_params
|
||||||
|
params.require(:email_domain_block).permit(:domain)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
app/models/email_domain_block.rb
Normal file
17
app/models/email_domain_block.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: email_domain_blocks
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# domain :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
|
class EmailDomainBlock < ApplicationRecord
|
||||||
|
def self.block?(email)
|
||||||
|
domain = email.gsub(/.+@([^.]+)/, '\1')
|
||||||
|
where(domain: domain).exists?
|
||||||
|
end
|
||||||
|
end
|
|
@ -12,6 +12,7 @@ class BlacklistedEmailValidator < ActiveModel::Validator
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_blacklist?(value)
|
def on_blacklist?(value)
|
||||||
|
return true if EmailDomainBlock.block?(value)
|
||||||
return false if Rails.configuration.x.email_domains_blacklist.blank?
|
return false if Rails.configuration.x.email_domains_blacklist.blank?
|
||||||
|
|
||||||
domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
|
domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
%tr
|
||||||
|
%td.domain
|
||||||
|
%samp= email_domain_block.domain
|
||||||
|
%td
|
||||||
|
= table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(email_domain_block), method: :delete
|
13
app/views/admin/email_domain_blocks/index.html.haml
Normal file
13
app/views/admin/email_domain_blocks/index.html.haml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.email_domain_blocks.title')
|
||||||
|
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th= t('admin.email_domain_blocks.domain')
|
||||||
|
%th
|
||||||
|
%tbody
|
||||||
|
= render @email_domain_blocks
|
||||||
|
|
||||||
|
= paginate @email_domain_blocks
|
||||||
|
= link_to t('admin.email_domain_blocks.add_new'), new_admin_email_domain_block_path, class: 'button'
|
10
app/views/admin/email_domain_blocks/new.html.haml
Normal file
10
app/views/admin/email_domain_blocks/new.html.haml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('.title')
|
||||||
|
|
||||||
|
= simple_form_for @email_domain_block, url: admin_email_domain_blocks_path do |f|
|
||||||
|
= render 'shared/error_messages', object: @email_domain_block
|
||||||
|
|
||||||
|
= f.input :domain, placeholder: t('admin.email_domain_blocks.domain')
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('.create'), type: :submit
|
|
@ -152,6 +152,16 @@ en:
|
||||||
undo: Undo
|
undo: Undo
|
||||||
title: Domain Blocks
|
title: Domain Blocks
|
||||||
undo: Undo
|
undo: Undo
|
||||||
|
email_domain_blocks:
|
||||||
|
add_new: Add new
|
||||||
|
created_msg: Email domain block successfully created
|
||||||
|
delete: Delete
|
||||||
|
destroyed_msg: Email domain block successfully deleted
|
||||||
|
domain: Domain
|
||||||
|
new:
|
||||||
|
create: Create block
|
||||||
|
title: New email domain block
|
||||||
|
title: Email Domain Block
|
||||||
instances:
|
instances:
|
||||||
account_count: Known accounts
|
account_count: Known accounts
|
||||||
domain_name: Domain
|
domain_name: Domain
|
||||||
|
|
|
@ -152,6 +152,16 @@ ja:
|
||||||
undo: 元に戻す
|
undo: 元に戻す
|
||||||
title: ドメインブロック
|
title: ドメインブロック
|
||||||
undo: 元に戻す
|
undo: 元に戻す
|
||||||
|
email_domain_blocks:
|
||||||
|
add_new: 新規追加
|
||||||
|
created_msg: 処理を完了しました
|
||||||
|
delete: 消去
|
||||||
|
destroyed_msg: 消去しました
|
||||||
|
domain: ドメイン
|
||||||
|
new:
|
||||||
|
create: ブロックを作成
|
||||||
|
title: 新規メールドメインブロック
|
||||||
|
title: メールドメインブロック
|
||||||
instances:
|
instances:
|
||||||
account_count: 既知のアカウント数
|
account_count: 既知のアカウント数
|
||||||
domain_name: ドメイン名
|
domain_name: ドメイン名
|
||||||
|
|
|
@ -26,6 +26,7 @@ SimpleNavigation::Configuration.run do |navigation|
|
||||||
admin.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url, highlights_on: %r{/admin/instances}
|
admin.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url, highlights_on: %r{/admin/instances}
|
||||||
admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url
|
admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url
|
||||||
admin.item :domain_blocks, safe_join([fa_icon('lock fw'), t('admin.domain_blocks.title')]), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks}
|
admin.item :domain_blocks, safe_join([fa_icon('lock fw'), t('admin.domain_blocks.title')]), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks}
|
||||||
|
admin.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}
|
||||||
admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }
|
admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }
|
||||||
admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }
|
admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }
|
||||||
admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url
|
admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url
|
||||||
|
|
|
@ -108,6 +108,7 @@ Rails.application.routes.draw do
|
||||||
namespace :admin do
|
namespace :admin do
|
||||||
resources :subscriptions, only: [:index]
|
resources :subscriptions, only: [:index]
|
||||||
resources :domain_blocks, only: [:index, :new, :create, :show, :destroy]
|
resources :domain_blocks, only: [:index, :new, :create, :show, :destroy]
|
||||||
|
resources :email_domain_blocks, only: [:index, :new, :create, :destroy]
|
||||||
resource :settings, only: [:edit, :update]
|
resource :settings, only: [:edit, :update]
|
||||||
|
|
||||||
resources :instances, only: [:index] do
|
resources :instances, only: [:index] do
|
||||||
|
|
9
db/migrate/20170928082043_create_email_domain_blocks.rb
Normal file
9
db/migrate/20170928082043_create_email_domain_blocks.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class CreateEmailDomainBlocks < ActiveRecord::Migration[5.1]
|
||||||
|
def change
|
||||||
|
create_table :email_domain_blocks do |t|
|
||||||
|
t.string :domain, null: false
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20170927215609) do
|
ActiveRecord::Schema.define(version: 20170928082043) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -110,6 +110,12 @@ ActiveRecord::Schema.define(version: 20170927215609) do
|
||||||
t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true
|
t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "email_domain_blocks", force: :cascade do |t|
|
||||||
|
t.string "domain", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "favourites", force: :cascade do |t|
|
create_table "favourites", force: :cascade do |t|
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Admin::EmailDomainBlocksController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in Fabricate(:user, admin: true), scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET #index' do
|
||||||
|
around do |example|
|
||||||
|
default_per_page = EmailDomainBlock.default_per_page
|
||||||
|
EmailDomainBlock.paginates_per 1
|
||||||
|
example.run
|
||||||
|
EmailDomainBlock.paginates_per default_per_page
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders email blacks' do
|
||||||
|
2.times { Fabricate(:email_domain_block) }
|
||||||
|
|
||||||
|
get :index, params: { page: 2 }
|
||||||
|
|
||||||
|
assigned = assigns(:email_domain_blocks)
|
||||||
|
expect(assigned.count).to eq 1
|
||||||
|
expect(assigned.klass).to be EmailDomainBlock
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET #new' do
|
||||||
|
it 'assigns a new email black' do
|
||||||
|
get :new
|
||||||
|
|
||||||
|
expect(assigns(:email_domain_block)).to be_instance_of(EmailDomainBlock)
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST #create' do
|
||||||
|
it 'blocks the domain when succeeded to save' do
|
||||||
|
post :create, params: { email_domain_block: { domain: 'example.com'} }
|
||||||
|
|
||||||
|
expect(flash[:notice]).to eq I18n.t('admin.email_domain_blocks.created_msg')
|
||||||
|
expect(response).to redirect_to(admin_email_domain_blocks_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE #destroy' do
|
||||||
|
it 'unblocks the domain' do
|
||||||
|
email_domain_block = Fabricate(:email_domain_block)
|
||||||
|
delete :destroy, params: { id: email_domain_block.id }
|
||||||
|
|
||||||
|
expect(flash[:notice]).to eq I18n.t('admin.email_domain_blocks.destroyed_msg')
|
||||||
|
expect(response).to redirect_to(admin_email_domain_blocks_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
3
spec/fabricators/email_domain_block_fabricator.rb
Normal file
3
spec/fabricators/email_domain_block_fabricator.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Fabricator(:email_domain_block) do
|
||||||
|
domain { sequence(:domain) { |i| "#{i}#{Faker::Internet.domain_name}" } }
|
||||||
|
end
|
21
spec/models/email_domain_block_spec.rb
Normal file
21
spec/models/email_domain_block_spec.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe EmailDomainBlock, type: :model do
|
||||||
|
describe 'validations' do
|
||||||
|
it 'has a valid fabricator' do
|
||||||
|
email_domain_block = Fabricate.build(:email_domain_block)
|
||||||
|
expect(email_domain_block).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'block?' do
|
||||||
|
it 'returns true if the domain is registed' do
|
||||||
|
Fabricate(:email_domain_block, domain: 'example.com')
|
||||||
|
expect(EmailDomainBlock.block?('nyarn@example.com')).to eq true
|
||||||
|
end
|
||||||
|
it 'returns true if the domain is not registed' do
|
||||||
|
Fabricate(:email_domain_block, domain: 'domain')
|
||||||
|
expect(EmailDomainBlock.block?('example')).to eq false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue