commit: b3af3f9f8cd5ed9c7ee06452e981b1b7734e1d89
parent: d5091387c6ddbe03b118b0cfb6d74cf821b84fb2
Author: utam0k <k0ma@utam0k.jp>
Date: Wed, 4 Oct 2017 22:16:10 +0900
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
Diffstat:
15 files changed, 207 insertions(+), 1 deletion(-)
diff --git a/app/controllers/admin/email_domain_blocks_controller.rb b/app/controllers/admin/email_domain_blocks_controller.rb
@@ -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
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
@@ -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
diff --git a/app/validators/blacklisted_email_validator.rb b/app/validators/blacklisted_email_validator.rb
@@ -12,6 +12,7 @@ class BlacklistedEmailValidator < ActiveModel::Validator
end
def on_blacklist?(value)
+ return true if EmailDomainBlock.block?(value)
return false if Rails.configuration.x.email_domains_blacklist.blank?
domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
diff --git a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
@@ -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
diff --git a/app/views/admin/email_domain_blocks/index.html.haml b/app/views/admin/email_domain_blocks/index.html.haml
@@ -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'
diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml
@@ -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
diff --git a/config/locales/en.yml b/config/locales/en.yml
@@ -152,6 +152,16 @@ en:
undo: Undo
title: Domain Blocks
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:
account_count: Known accounts
domain_name: Domain
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
@@ -152,6 +152,16 @@ ja:
undo: 元に戻す
title: ドメインブロック
undo: 元に戻す
+ email_domain_blocks:
+ add_new: 新規追加
+ created_msg: 処理を完了しました
+ delete: 消去
+ destroyed_msg: 消去しました
+ domain: ドメイン
+ new:
+ create: ブロックを作成
+ title: 新規メールドメインブロック
+ title: メールドメインブロック
instances:
account_count: 既知のアカウント数
domain_name: ドメイン名
diff --git a/config/navigation.rb b/config/navigation.rb
@@ -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 :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 :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 :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
diff --git a/config/routes.rb b/config/routes.rb
@@ -108,6 +108,7 @@ Rails.application.routes.draw do
namespace :admin do
resources :subscriptions, only: [:index]
resources :domain_blocks, only: [:index, :new, :create, :show, :destroy]
+ resources :email_domain_blocks, only: [:index, :new, :create, :destroy]
resource :settings, only: [:edit, :update]
resources :instances, only: [:index] do
diff --git a/db/migrate/20170928082043_create_email_domain_blocks.rb b/db/migrate/20170928082043_create_email_domain_blocks.rb
@@ -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
diff --git a/db/schema.rb b/db/schema.rb
@@ -10,7 +10,7 @@
#
# 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
enable_extension "plpgsql"
@@ -110,6 +110,12 @@ ActiveRecord::Schema.define(version: 20170927215609) do
t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true
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|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb
@@ -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
diff --git a/spec/fabricators/email_domain_block_fabricator.rb b/spec/fabricators/email_domain_block_fabricator.rb
@@ -0,0 +1,3 @@
+Fabricator(:email_domain_block) do
+ domain { sequence(:domain) { |i| "#{i}#{Faker::Internet.domain_name}" } }
+end
diff --git a/spec/models/email_domain_block_spec.rb b/spec/models/email_domain_block_spec.rb
@@ -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