[#817] Add email whitelist
This adds the ability to filter user signup with a whitelist instead of or in addition to a blacklist. Fixes #817
This commit is contained in:
		| @@ -22,6 +22,8 @@ OTP_SECRET= | ||||
| # SINGLE_USER_MODE=true | ||||
| # Prevent registrations with following e-mail domains | ||||
| # EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc | ||||
| # Only allow registrations with the following e-mail domains | ||||
| # EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc | ||||
|  | ||||
| # E-mail configuration | ||||
| SMTP_SERVER=smtp.mailgun.org | ||||
|   | ||||
| @@ -2,17 +2,30 @@ | ||||
|  | ||||
| class EmailValidator < ActiveModel::EachValidator | ||||
|   def validate_each(record, attribute, value) | ||||
|     return if Rails.configuration.x.email_domains_blacklist.empty? | ||||
|  | ||||
|     record.errors.add(attribute, I18n.t('users.invalid_email')) if blocked_email?(value) | ||||
|   end | ||||
|  | ||||
|   private | ||||
|  | ||||
|   def blocked_email?(value) | ||||
|     on_blacklist?(value) || not_on_whitelist?(value) | ||||
|   end | ||||
|  | ||||
|   def on_blacklist?(value) | ||||
|     return false if Rails.configuration.x.email_domains_blacklist.blank? | ||||
|  | ||||
|     domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.') | ||||
|     regexp  = Regexp.new("@(.+\\.)?(#{domains})", true) | ||||
|  | ||||
|     value =~ regexp | ||||
|   end | ||||
|  | ||||
|   def not_on_whitelist?(value) | ||||
|     return false if Rails.configuration.x.email_domains_whitelist.blank? | ||||
|  | ||||
|     domains = Rails.configuration.x.email_domains_whitelist.gsub('.', '\.') | ||||
|     regexp  = Regexp.new("@(.+\\.)?(#{domains})", true) | ||||
|  | ||||
|     value !~ regexp | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -2,4 +2,5 @@ | ||||
|  | ||||
| Rails.application.configure do | ||||
|   config.x.email_domains_blacklist = ENV.fetch('EMAIL_DOMAIN_BLACKLIST') { 'mvrht.com' } | ||||
|   config.x.email_domains_whitelist = ENV.fetch('EMAIL_DOMAIN_WHITELIST') { '' }   | ||||
| end | ||||
|   | ||||
| @@ -1,5 +1,42 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe User, type: :model do | ||||
|   let(:account) { Fabricate(:account, username: 'alice') }   | ||||
|   let(:password) { 'abcd1234' } | ||||
|  | ||||
|   describe 'blacklist' do | ||||
|     it 'should allow a non-blacklisted user to be created' do | ||||
|       user = User.new(email: 'foo@example.com', account: account, password: password) | ||||
|  | ||||
|       expect(user.valid?).to be_truthy | ||||
|     end | ||||
|      | ||||
|     it 'should not allow a blacklisted user to be created' do | ||||
|       user = User.new(email: 'foo@mvrht.com', account: account, password: password) | ||||
|  | ||||
|       expect(user.valid?).to be_falsey | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   describe 'whitelist' do | ||||
|     around(:each) do |example| | ||||
|       old_whitelist = Rails.configuration.x.email_whitelist | ||||
|  | ||||
|       Rails.configuration.x.email_domains_whitelist = 'mastodon.space' | ||||
|  | ||||
|       example.run | ||||
|  | ||||
|       Rails.configuration.x.email_domains_whitelist = old_whitelist | ||||
|     end | ||||
|  | ||||
|     it 'should not allow a user to be created unless they are whitelisted' do | ||||
|       user = User.new(email: 'foo@example.com', account: account, password: password) | ||||
|       expect(user.valid?).to be_falsey | ||||
|     end | ||||
|  | ||||
|     it 'should allow a user to be created if they are whitelisted' do | ||||
|       user = User.new(email: 'foo@mastodon.space', account: account, password: password) | ||||
|       expect(user.valid?).to be_truthy | ||||
|     end     | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user